genlayer 0.12.3 → 0.12.5

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.
Files changed (67) hide show
  1. package/.env.example +4 -0
  2. package/CHANGELOG.md +8 -0
  3. package/dist/index.js +409 -80
  4. package/esbuild.config.dev.js +1 -2
  5. package/esbuild.config.prod.js +1 -1
  6. package/eslint.config.js +2 -1
  7. package/package.json +5 -3
  8. package/src/commands/contracts/call.ts +16 -20
  9. package/src/commands/contracts/deploy.ts +107 -25
  10. package/src/commands/contracts/index.ts +14 -3
  11. package/src/commands/general/init.ts +0 -1
  12. package/src/commands/scaffold/index.ts +16 -0
  13. package/src/commands/scaffold/new.ts +34 -0
  14. package/src/index.ts +2 -0
  15. package/src/lib/actions/BaseAction.ts +11 -6
  16. package/src/lib/config/simulator.ts +2 -2
  17. package/templates/default/LICENSE +21 -0
  18. package/templates/default/README.md +101 -0
  19. package/templates/default/__init__.py +0 -0
  20. package/templates/default/app/.env.example +2 -0
  21. package/templates/default/app/.vscode/extensions.json +3 -0
  22. package/templates/default/app/README.md +5 -0
  23. package/templates/default/app/index.html +17 -0
  24. package/templates/default/app/package-lock.json +4920 -0
  25. package/templates/default/app/package.json +23 -0
  26. package/templates/default/app/postcss.config.js +6 -0
  27. package/templates/default/app/public/favicon.png +0 -0
  28. package/templates/default/app/src/App.vue +16 -0
  29. package/templates/default/app/src/components/Address.vue +38 -0
  30. package/templates/default/app/src/components/BetsScreen.vue +329 -0
  31. package/templates/default/app/src/logic/FootballBets.js +100 -0
  32. package/templates/default/app/src/main.js +5 -0
  33. package/templates/default/app/src/services/genlayer.js +19 -0
  34. package/templates/default/app/src/style.css +3 -0
  35. package/templates/default/app/tailwind.config.js +8 -0
  36. package/templates/default/app/vite.config.js +7 -0
  37. package/templates/default/config/__init__.py +0 -0
  38. package/templates/default/config/genlayer_config.py +14 -0
  39. package/templates/default/contracts/__init__.py +0 -0
  40. package/templates/default/contracts/football_bets.py +119 -0
  41. package/templates/default/deploy/deployScript.ts +31 -0
  42. package/templates/default/package-lock.json +3231 -0
  43. package/templates/default/package.json +7 -0
  44. package/templates/default/requirements.txt +6 -0
  45. package/templates/default/test/__init__.py +0 -0
  46. package/templates/default/test/football_bets_get_contract_schema_for_code.py +124 -0
  47. package/templates/default/test/test_football_bet_success_draw.py +108 -0
  48. package/templates/default/test/test_football_bet_success_win.py +106 -0
  49. package/templates/default/test/test_football_bet_unsuccess.py +107 -0
  50. package/templates/default/tools/__init__.py +0 -0
  51. package/templates/default/tools/accounts.py +5 -0
  52. package/templates/default/tools/calldata.py +224 -0
  53. package/templates/default/tools/request.py +134 -0
  54. package/templates/default/tools/response.py +52 -0
  55. package/templates/default/tools/structure.py +39 -0
  56. package/templates/default/tools/transactions.py +28 -0
  57. package/templates/default/tools/types.py +214 -0
  58. package/templates/default/tsconfig.json +7 -0
  59. package/tests/actions/call.test.ts +38 -76
  60. package/tests/actions/deploy.test.ts +200 -30
  61. package/tests/actions/new.test.ts +80 -0
  62. package/tests/commands/call.test.ts +6 -1
  63. package/tests/commands/deploy.test.ts +12 -1
  64. package/tests/commands/new.test.ts +68 -0
  65. package/tests/index.test.ts +4 -0
  66. package/tests/libs/baseAction.test.ts +17 -0
  67. package/vitest.config.ts +1 -1
package/dist/index.js CHANGED
@@ -9624,7 +9624,7 @@ var version3;
9624
9624
  var init_version2 = __esm({
9625
9625
  "node_modules/viem/_esm/errors/version.js"() {
9626
9626
  "use strict";
9627
- version3 = "2.23.5";
9627
+ version3 = "2.23.6";
9628
9628
  }
9629
9629
  });
9630
9630
 
@@ -16853,7 +16853,7 @@ var init_call = __esm({
16853
16853
  import { program } from "commander";
16854
16854
 
16855
16855
  // package.json
16856
- var version = "0.12.3";
16856
+ var version = "0.12.5";
16857
16857
  var package_default = {
16858
16858
  name: "genlayer",
16859
16859
  version,
@@ -16893,6 +16893,7 @@ var package_default = {
16893
16893
  devDependencies: {
16894
16894
  "@release-it/conventional-changelog": "^10.0.0",
16895
16895
  "@types/dockerode": "^3.3.31",
16896
+ "@types/fs-extra": "^11.0.4",
16896
16897
  "@types/inquirer": "^9.0.7",
16897
16898
  "@types/node": "^22.0.0",
16898
16899
  "@types/sinon": "^17.0.3",
@@ -16901,7 +16902,7 @@ var package_default = {
16901
16902
  "@typescript-eslint/parser": "^8.0.0",
16902
16903
  "@vitest/coverage-v8": "^2.1.4",
16903
16904
  "cross-env": "^7.0.3",
16904
- esbuild: "^0.25.0",
16905
+ esbuild: ">=0.25.0",
16905
16906
  eslint: "^9.0.0",
16906
16907
  "eslint-config-prettier": "^10.0.0",
16907
16908
  "eslint-import-resolver-typescript": "^3.6.1",
@@ -16918,7 +16919,8 @@ var package_default = {
16918
16919
  dockerode: "^4.0.2",
16919
16920
  dotenv: "^16.4.5",
16920
16921
  ethers: "^6.13.4",
16921
- "genlayer-js": "^0.6.0",
16922
+ "fs-extra": "^11.3.0",
16923
+ "genlayer-js": "^0.9.0",
16922
16924
  inquirer: "^12.0.0",
16923
16925
  "node-fetch": "^3.0.0",
16924
16926
  open: "^10.1.0",
@@ -16942,7 +16944,7 @@ var CLI_DESCRIPTION = "GenLayer CLI is a development environment for the GenLaye
16942
16944
  import inquirer2 from "inquirer";
16943
16945
 
16944
16946
  // src/lib/config/simulator.ts
16945
- var localnetCompatibleVersion = "v0.42.0";
16947
+ var localnetCompatibleVersion = "v0.51.0";
16946
16948
  var DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
16947
16949
  var CONTAINERS_NAME_PREFIX = "/genlayer-";
16948
16950
  var IMAGES_NAME_PREFIX = "yeagerai";
@@ -16966,7 +16968,7 @@ var STARTING_TIMEOUT_ATTEMPTS = 120;
16966
16968
  var AI_PROVIDERS_CONFIG = {
16967
16969
  ollama: {
16968
16970
  name: "Ollama",
16969
- hint: "(This will download and run a local instance of Llama 3)",
16971
+ hint: "(By default, this will download and run a local instance of Llama 3)",
16970
16972
  cliOptionValue: "ollama"
16971
16973
  },
16972
16974
  openai: {
@@ -19798,39 +19800,42 @@ var BaseAction = class extends ConfigFileManager {
19798
19800
  };
19799
19801
  return JSON.stringify(errorDetails, null, 2);
19800
19802
  }
19803
+ if (data instanceof Map) {
19804
+ data = Object.fromEntries(data);
19805
+ }
19801
19806
  return typeof data === "object" ? JSON.stringify(data, null, 2) : String(data);
19802
19807
  }
19803
19808
  log(message, data) {
19804
19809
  console.log(source_default.white(`
19805
19810
  ${message}`));
19806
- if (data) console.log(this.formatOutput(data));
19811
+ if (data !== void 0) console.log(this.formatOutput(data));
19807
19812
  }
19808
19813
  logSuccess(message, data) {
19809
19814
  console.log(source_default.green(`
19810
19815
  \u2714 ${message}`));
19811
- if (data) console.log(source_default.green(this.formatOutput(data)));
19816
+ if (data !== void 0) console.log(source_default.green(this.formatOutput(data)));
19812
19817
  }
19813
19818
  logInfo(message, data) {
19814
19819
  console.log(source_default.blue(`
19815
19820
  \u2139 ${message}`));
19816
- if (data) console.log(source_default.blue(this.formatOutput(data)));
19821
+ if (data !== void 0) console.log(source_default.blue(this.formatOutput(data)));
19817
19822
  }
19818
19823
  logWarning(message, data) {
19819
19824
  console.log(source_default.yellow(`
19820
19825
  \u26A0 ${message}`));
19821
- if (data) console.log(source_default.yellow(this.formatOutput(data)));
19826
+ if (data !== void 0) console.log(source_default.yellow(this.formatOutput(data)));
19822
19827
  }
19823
19828
  logError(message, error) {
19824
19829
  console.error(source_default.red(`
19825
19830
  \u2716 ${message}`));
19826
- if (error) console.error(source_default.red(this.formatOutput(error)));
19831
+ if (error !== void 0) console.error(source_default.red(this.formatOutput(error)));
19827
19832
  }
19828
19833
  startSpinner(message) {
19829
19834
  this.spinner.text = source_default.blue(`${message}`);
19830
19835
  this.spinner.start();
19831
19836
  }
19832
19837
  succeedSpinner(message, data) {
19833
- if (data) this.log("Result:", data);
19838
+ if (data !== void 0) this.log("Result:", data);
19834
19839
  this.spinner.succeed(source_default.green(message));
19835
19840
  }
19836
19841
  failSpinner(message, error) {
@@ -20723,7 +20728,6 @@ var InitAction = class extends BaseAction {
20723
20728
  const llmProvidersAnswer = await inquirer2.prompt(llmQuestions);
20724
20729
  const selectedLlmProviders = llmProvidersAnswer.selectedLlmProviders;
20725
20730
  let defaultOllamaModel = this.getConfig().defaultOllamaModel;
20726
- AI_PROVIDERS_CONFIG.ollama.hint = `(This will download and run a local instance of ${defaultOllamaModel})`;
20727
20731
  const aiProvidersEnvVars = {};
20728
20732
  const configurableAiProviders = selectedLlmProviders.filter(
20729
20733
  (provider) => AI_PROVIDERS_CONFIG[provider].envVar
@@ -20951,6 +20955,7 @@ function initializeKeygenCommands(program2) {
20951
20955
 
20952
20956
  // src/commands/contracts/deploy.ts
20953
20957
  import fs9 from "fs";
20958
+ import path4 from "path";
20954
20959
 
20955
20960
  // node_modules/genlayer-js/dist/chunk-MLKGABMK.js
20956
20961
  var __defProp2 = Object.defineProperty;
@@ -27891,15 +27896,16 @@ init_encodeFunctionData();
27891
27896
  init_toHex();
27892
27897
  init_fromHex();
27893
27898
 
27894
- // node_modules/genlayer-js/dist/chunk-O3T2C57T.js
27899
+ // node_modules/genlayer-js/dist/chunk-WEXFFND6.js
27895
27900
  var chains_exports = {};
27896
27901
  __export2(chains_exports, {
27902
+ localnet: () => localnet,
27897
27903
  simulator: () => simulator
27898
27904
  });
27899
27905
  var SIMULATOR_JSON_RPC_URL = "http://127.0.0.1:4000/api";
27900
- var simulator = defineChain({
27906
+ var localnet = defineChain({
27901
27907
  id: 61999,
27902
- name: "GenLayer Simulator",
27908
+ name: "Genlayer Localnet",
27903
27909
  rpcUrls: {
27904
27910
  default: {
27905
27911
  http: [SIMULATOR_JSON_RPC_URL]
@@ -27921,8 +27927,33 @@ var simulator = defineChain({
27921
27927
  defaultNumberOfInitialValidators: 5,
27922
27928
  defaultConsensusMaxRotations: 3
27923
27929
  });
27930
+ var SIMULATOR_JSON_RPC_URL2 = "http://127.0.0.1:4000/api";
27931
+ var simulator = defineChain({
27932
+ id: 61999,
27933
+ name: "GenLayer Simulator",
27934
+ rpcUrls: {
27935
+ default: {
27936
+ http: [SIMULATOR_JSON_RPC_URL2]
27937
+ }
27938
+ },
27939
+ nativeCurrency: {
27940
+ name: "GEN Token",
27941
+ symbol: "GEN",
27942
+ decimals: 18
27943
+ },
27944
+ blockExplorers: {
27945
+ default: {
27946
+ name: "GenLayer Explorer",
27947
+ url: SIMULATOR_JSON_RPC_URL2
27948
+ }
27949
+ },
27950
+ testnet: true,
27951
+ consensusMainContract: null,
27952
+ defaultNumberOfInitialValidators: 5,
27953
+ defaultConsensusMaxRotations: 3
27954
+ });
27924
27955
 
27925
- // node_modules/genlayer-js/dist/chunk-2EJVFGKU.js
27956
+ // node_modules/genlayer-js/dist/chunk-K72OSU5N.js
27926
27957
  var CalldataAddress = class {
27927
27958
  constructor(addr) {
27928
27959
  __publicField(this, "bytes");
@@ -27932,6 +27963,17 @@ var CalldataAddress = class {
27932
27963
  this.bytes = addr;
27933
27964
  }
27934
27965
  };
27966
+ var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
27967
+ TransactionStatus2["PENDING"] = "PENDING";
27968
+ TransactionStatus2["CANCELED"] = "CANCELED";
27969
+ TransactionStatus2["PROPOSING"] = "PROPOSING";
27970
+ TransactionStatus2["COMMITTING"] = "COMMITTING";
27971
+ TransactionStatus2["REVEALING"] = "REVEALING";
27972
+ TransactionStatus2["ACCEPTED"] = "ACCEPTED";
27973
+ TransactionStatus2["FINALIZED"] = "FINALIZED";
27974
+ TransactionStatus2["UNDETERMINED"] = "UNDETERMINED";
27975
+ return TransactionStatus2;
27976
+ })(TransactionStatus || {});
27935
27977
 
27936
27978
  // node_modules/viem/_esm/accounts/generatePrivateKey.js
27937
27979
  init_secp256k1();
@@ -28077,8 +28119,8 @@ function privateKeyToAccount(privateKey, options = {}) {
28077
28119
  function accountActions(client) {
28078
28120
  return {
28079
28121
  fundAccount: async ({ address, amount }) => {
28080
- if (client.chain?.id !== simulator.id) {
28081
- throw new Error("Client is not connected to the simulator");
28122
+ if (client.chain?.id !== localnet.id) {
28123
+ throw new Error("Client is not connected to the localnet");
28082
28124
  }
28083
28125
  return client.request({
28084
28126
  method: "sim_fundAccount",
@@ -28485,18 +28527,18 @@ var overrideContractActions = (client) => {
28485
28527
  return decode2(resultBinary);
28486
28528
  };
28487
28529
  client.writeContract = async (args) => {
28488
- const { account, address, functionName, args: callArgs, kwargs, value = 0n, leaderOnly = false } = args;
28530
+ const { account, address, functionName, args: callArgs, kwargs, value = 0n, leaderOnly = false, consensusMaxRotations = client.chain.defaultConsensusMaxRotations } = args;
28489
28531
  const data = [encode4(makeCalldataObject(functionName, callArgs, kwargs)), leaderOnly];
28490
28532
  const serializedData = serialize(data);
28491
- return _sendTransaction(address, serializedData, account || client.account, value);
28533
+ return _sendTransaction(address, serializedData, account || client.account, consensusMaxRotations, value);
28492
28534
  };
28493
28535
  client.deployContract = async (args) => {
28494
- const { account, code, args: constructorArgs, kwargs, leaderOnly = false } = args;
28536
+ const { account, code, args: constructorArgs, kwargs, leaderOnly = false, consensusMaxRotations = client.chain.defaultConsensusMaxRotations } = args;
28495
28537
  const data = [code, encode4(makeCalldataObject(void 0, constructorArgs, kwargs)), leaderOnly];
28496
28538
  const serializedData = serialize(data);
28497
- return _sendTransaction(zeroAddress, serializedData, account || client.account);
28539
+ return _sendTransaction(zeroAddress, serializedData, account || client.account, consensusMaxRotations);
28498
28540
  };
28499
- const _sendTransaction = async (recipient, data, senderAccount, value) => {
28541
+ const _sendTransaction = async (recipient, data, senderAccount, consensusMaxRotations, value) => {
28500
28542
  if (!senderAccount) {
28501
28543
  throw new Error(
28502
28544
  "No account set. Configure the client with an account or pass an account to this function."
@@ -28514,7 +28556,7 @@ var overrideContractActions = (client) => {
28514
28556
  senderAccount.address,
28515
28557
  recipient,
28516
28558
  client.chain.defaultNumberOfInitialValidators,
28517
- client.chain.defaultConsensusMaxRotations,
28559
+ consensusMaxRotations,
28518
28560
  data
28519
28561
  ]
28520
28562
  });
@@ -28554,6 +28596,51 @@ var transactionsConfig = {
28554
28596
  async function sleep2(ms) {
28555
28597
  return new Promise((resolve2) => setTimeout(resolve2, ms));
28556
28598
  }
28599
+ var abi_exports = {};
28600
+ __export2(abi_exports, {
28601
+ calldata: () => calldata,
28602
+ transactions: () => transactions
28603
+ });
28604
+ var calldata = calldata_exports;
28605
+ var transactions = transactions_exports;
28606
+ function b64ToArray(b64) {
28607
+ return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
28608
+ }
28609
+ function calldataToUserFriendlyJson(cd) {
28610
+ return {
28611
+ raw: Array.from(cd),
28612
+ readable: calldata.toString(calldata.decode(cd))
28613
+ };
28614
+ }
28615
+ var RESULT_CODES = /* @__PURE__ */ new Map([
28616
+ [0, "return"],
28617
+ [1, "rollback"],
28618
+ [2, "contract_error"],
28619
+ [3, "error"],
28620
+ [4, "none"],
28621
+ [5, "no_leaders"]
28622
+ ]);
28623
+ function resultToUserFriendlyJson(cd64) {
28624
+ const raw = b64ToArray(cd64);
28625
+ const code = RESULT_CODES.get(raw[0]);
28626
+ let status;
28627
+ let payload = null;
28628
+ if (code === void 0) {
28629
+ status = "<unknown>";
28630
+ } else {
28631
+ status = code;
28632
+ if ([1, 2].includes(raw[0])) {
28633
+ payload = new TextDecoder("utf-8").decode(raw.slice(1));
28634
+ } else if (raw[0] == 0) {
28635
+ payload = calldataToUserFriendlyJson(raw.slice(1));
28636
+ }
28637
+ }
28638
+ return {
28639
+ raw: cd64,
28640
+ status,
28641
+ payload
28642
+ };
28643
+ }
28557
28644
  var transactionActions = (client) => ({
28558
28645
  waitForTransactionReceipt: async ({
28559
28646
  hash: hash2,
@@ -28566,7 +28653,7 @@ var transactionActions = (client) => ({
28566
28653
  throw new Error("Transaction not found");
28567
28654
  }
28568
28655
  if (transaction.status === status || status === "ACCEPTED" && transaction.status === "FINALIZED") {
28569
- return transaction;
28656
+ return _decodeTransaction(transaction);
28570
28657
  }
28571
28658
  if (retries === 0) {
28572
28659
  throw new Error("Transaction status is not " + status);
@@ -28580,6 +28667,137 @@ var transactionActions = (client) => ({
28580
28667
  });
28581
28668
  }
28582
28669
  });
28670
+ var _decodeTransaction = (tx) => {
28671
+ if (!tx.data) return tx;
28672
+ try {
28673
+ const leaderReceipt = tx.consensus_data?.leader_receipt;
28674
+ if (leaderReceipt) {
28675
+ if (leaderReceipt.result) {
28676
+ leaderReceipt.result = resultToUserFriendlyJson(leaderReceipt.result);
28677
+ }
28678
+ if (leaderReceipt.calldata) {
28679
+ leaderReceipt.calldata = {
28680
+ base64: leaderReceipt.calldata,
28681
+ ...calldataToUserFriendlyJson(b64ToArray(leaderReceipt.calldata))
28682
+ };
28683
+ }
28684
+ if (leaderReceipt.eq_outputs) {
28685
+ leaderReceipt.eq_outputs = Object.fromEntries(
28686
+ Object.entries(leaderReceipt.eq_outputs).map(([key, value]) => {
28687
+ const decodedValue = new TextDecoder().decode(b64ToArray(String(value)));
28688
+ return [key, resultToUserFriendlyJson(decodedValue)];
28689
+ })
28690
+ );
28691
+ }
28692
+ }
28693
+ if (tx.data.calldata) {
28694
+ tx.data.calldata = {
28695
+ base64: tx.data.calldata,
28696
+ ...calldataToUserFriendlyJson(b64ToArray(tx.data.calldata))
28697
+ };
28698
+ }
28699
+ } catch (e2) {
28700
+ console.error("Error decoding transaction:", e2);
28701
+ }
28702
+ return tx;
28703
+ };
28704
+ var snapID = {
28705
+ local: "local:http://localhost:8081",
28706
+ npm: "npm:genlayer-wallet-plugin"
28707
+ };
28708
+ var networks = {
28709
+ localnet
28710
+ };
28711
+ var connect = async (client, network = "localnet", snapSource = "npm") => {
28712
+ if (!window.ethereum) {
28713
+ throw new Error("MetaMask is not installed.");
28714
+ }
28715
+ if (network === "testnet" || network === "mainnet") {
28716
+ throw new Error(`${network} is not available yet. Please use localnet.`);
28717
+ }
28718
+ const selectedNetwork = networks[network];
28719
+ if (!selectedNetwork) {
28720
+ throw new Error(`Network configuration for '${network}' is not available.`);
28721
+ }
28722
+ const chainIdHex = `0x${selectedNetwork.id.toString(16)}`;
28723
+ const chainParams = {
28724
+ chainId: chainIdHex,
28725
+ chainName: selectedNetwork.name,
28726
+ rpcUrls: selectedNetwork.rpcUrls.default.http,
28727
+ nativeCurrency: selectedNetwork.nativeCurrency,
28728
+ blockExplorerUrls: [selectedNetwork.blockExplorers?.default.url]
28729
+ };
28730
+ const currentChainId = await window.ethereum.request({ method: "eth_chainId" });
28731
+ if (currentChainId !== chainIdHex) {
28732
+ await window.ethereum.request({
28733
+ method: "wallet_addEthereumChain",
28734
+ params: [chainParams]
28735
+ });
28736
+ await window.ethereum.request({
28737
+ method: "wallet_switchEthereumChain",
28738
+ params: [{ chainId: chainIdHex }]
28739
+ });
28740
+ }
28741
+ const id = snapSource === "local" ? snapID.local : snapID.npm;
28742
+ const installedSnaps = await window.ethereum.request({ method: "wallet_getSnaps" });
28743
+ const isGenLayerSnapInstalled = Object.values(installedSnaps).some(
28744
+ (snap) => snap.id === id
28745
+ );
28746
+ if (!isGenLayerSnapInstalled) {
28747
+ await window.ethereum.request({
28748
+ method: "wallet_requestSnaps",
28749
+ params: {
28750
+ [id]: {}
28751
+ }
28752
+ });
28753
+ }
28754
+ client.chain = selectedNetwork;
28755
+ };
28756
+ var metamaskClient = async (snapSource = "npm") => {
28757
+ if (typeof window === "undefined" || !window.ethereum) {
28758
+ throw new Error("MetaMask is not installed.");
28759
+ }
28760
+ const isFlask = async () => {
28761
+ try {
28762
+ const clientVersion = await window.ethereum?.request({
28763
+ method: "web3_clientVersion"
28764
+ });
28765
+ return clientVersion?.includes("flask");
28766
+ } catch (error) {
28767
+ console.error("Error detecting Flask:", error);
28768
+ return false;
28769
+ }
28770
+ };
28771
+ const installedSnaps = async () => {
28772
+ try {
28773
+ return await window.ethereum?.request({
28774
+ method: "wallet_getSnaps"
28775
+ });
28776
+ } catch (error) {
28777
+ console.error("Error getting installed snaps:", error);
28778
+ return {};
28779
+ }
28780
+ };
28781
+ const isGenLayerSnapInstalled = async () => {
28782
+ const id = snapSource === "local" ? snapID.local : snapID.npm;
28783
+ const snaps = await installedSnaps();
28784
+ return Object.values(snaps).some((snap) => snap.id === id);
28785
+ };
28786
+ const flaskDetected = await isFlask();
28787
+ const snapsList = await installedSnaps();
28788
+ const genLayerSnapInstalled = await isGenLayerSnapInstalled();
28789
+ return {
28790
+ isFlask: flaskDetected,
28791
+ installedSnaps: snapsList,
28792
+ isGenLayerSnapInstalled: genLayerSnapInstalled
28793
+ };
28794
+ };
28795
+ function walletActions2(client) {
28796
+ return {
28797
+ connect: (network, snapSource) => connect(client, network, snapSource),
28798
+ metamaskClient: (snapSource = "npm") => metamaskClient(snapSource)
28799
+ };
28800
+ }
28583
28801
  function chainActions(client) {
28584
28802
  return {
28585
28803
  initializeConsensusSmartContract: async (forceReset = false) => {
@@ -28609,8 +28827,8 @@ function chainActions(client) {
28609
28827
  }
28610
28828
  };
28611
28829
  }
28612
- var createClient2 = (config = { chain: simulator }) => {
28613
- const chainConfig = config.chain || simulator;
28830
+ var createClient2 = (config = { chain: localnet }) => {
28831
+ const chainConfig = config.chain || localnet;
28614
28832
  if (config.endpoint) {
28615
28833
  chainConfig.rpcUrls.default.http = [config.endpoint];
28616
28834
  }
@@ -28654,7 +28872,7 @@ var createClient2 = (config = { chain: simulator }) => {
28654
28872
  chain: chainConfig,
28655
28873
  transport: custom(customTransport),
28656
28874
  ...config.account ? { account: config.account } : {}
28657
- }).extend(publicActions).extend(walletActions).extend((client) => accountActions(client)).extend((client) => transactionActions(client)).extend((client) => contractActions(client)).extend((client) => chainActions(client));
28875
+ }).extend(publicActions).extend(walletActions).extend((client) => accountActions(client)).extend((client) => transactionActions(client)).extend((client) => contractActions(client)).extend((client) => chainActions(client)).extend((client) => walletActions2(client));
28658
28876
  baseClient.initializeConsensusSmartContract().catch((error) => {
28659
28877
  console.error("Failed to initialize consensus smart contract:", error);
28660
28878
  });
@@ -28666,13 +28884,6 @@ var createAccount = (accountPrivateKey) => {
28666
28884
  const account = privateKeyToAccount(privateKey);
28667
28885
  return account;
28668
28886
  };
28669
- var abi_exports = {};
28670
- __export2(abi_exports, {
28671
- calldata: () => calldata,
28672
- transactions: () => transactions
28673
- });
28674
- var calldata = calldata_exports;
28675
- var transactions = transactions_exports;
28676
28887
 
28677
28888
  // src/lib/accounts/getPrivateKey.ts
28678
28889
  import fs8 from "fs";
@@ -28692,9 +28903,13 @@ function getPrivateKey() {
28692
28903
  }
28693
28904
 
28694
28905
  // src/commands/contracts/deploy.ts
28695
- var DeployAction = class {
28906
+ import { pathToFileURL } from "url";
28907
+ import { buildSync } from "esbuild";
28908
+ var DeployAction = class extends BaseAction {
28696
28909
  constructor() {
28910
+ super();
28697
28911
  __publicField(this, "genlayerClient");
28912
+ __publicField(this, "deployDir", path4.resolve(process.cwd(), "deploy"));
28698
28913
  this.genlayerClient = createClient2({
28699
28914
  chain: simulator,
28700
28915
  endpoint: process.env.VITE_JSON_RPC_SERVER_URL,
@@ -28707,41 +28922,113 @@ var DeployAction = class {
28707
28922
  }
28708
28923
  return fs9.readFileSync(contractPath, "utf-8");
28709
28924
  }
28710
- async deploy(options) {
28711
- const argsUsed = options.args && options.args.length > 0;
28712
- const kwargsUsed = options.kwargs && options.kwargs.trim() !== "";
28713
- if (argsUsed && kwargsUsed) {
28714
- throw new Error("Invalid usage: Please specify either `args` or `kwargs`, but not both.");
28925
+ async executeTsScript(filePath) {
28926
+ const outFile = filePath.replace(/\.ts$/, ".compiled.js");
28927
+ this.startSpinner(`Transpiling TypeScript file: ${filePath}`);
28928
+ try {
28929
+ buildSync({
28930
+ entryPoints: [filePath],
28931
+ outfile: outFile,
28932
+ bundle: false,
28933
+ platform: "node",
28934
+ format: "esm",
28935
+ target: "es2020",
28936
+ sourcemap: false
28937
+ });
28938
+ await this.executeJsScript(filePath, outFile);
28939
+ } catch (error) {
28940
+ this.failSpinner(`Error executing: ${filePath}`, error);
28941
+ } finally {
28942
+ fs9.unlinkSync(outFile);
28715
28943
  }
28716
- if (!options.contract) {
28717
- console.error("No contract specified for deployment.");
28944
+ }
28945
+ async executeJsScript(filePath, transpiledFilePath) {
28946
+ this.startSpinner(`Executing file: ${filePath}`);
28947
+ try {
28948
+ const module = await import(pathToFileURL(transpiledFilePath || filePath).href);
28949
+ if (!module.default || typeof module.default !== "function") {
28950
+ this.failSpinner(`No "default" function found in: ${filePath}`);
28951
+ return;
28952
+ }
28953
+ await module.default(this.genlayerClient);
28954
+ this.succeedSpinner(`Successfully executed: ${filePath}`);
28955
+ } catch (error) {
28956
+ this.failSpinner(`Error executing: ${filePath}`, error);
28957
+ }
28958
+ }
28959
+ async deployScripts() {
28960
+ this.startSpinner("Searching for deploy scripts...");
28961
+ if (!fs9.existsSync(this.deployDir)) {
28962
+ this.failSpinner("No deploy folder found.");
28718
28963
  return;
28719
28964
  }
28720
- const contractCode = this.readContractCode(options.contract);
28721
- if (!contractCode) {
28722
- console.error("Contract code is empty.");
28965
+ const files = fs9.readdirSync(this.deployDir).filter((file) => file.endsWith(".ts") || file.endsWith(".js")).sort((a, b) => {
28966
+ const numA = parseInt(a.split("_")[0]);
28967
+ const numB = parseInt(b.split("_")[0]);
28968
+ if (!isNaN(numA) && !isNaN(numB)) return numA - numB;
28969
+ if (!isNaN(numA)) return -1;
28970
+ if (!isNaN(numB)) return 1;
28971
+ return a.localeCompare(b);
28972
+ });
28973
+ if (files.length === 0) {
28974
+ this.failSpinner("No deploy scripts found.");
28723
28975
  return;
28724
28976
  }
28725
- const leaderOnly = false;
28726
- let deployParams = { code: contractCode, args: options.args, leaderOnly };
28727
- console.log("Starting contract deployment...");
28728
- console.log("Deployment Parameters:", deployParams);
28977
+ this.setSpinnerText(`Found ${files.length} deploy scripts. Executing...`);
28978
+ for (const file of files) {
28979
+ const filePath = path4.resolve(this.deployDir, file);
28980
+ this.setSpinnerText(`Executing script: ${filePath}`);
28981
+ try {
28982
+ if (file.endsWith(".ts")) {
28983
+ await this.executeTsScript(filePath);
28984
+ } else {
28985
+ await this.executeJsScript(filePath);
28986
+ }
28987
+ } catch (error) {
28988
+ this.failSpinner(`Error executing script: ${filePath}`, error);
28989
+ }
28990
+ }
28991
+ }
28992
+ async deploy(options) {
28729
28993
  try {
28994
+ this.startSpinner("Setting up the deployment environment...");
28995
+ await this.genlayerClient.initializeConsensusSmartContract();
28996
+ if (!options.contract) {
28997
+ this.failSpinner("No contract specified for deployment.");
28998
+ return;
28999
+ }
29000
+ this.setSpinnerText("Reading contract code...");
29001
+ const contractCode = this.readContractCode(options.contract);
29002
+ if (!contractCode) {
29003
+ this.failSpinner("Contract code is empty.");
29004
+ return;
29005
+ }
29006
+ const leaderOnly = false;
29007
+ const deployParams = { code: contractCode, args: options.args, leaderOnly };
29008
+ this.setSpinnerText("Starting contract deployment...");
29009
+ this.log("Deployment Parameters:", deployParams);
28730
29010
  const hash2 = await this.genlayerClient.deployContract(deployParams);
28731
- const result = await this.genlayerClient.waitForTransactionReceipt({ hash: hash2, retries: 15, interval: 2e3 });
28732
- console.log("Contract deployed successfully.");
28733
- console.log("Transaction Hash:", hash2);
28734
- console.log("Contract Address:", result.data?.contract_address);
29011
+ const result = await this.genlayerClient.waitForTransactionReceipt({
29012
+ hash: hash2,
29013
+ retries: 15,
29014
+ interval: 2e3,
29015
+ status: TransactionStatus.ACCEPTED
29016
+ });
29017
+ this.log("Deployment Receipt:", result);
29018
+ this.succeedSpinner("Contract deployed successfully.", {
29019
+ "Transaction Hash": hash2,
29020
+ "Contract Address": result.data?.contract_address
29021
+ });
28735
29022
  } catch (error) {
28736
- console.error("Error deploying contract:", error);
28737
- throw new Error("Contract deployment failed.");
29023
+ this.failSpinner("Error deploying contract", error);
28738
29024
  }
28739
29025
  }
28740
29026
  };
28741
29027
 
28742
29028
  // src/commands/contracts/call.ts
28743
- var CallAction = class {
29029
+ var CallAction = class extends BaseAction {
28744
29030
  constructor() {
29031
+ super();
28745
29032
  __publicField(this, "genlayerClient");
28746
29033
  this.genlayerClient = createClient2({
28747
29034
  chain: simulator,
@@ -28754,23 +29041,18 @@ var CallAction = class {
28754
29041
  method,
28755
29042
  args
28756
29043
  }) {
28757
- console.log(`Calling method ${method} on contract at ${contractAddress}...`);
29044
+ this.startSpinner(`Calling method ${method} on contract at ${contractAddress}...`);
28758
29045
  const contractSchema = await this.genlayerClient.getContractSchema(contractAddress);
28759
29046
  if (!contractSchema.methods.hasOwnProperty(method)) {
28760
- console.error(`method ${method} not found.`);
28761
- process.exit(1);
29047
+ this.failSpinner(`method ${method} not found.`);
29048
+ return;
28762
29049
  }
28763
29050
  const readonly = contractSchema.methods[method].readonly;
28764
- try {
28765
- if (readonly) {
28766
- await this.executeRead(contractAddress, method, args);
28767
- } else {
28768
- await this.executeWrite(contractAddress, method, args);
28769
- }
28770
- } catch (error) {
28771
- console.error("Error calling contract method:", error);
28772
- throw error;
29051
+ if (readonly) {
29052
+ await this.executeRead(contractAddress, method, args);
29053
+ return;
28773
29054
  }
29055
+ await this.executeWrite(contractAddress, method, args);
28774
29056
  }
28775
29057
  async executeRead(contractAddress, method, args) {
28776
29058
  try {
@@ -28779,10 +29061,9 @@ var CallAction = class {
28779
29061
  functionName: method,
28780
29062
  args
28781
29063
  });
28782
- console.log("Read result:", result);
29064
+ this.succeedSpinner("Read operation successfully executed", result);
28783
29065
  } catch (error) {
28784
- console.error("Error during read operation:", error);
28785
- throw error;
29066
+ this.failSpinner("Error during read operation", error);
28786
29067
  }
28787
29068
  }
28788
29069
  async executeWrite(contractAddress, method, args) {
@@ -28798,22 +29079,31 @@ var CallAction = class {
28798
29079
  retries: 15,
28799
29080
  interval: 2e3
28800
29081
  });
28801
- console.log("Write transaction hash:", hash2);
28802
- console.log("Result:", result);
29082
+ this.log("Write transaction hash:", hash2);
29083
+ this.succeedSpinner("Write operation successfully executed", result);
28803
29084
  } catch (error) {
28804
- console.error("Error during write operation:", error);
28805
- throw error;
29085
+ this.failSpinner("Error during write operation", error);
28806
29086
  }
28807
29087
  }
28808
29088
  };
28809
29089
 
28810
29090
  // src/commands/contracts/index.ts
29091
+ function parseArg(value, previous = []) {
29092
+ if (value === "true") return [...previous, true];
29093
+ if (value === "false") return [...previous, false];
29094
+ if (!isNaN(Number(value))) return [...previous, Number(value)];
29095
+ return [...previous, value];
29096
+ }
28811
29097
  function initializeContractsCommands(program2) {
28812
- program2.command("deploy").description("Deploy intelligent contracts").option("--contract <contractPath>", "Path to the smart contract to deploy").option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", []).action(async (options) => {
29098
+ program2.command("deploy").description("Deploy intelligent contracts").option("--contract <contractPath>", "Path to the smart contract to deploy").option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", parseArg, []).action(async (options) => {
28813
29099
  const deployer = new DeployAction();
28814
- await deployer.deploy(options);
29100
+ if (options.contract) {
29101
+ await deployer.deploy(options);
29102
+ } else {
29103
+ await deployer.deployScripts();
29104
+ }
28815
29105
  });
28816
- program2.command("call <contractAddress> <method>").description("Call a contract method").option("--args <args...>", "Positional arguments for the method (space-separated, use quotes for multi-word arguments)", []).action(async (contractAddress, method, options) => {
29106
+ program2.command("call <contractAddress> <method>").description("Call a contract method").option("--args <args...>", "Positional arguments for the method (space-separated, use quotes for multi-word arguments)", parseArg, []).action(async (contractAddress, method, options) => {
28817
29107
  const caller = new CallAction();
28818
29108
  await caller.call({ contractAddress, method, ...options });
28819
29109
  });
@@ -29131,6 +29421,44 @@ function initializeUpdateCommands(program2) {
29131
29421
  return program2;
29132
29422
  }
29133
29423
 
29424
+ // src/commands/scaffold/new.ts
29425
+ import fs10 from "fs-extra";
29426
+ import path5 from "path";
29427
+ import { fileURLToPath as fileURLToPath3 } from "url";
29428
+ var NewAction = class extends BaseAction {
29429
+ constructor() {
29430
+ super();
29431
+ __publicField(this, "templatePath");
29432
+ const __filename = fileURLToPath3(import.meta.url);
29433
+ const basePath = path5.resolve(path5.dirname(__filename), "..");
29434
+ this.templatePath = path5.join(basePath, "templates", "default");
29435
+ }
29436
+ async createProject(projectName, options) {
29437
+ const targetPath = path5.resolve(options.path, projectName);
29438
+ if (fs10.existsSync(targetPath) && !options.overwrite) {
29439
+ return this.failSpinner(
29440
+ `Project directory "${targetPath}" already exists. Use --overwrite to replace it.`
29441
+ );
29442
+ }
29443
+ this.startSpinner(`Creating new GenLayer project: ${projectName}`);
29444
+ try {
29445
+ fs10.copySync(this.templatePath, targetPath);
29446
+ this.succeedSpinner(`Project "${projectName}" created successfully at ${targetPath}`);
29447
+ } catch (error) {
29448
+ this.failSpinner(`Error creating project "${projectName}"`, error);
29449
+ }
29450
+ }
29451
+ };
29452
+
29453
+ // src/commands/scaffold/index.ts
29454
+ function initializeScaffoldCommands(program2) {
29455
+ program2.command("new <projectName>").description("Create a new GenLayer project using the default template").option("--path <directory>", "Specify the directory for the new project", ".").option("--overwrite", "Overwrite existing directory if it exists", false).action(async (projectName, options) => {
29456
+ const newProjectAction = new NewAction();
29457
+ await newProjectAction.createProject(projectName, options);
29458
+ });
29459
+ return program2;
29460
+ }
29461
+
29134
29462
  // src/index.ts
29135
29463
  function initializeCLI() {
29136
29464
  program.version(version).description(CLI_DESCRIPTION);
@@ -29140,6 +29468,7 @@ function initializeCLI() {
29140
29468
  initializeConfigCommands(program);
29141
29469
  initializeUpdateCommands(program);
29142
29470
  initializeValidatorCommands(program);
29471
+ initializeScaffoldCommands(program);
29143
29472
  program.parse(process.argv);
29144
29473
  }
29145
29474
  initializeCLI();