create-fhevm-example 1.3.1 → 1.4.0

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 (122) hide show
  1. package/contracts/advanced/BlindAuction.sol +255 -0
  2. package/contracts/advanced/EncryptedEscrow.sol +315 -0
  3. package/contracts/advanced/HiddenVoting.sol +231 -0
  4. package/contracts/advanced/PrivateKYC.sol +309 -0
  5. package/contracts/advanced/PrivatePayroll.sol +285 -0
  6. package/contracts/basic/decryption/PublicDecryptMultipleValues.sol +160 -0
  7. package/contracts/basic/decryption/PublicDecryptSingleValue.sol +142 -0
  8. package/contracts/basic/decryption/UserDecryptMultipleValues.sol +61 -0
  9. package/contracts/basic/decryption/UserDecryptSingleValue.sol +59 -0
  10. package/contracts/basic/encryption/EncryptMultipleValues.sol +72 -0
  11. package/contracts/basic/encryption/EncryptSingleValue.sol +44 -0
  12. package/contracts/basic/encryption/FHECounter.sol +54 -0
  13. package/contracts/basic/fhe-operations/FHEAdd.sol +51 -0
  14. package/contracts/basic/fhe-operations/FHEArithmetic.sol +99 -0
  15. package/contracts/basic/fhe-operations/FHEComparison.sol +116 -0
  16. package/contracts/basic/fhe-operations/FHEIfThenElse.sol +53 -0
  17. package/contracts/concepts/FHEAccessControl.sol +94 -0
  18. package/contracts/concepts/FHEAntiPatterns.sol +329 -0
  19. package/contracts/concepts/FHEHandles.sol +128 -0
  20. package/contracts/concepts/FHEInputProof.sol +104 -0
  21. package/contracts/gaming/EncryptedLottery.sol +298 -0
  22. package/contracts/gaming/EncryptedPoker.sol +337 -0
  23. package/contracts/gaming/RockPaperScissors.sol +213 -0
  24. package/contracts/openzeppelin/ERC7984.sol +85 -0
  25. package/contracts/openzeppelin/ERC7984ERC20Wrapper.sol +43 -0
  26. package/contracts/openzeppelin/SwapERC7984ToERC20.sol +110 -0
  27. package/contracts/openzeppelin/SwapERC7984ToERC7984.sol +48 -0
  28. package/contracts/openzeppelin/VestingWallet.sol +147 -0
  29. package/contracts/openzeppelin/mocks/ERC20Mock.sol +31 -0
  30. package/dist/scripts/commands/add-mode.d.ts.map +1 -0
  31. package/dist/scripts/{add-mode.js → commands/add-mode.js} +27 -61
  32. package/dist/scripts/commands/doctor.d.ts.map +1 -0
  33. package/dist/scripts/{doctor.js → commands/doctor.js} +2 -2
  34. package/dist/scripts/commands/generate-config.d.ts.map +1 -0
  35. package/dist/scripts/{generate-config.js → commands/generate-config.js} +3 -10
  36. package/dist/scripts/commands/generate-docs.d.ts.map +1 -0
  37. package/dist/scripts/{generate-docs.js → commands/generate-docs.js} +4 -3
  38. package/dist/scripts/commands/maintenance.d.ts.map +1 -0
  39. package/dist/scripts/{maintenance.js → commands/maintenance.js} +11 -10
  40. package/dist/scripts/index.js +63 -59
  41. package/dist/scripts/{builders.d.ts → shared/builders.d.ts} +2 -2
  42. package/dist/scripts/shared/builders.d.ts.map +1 -0
  43. package/dist/scripts/{builders.js → shared/builders.js} +49 -30
  44. package/dist/scripts/{config.d.ts → shared/config.d.ts} +0 -2
  45. package/dist/scripts/shared/config.d.ts.map +1 -0
  46. package/dist/scripts/{config.js → shared/config.js} +48 -59
  47. package/dist/scripts/shared/generators.d.ts +42 -0
  48. package/dist/scripts/shared/generators.d.ts.map +1 -0
  49. package/dist/scripts/{utils.js → shared/generators.js} +34 -271
  50. package/dist/scripts/shared/ui.d.ts.map +1 -0
  51. package/dist/scripts/{ui.js → shared/ui.js} +3 -2
  52. package/dist/scripts/{utils.d.ts → shared/utils.d.ts} +4 -27
  53. package/dist/scripts/shared/utils.d.ts.map +1 -0
  54. package/dist/scripts/shared/utils.js +228 -0
  55. package/fhevm-hardhat-template/.eslintignore +26 -0
  56. package/fhevm-hardhat-template/.eslintrc.yml +21 -0
  57. package/fhevm-hardhat-template/.github/workflows/main.yml +47 -0
  58. package/fhevm-hardhat-template/.github/workflows/manual-windows.yml +28 -0
  59. package/fhevm-hardhat-template/.github/workflows/manual.yml +28 -0
  60. package/fhevm-hardhat-template/.prettierignore +25 -0
  61. package/fhevm-hardhat-template/.prettierrc.yml +15 -0
  62. package/fhevm-hardhat-template/.solcover.js +4 -0
  63. package/fhevm-hardhat-template/.solhint.json +12 -0
  64. package/fhevm-hardhat-template/.solhintignore +3 -0
  65. package/fhevm-hardhat-template/.vscode/extensions.json +3 -0
  66. package/fhevm-hardhat-template/.vscode/settings.json +9 -0
  67. package/fhevm-hardhat-template/LICENSE +33 -0
  68. package/fhevm-hardhat-template/README.md +110 -0
  69. package/fhevm-hardhat-template/contracts/FHECounter.sol +46 -0
  70. package/fhevm-hardhat-template/deploy/deploy.ts +17 -0
  71. package/fhevm-hardhat-template/hardhat.config.ts +90 -0
  72. package/fhevm-hardhat-template/package-lock.json +10405 -0
  73. package/fhevm-hardhat-template/package.json +104 -0
  74. package/fhevm-hardhat-template/tasks/FHECounter.ts +184 -0
  75. package/fhevm-hardhat-template/tasks/accounts.ts +9 -0
  76. package/fhevm-hardhat-template/test/FHECounter.ts +104 -0
  77. package/fhevm-hardhat-template/test/FHECounterSepolia.ts +104 -0
  78. package/fhevm-hardhat-template/tsconfig.json +23 -0
  79. package/package.json +13 -10
  80. package/test/advanced/BlindAuction.ts +246 -0
  81. package/test/advanced/EncryptedEscrow.ts +295 -0
  82. package/test/advanced/HiddenVoting.ts +268 -0
  83. package/test/advanced/PrivateKYC.ts +382 -0
  84. package/test/advanced/PrivatePayroll.ts +253 -0
  85. package/test/basic/decryption/PublicDecryptMultipleValues.ts +254 -0
  86. package/test/basic/decryption/PublicDecryptSingleValue.ts +264 -0
  87. package/test/basic/decryption/UserDecryptMultipleValues.ts +107 -0
  88. package/test/basic/decryption/UserDecryptSingleValue.ts +97 -0
  89. package/test/basic/encryption/EncryptMultipleValues.ts +110 -0
  90. package/test/basic/encryption/EncryptSingleValue.ts +124 -0
  91. package/test/basic/encryption/FHECounter.ts +112 -0
  92. package/test/basic/fhe-operations/FHEAdd.ts +97 -0
  93. package/test/basic/fhe-operations/FHEArithmetic.ts +161 -0
  94. package/test/basic/fhe-operations/FHEComparison.ts +167 -0
  95. package/test/basic/fhe-operations/FHEIfThenElse.ts +97 -0
  96. package/test/concepts/FHEAccessControl.ts +154 -0
  97. package/test/concepts/FHEAntiPatterns.ts +111 -0
  98. package/test/concepts/FHEHandles.ts +156 -0
  99. package/test/concepts/FHEInputProof.ts +151 -0
  100. package/test/gaming/EncryptedLottery.ts +214 -0
  101. package/test/gaming/EncryptedPoker.ts +349 -0
  102. package/test/gaming/RockPaperScissors.ts +205 -0
  103. package/test/openzeppelin/ERC7984.ts +142 -0
  104. package/test/openzeppelin/ERC7984ERC20Wrapper.ts +71 -0
  105. package/test/openzeppelin/SwapERC7984ToERC20.ts +76 -0
  106. package/test/openzeppelin/SwapERC7984ToERC7984.ts +113 -0
  107. package/test/openzeppelin/VestingWallet.ts +89 -0
  108. package/dist/scripts/add-mode.d.ts.map +0 -1
  109. package/dist/scripts/builders.d.ts.map +0 -1
  110. package/dist/scripts/config.d.ts.map +0 -1
  111. package/dist/scripts/doctor.d.ts.map +0 -1
  112. package/dist/scripts/generate-config.d.ts.map +0 -1
  113. package/dist/scripts/generate-docs.d.ts.map +0 -1
  114. package/dist/scripts/maintenance.d.ts.map +0 -1
  115. package/dist/scripts/ui.d.ts.map +0 -1
  116. package/dist/scripts/utils.d.ts.map +0 -1
  117. /package/dist/scripts/{add-mode.d.ts → commands/add-mode.d.ts} +0 -0
  118. /package/dist/scripts/{doctor.d.ts → commands/doctor.d.ts} +0 -0
  119. /package/dist/scripts/{generate-config.d.ts → commands/generate-config.d.ts} +0 -0
  120. /package/dist/scripts/{generate-docs.d.ts → commands/generate-docs.d.ts} +0 -0
  121. /package/dist/scripts/{maintenance.d.ts → commands/maintenance.d.ts} +0 -0
  122. /package/dist/scripts/{ui.d.ts → shared/ui.d.ts} +0 -0
@@ -47,8 +47,8 @@ const p = __importStar(require("@clack/prompts"));
47
47
  const picocolors_1 = __importDefault(require("picocolors"));
48
48
  const fs = __importStar(require("fs"));
49
49
  const path = __importStar(require("path"));
50
- const config_1 = require("./config");
51
- const utils_1 = require("./utils");
50
+ const config_1 = require("../shared/config");
51
+ const utils_1 = require("../shared/utils");
52
52
  // =============================================================================
53
53
  // PROJECT DETECTION
54
54
  // =============================================================================
@@ -136,88 +136,54 @@ function updateHardhatConfig(targetDir) {
136
136
  /**
137
137
  * Adds example contract and test files to the project
138
138
  */
139
- async function addExampleFiles(exampleName, targetDir) {
139
+ function addExampleFiles(exampleName, targetDir) {
140
140
  const example = config_1.EXAMPLES[exampleName];
141
141
  if (!example) {
142
142
  throw new Error(`Unknown example: ${exampleName}`);
143
143
  }
144
+ const rootDir = (0, utils_1.getRootDir)();
144
145
  const contractName = (0, utils_1.getContractName)(example.contract);
145
146
  if (!contractName) {
146
147
  throw new Error("Could not extract contract name");
147
148
  }
149
+ const contractSource = path.join(rootDir, example.contract);
150
+ const testSource = path.join(rootDir, example.test);
148
151
  // Handle contract file
149
152
  let contractDest = path.join(targetDir, "contracts", `${contractName}.sol`);
153
+ const contractsDir = path.join(targetDir, "contracts");
154
+ if (!fs.existsSync(contractsDir)) {
155
+ fs.mkdirSync(contractsDir, { recursive: true });
156
+ }
150
157
  if (fs.existsSync(contractDest)) {
151
- const action = await p.select({
152
- message: `${contractName}.sol already exists. What do you want to do?`,
153
- options: [
154
- { value: "skip", label: "Skip contract" },
155
- { value: "overwrite", label: "Overwrite existing file" },
156
- {
157
- value: "rename",
158
- label: `Rename to ${contractName}_fhevm.sol`,
159
- },
160
- ],
161
- });
162
- if (p.isCancel(action)) {
163
- throw new Error("Operation cancelled");
164
- }
165
- if (action === "skip") {
166
- p.log.info(`Skipped: ${contractName}.sol`);
167
- }
168
- else if (action === "rename") {
169
- contractDest = path.join(targetDir, "contracts", `${contractName}_fhevm.sol`);
170
- await (0, utils_1.downloadFileFromGitHub)(example.contract, contractDest);
171
- p.log.success(`Added: ${contractName}_fhevm.sol`);
172
- }
173
- else {
174
- await (0, utils_1.downloadFileFromGitHub)(example.contract, contractDest);
175
- p.log.success(`Overwritten: ${contractName}.sol`);
176
- }
158
+ // File exists - will be handled by caller with prompts
159
+ fs.copyFileSync(contractSource, contractDest);
160
+ p.log.success(`Overwritten: ${contractName}.sol`);
177
161
  }
178
162
  else {
179
- const contractsDir = path.join(targetDir, "contracts");
180
- if (!fs.existsSync(contractsDir)) {
181
- fs.mkdirSync(contractsDir, { recursive: true });
182
- }
183
- await (0, utils_1.downloadFileFromGitHub)(example.contract, contractDest);
163
+ fs.copyFileSync(contractSource, contractDest);
184
164
  p.log.success(`Added: ${contractName}.sol`);
185
165
  }
186
166
  // Handle test file
187
167
  const testFileName = path.basename(example.test);
188
- let testDest = path.join(targetDir, "test", testFileName);
168
+ const testDest = path.join(targetDir, "test", testFileName);
169
+ const testDir = path.join(targetDir, "test");
170
+ if (!fs.existsSync(testDir)) {
171
+ fs.mkdirSync(testDir, { recursive: true });
172
+ }
189
173
  if (fs.existsSync(testDest)) {
190
- const action = await p.select({
191
- message: `${testFileName} already exists. What do you want to do?`,
192
- options: [
193
- { value: "skip", label: "Skip test" },
194
- { value: "overwrite", label: "Overwrite existing file" },
195
- ],
196
- });
197
- if (p.isCancel(action)) {
198
- throw new Error("Operation cancelled");
199
- }
200
- if (action === "skip") {
201
- p.log.info(`Skipped: ${testFileName}`);
202
- }
203
- else {
204
- await (0, utils_1.downloadFileFromGitHub)(example.test, testDest);
205
- p.log.success(`Overwritten: ${testFileName}`);
206
- }
174
+ fs.copyFileSync(testSource, testDest);
175
+ p.log.success(`Overwritten: ${testFileName}`);
207
176
  }
208
177
  else {
209
- const testDir = path.join(targetDir, "test");
210
- if (!fs.existsSync(testDir)) {
211
- fs.mkdirSync(testDir, { recursive: true });
212
- }
213
- await (0, utils_1.downloadFileFromGitHub)(example.test, testDest);
178
+ fs.copyFileSync(testSource, testDest);
214
179
  p.log.success(`Added: ${testFileName}`);
215
180
  }
216
181
  // Handle contract dependencies
217
182
  if (example.dependencies) {
218
183
  p.log.message("");
219
- p.log.message(picocolors_1.default.bold("Downloading contract dependencies..."));
184
+ p.log.message(picocolors_1.default.bold("Copying contract dependencies..."));
220
185
  for (const depPath of example.dependencies) {
186
+ const depSource = path.join(rootDir, depPath);
221
187
  const relativePath = depPath.replace(/^contracts\//, "");
222
188
  const depDestPath = path.join(targetDir, "contracts", relativePath);
223
189
  const depDestDir = path.dirname(depDestPath);
@@ -228,8 +194,8 @@ async function addExampleFiles(exampleName, targetDir) {
228
194
  if (fs.existsSync(depDestPath)) {
229
195
  p.log.info(`Skipped (exists): ${depName}`);
230
196
  }
231
- else {
232
- await (0, utils_1.downloadFileFromGitHub)(depPath, depDestPath);
197
+ else if (fs.existsSync(depSource)) {
198
+ fs.copyFileSync(depSource, depDestPath);
233
199
  p.log.success(`Added: ${depName}`);
234
200
  }
235
201
  }
@@ -313,7 +279,7 @@ async function runAddMode(targetDir) {
313
279
  p.log.message("");
314
280
  p.log.message(picocolors_1.default.bold("Adding example files..."));
315
281
  try {
316
- await addExampleFiles(exampleName, absoluteDir);
282
+ addExampleFiles(exampleName, absoluteDir);
317
283
  }
318
284
  catch (error) {
319
285
  p.log.error("Failed to add example files");
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../scripts/commands/doctor.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
@@ -50,8 +50,8 @@ const path = __importStar(require("path"));
50
50
  const child_process_1 = require("child_process");
51
51
  const p = __importStar(require("@clack/prompts"));
52
52
  const picocolors_1 = __importDefault(require("picocolors"));
53
- const utils_1 = require("./utils");
54
- const config_1 = require("./config");
53
+ const utils_1 = require("../shared/utils");
54
+ const config_1 = require("../shared/config");
55
55
  const ROOT_DIR = (0, utils_1.getRootDir)();
56
56
  // =============================================================================
57
57
  // Checks
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-config.d.ts","sourceRoot":"","sources":["../../../scripts/commands/generate-config.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
@@ -45,12 +45,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
45
45
  Object.defineProperty(exports, "__esModule", { value: true });
46
46
  const fs = __importStar(require("fs"));
47
47
  const path = __importStar(require("path"));
48
- const utils_1 = require("./utils");
48
+ const utils_1 = require("../shared/utils");
49
49
  const picocolors_1 = __importDefault(require("picocolors"));
50
- const ROOT_DIR = path.resolve(__dirname, "..");
50
+ const ROOT_DIR = path.resolve(__dirname, "../..");
51
51
  const CONTRACTS_DIR = path.join(ROOT_DIR, "contracts");
52
52
  const TEST_DIR = path.join(ROOT_DIR, "test");
53
- const OUTPUT_FILE = path.join(ROOT_DIR, "scripts/config.ts");
53
+ const OUTPUT_FILE = path.join(ROOT_DIR, "scripts/shared/config.ts");
54
54
  // =============================================================================
55
55
  // Contract Analysis
56
56
  // =============================================================================
@@ -234,13 +234,6 @@ export interface CategoryConfig {
234
234
  contracts: Array<{ sol: string; test?: string }>;
235
235
  }
236
236
 
237
- // =============================================================================
238
- // GitHub Repository Configuration
239
- // =============================================================================
240
-
241
- export const REPO_URL = "https://github.com/NecipAkgz/fhevm-example-factory";
242
- export const REPO_BRANCH = "main";
243
-
244
237
  // =============================================================================
245
238
  // Example Configurations
246
239
  // =============================================================================
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-docs.d.ts","sourceRoot":"","sources":["../../../scripts/commands/generate-docs.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAkEH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiE3D;AAMD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhE"}
@@ -49,8 +49,9 @@ const p = __importStar(require("@clack/prompts"));
49
49
  const picocolors_1 = __importDefault(require("picocolors"));
50
50
  const fs = __importStar(require("fs"));
51
51
  const path = __importStar(require("path"));
52
- const config_1 = require("./config");
53
- const utils_1 = require("./utils");
52
+ const config_1 = require("../shared/config");
53
+ const utils_1 = require("../shared/utils");
54
+ const generators_1 = require("../shared/generators");
54
55
  // =============================================================================
55
56
  // Documentation Generator
56
57
  // =============================================================================
@@ -70,7 +71,7 @@ async function generateDocumentation(exampleName) {
70
71
  const testContent = fs.readFileSync(testPath, "utf-8");
71
72
  const contractName = (0, utils_1.getContractName)(example.contract) || "Contract";
72
73
  const testFileName = path.basename(example.test);
73
- const markdown = (0, utils_1.generateGitBookMarkdown)(example.description, contractContent, testContent, contractName, testFileName);
74
+ const markdown = (0, generators_1.generateGitBookMarkdown)(example.description, contractContent, testContent, contractName, testFileName);
74
75
  const outputPath = example.docsOutput
75
76
  ? path.join(rootDir, example.docsOutput)
76
77
  : path.join(rootDir, "docs", `${(0, config_1.getDocsFileName)(name)}.md`);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../../scripts/commands/maintenance.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAuNH,wBAAsB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC3E"}
@@ -52,9 +52,10 @@ const p = __importStar(require("@clack/prompts"));
52
52
  const picocolors_1 = __importDefault(require("picocolors"));
53
53
  const fs = __importStar(require("fs"));
54
54
  const path = __importStar(require("path"));
55
- const config_1 = require("./config");
56
- const utils_1 = require("./utils");
57
- const builders_1 = require("./builders");
55
+ const config_1 = require("../shared/config");
56
+ const utils_1 = require("../shared/utils");
57
+ const generators_1 = require("../shared/generators");
58
+ const builders_1 = require("../shared/builders");
58
59
  // =============================================================================
59
60
  // Example Selection
60
61
  // =============================================================================
@@ -98,19 +99,19 @@ async function runTestPipeline(tempDir, exampleCount) {
98
99
  };
99
100
  const s1 = p.spinner();
100
101
  s1.start("Installing dependencies...");
101
- const installResult = await (0, utils_1.runCommandWithStatus)("npm", ["install"], tempDir);
102
+ const installResult = await (0, generators_1.runCommandWithStatus)("npm", ["install"], tempDir);
102
103
  if (!installResult.success) {
103
104
  s1.stop(picocolors_1.default.red("✗ npm install failed"));
104
- p.log.error((0, utils_1.extractErrorMessage)(installResult.output));
105
+ p.log.error((0, generators_1.extractErrorMessage)(installResult.output));
105
106
  return summary;
106
107
  }
107
108
  s1.stop(picocolors_1.default.green("✓ Dependencies installed"));
108
109
  const s2 = p.spinner();
109
110
  s2.start("Compiling contracts...");
110
- const compileResult = await (0, utils_1.runCommandWithStatus)("npm", ["run", "compile"], tempDir);
111
+ const compileResult = await (0, generators_1.runCommandWithStatus)("npm", ["run", "compile"], tempDir);
111
112
  if (!compileResult.success) {
112
113
  s2.stop(picocolors_1.default.red("✗ Compilation failed"));
113
- p.log.error((0, utils_1.extractErrorMessage)(compileResult.output));
114
+ p.log.error((0, generators_1.extractErrorMessage)(compileResult.output));
114
115
  return summary;
115
116
  }
116
117
  s2.stop(picocolors_1.default.green("✓ Contracts compiled"));
@@ -135,10 +136,10 @@ async function runTestPipeline(tempDir, exampleCount) {
135
136
  const progress = `[${i + 1}/${testFiles.length}]`;
136
137
  process.stdout.write(` ${picocolors_1.default.dim(progress)} ${testFile} `);
137
138
  const testStart = Date.now();
138
- const result = await (0, utils_1.runCommandWithStatus)("npx", ["hardhat", "test", `test/${testFile}`], tempDir);
139
+ const result = await (0, generators_1.runCommandWithStatus)("npx", ["hardhat", "test", `test/${testFile}`], tempDir);
139
140
  const duration = ((Date.now() - testStart) / 1000).toFixed(1);
140
141
  if (result.success) {
141
- const testResults = (0, utils_1.extractTestResults)(result.output);
142
+ const testResults = (0, generators_1.extractTestResults)(result.output);
142
143
  const resultInfo = testResults
143
144
  ? picocolors_1.default.dim(`(${testResults.replace(" ✓", "")})`)
144
145
  : "";
@@ -149,7 +150,7 @@ async function runTestPipeline(tempDir, exampleCount) {
149
150
  p.log.message(picocolors_1.default.red(`✗`) + ` ${picocolors_1.default.dim(duration + "s")}`);
150
151
  failedTests++;
151
152
  summary.failedTests.push(testFile);
152
- const errorMsg = (0, utils_1.extractErrorMessage)(result.output);
153
+ const errorMsg = (0, generators_1.extractErrorMessage)(result.output);
153
154
  if (errorMsg) {
154
155
  const shortError = errorMsg.split("\n")[0].slice(0, 80);
155
156
  p.log.message(` ${picocolors_1.default.red(picocolors_1.default.dim(shortError))}`);
@@ -50,13 +50,12 @@ const p = __importStar(require("@clack/prompts"));
50
50
  const picocolors_1 = __importDefault(require("picocolors"));
51
51
  const fs = __importStar(require("fs"));
52
52
  const path = __importStar(require("path"));
53
- const os = __importStar(require("os"));
54
- const config_1 = require("./config");
55
- const utils_1 = require("./utils");
56
- const builders_1 = require("./builders");
57
- const ui_1 = require("./ui");
58
- const add_mode_1 = require("./add-mode");
59
- const generate_docs_1 = require("./generate-docs");
53
+ const config_1 = require("./shared/config");
54
+ const utils_1 = require("./shared/utils");
55
+ const builders_1 = require("./shared/builders");
56
+ const ui_1 = require("./shared/ui");
57
+ const add_mode_1 = require("./commands/add-mode");
58
+ const generate_docs_1 = require("./commands/generate-docs");
60
59
  /** Prompts user to select mode and returns project configuration */
61
60
  async function getProjectConfig() {
62
61
  // Build options - docs only available in local dev mode
@@ -155,19 +154,14 @@ async function scaffoldProject(config) {
155
154
  p.log.error(`Directory already exists: ${resolvedOutput}`);
156
155
  process.exit(1);
157
156
  }
158
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "fhevm-"));
159
157
  const s = p.spinner();
160
158
  try {
161
- s.start("Downloading template...");
162
- const tempRepoPath = await (0, utils_1.cloneTemplate)(tempDir);
163
- s.message("Initializing submodules...");
164
- await (0, utils_1.initSubmodule)(tempRepoPath);
165
- s.message("Scaffolding your confidential project...");
159
+ s.start("Scaffolding your confidential project...");
166
160
  if (config.mode === "single") {
167
- await (0, builders_1.createSingleExample)(config.name, resolvedOutput, tempRepoPath);
161
+ (0, builders_1.createSingleExample)(config.name, resolvedOutput);
168
162
  }
169
163
  else {
170
- await (0, builders_1.createCategoryProject)(config.name, resolvedOutput, tempRepoPath);
164
+ (0, builders_1.createCategoryProject)(config.name, resolvedOutput);
171
165
  }
172
166
  s.stop("🎉 Project scaffolded successfully!");
173
167
  const relativePath = path.relative(process.cwd(), resolvedOutput);
@@ -198,11 +192,6 @@ async function scaffoldProject(config) {
198
192
  p.log.error(error instanceof Error ? error.message : String(error));
199
193
  process.exit(1);
200
194
  }
201
- finally {
202
- if (fs.existsSync(tempDir)) {
203
- fs.rmSync(tempDir, { recursive: true, force: true });
204
- }
205
- }
206
195
  p.outro(picocolors_1.default.green("✅ Setup complete. Happy encrypting!"));
207
196
  }
208
197
  /** Main interactive mode entry point */
@@ -282,20 +271,15 @@ async function runDirectMode(args) {
282
271
  catch (error) {
283
272
  (0, utils_1.handleError)(error);
284
273
  }
285
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "fhevm-"));
286
274
  try {
287
275
  utils_1.log.info(`\n🚀 Creating ${mode}: ${picocolors_1.default.yellow(name)}`);
288
276
  utils_1.log.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
289
- utils_1.log.dim("Downloading template...");
290
- const tempRepoPath = await (0, utils_1.cloneTemplate)(tempDir);
291
- utils_1.log.dim("Initializing submodules...");
292
- await (0, utils_1.initSubmodule)(tempRepoPath);
293
277
  utils_1.log.dim("Building project...");
294
278
  if (mode === "example") {
295
- await (0, builders_1.createSingleExample)(name, resolved, tempRepoPath);
279
+ (0, builders_1.createSingleExample)(name, resolved);
296
280
  }
297
281
  else {
298
- await (0, builders_1.createCategoryProject)(name, resolved, tempRepoPath);
282
+ (0, builders_1.createCategoryProject)(name, resolved);
299
283
  }
300
284
  utils_1.log.success(`\n✨ Successfully created: ${picocolors_1.default.cyan(output)}`);
301
285
  if (shouldInstall) {
@@ -313,59 +297,79 @@ async function runDirectMode(args) {
313
297
  catch (error) {
314
298
  (0, utils_1.handleError)(error);
315
299
  }
316
- finally {
317
- if (fs.existsSync(tempDir)) {
318
- fs.rmSync(tempDir, { recursive: true, force: true });
319
- }
320
- }
321
300
  }
322
301
  // =============================================================================
323
302
  // QUICK MODE (CLI Arguments)
324
303
  // =============================================================================
325
304
  function showHelp() {
326
- console.log(`
305
+ const isDev = process.env.LOCAL_DEV === "1";
306
+ if (isDev) {
307
+ // Developer help - show npm run scripts
308
+ console.log(`
309
+ ${picocolors_1.default.bgCyan(picocolors_1.default.black(picocolors_1.default.bold(" 🔐 FHEVM Example Factory - Developer Mode ")))}
310
+ ${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
311
+
312
+ ${picocolors_1.default.cyan(picocolors_1.default.bold("📋 CREATE COMMANDS"))}
313
+
314
+ ${picocolors_1.default.green("npm run create")} Interactive mode ${picocolors_1.default.yellow("(recommended)")}
315
+ ${picocolors_1.default.green("npm run create:example")} ${picocolors_1.default.dim("<name>")} Create single example
316
+ ${picocolors_1.default.green("npm run create:category")} ${picocolors_1.default.dim("<name>")} Create category project
317
+ ${picocolors_1.default.green("npm run create:docs")} Generate documentation
318
+
319
+ ${picocolors_1.default.cyan(picocolors_1.default.bold("🛠️ MAINTENANCE"))}
320
+
321
+ ${picocolors_1.default.green("npm run test:all")} Test multiple examples
322
+ ${picocolors_1.default.green("npm run generate:config")} Update contract registry
323
+ ${picocolors_1.default.green("npm run doctor")} System health check
324
+
325
+ ${picocolors_1.default.cyan(picocolors_1.default.bold("❓ HELP"))}
326
+
327
+ ${picocolors_1.default.green("npm run help:create")} This help
328
+ ${picocolors_1.default.green("npm run help:docs")} Docs generator help
329
+ ${picocolors_1.default.green("npm run help:test")} Test runner help
330
+
331
+ ${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
332
+ `);
333
+ }
334
+ else {
335
+ // End-user help - show npx commands
336
+ console.log(`
327
337
  ${picocolors_1.default.bgCyan(picocolors_1.default.black(picocolors_1.default.bold(" 🔐 create-fhevm-example ")))}
328
338
  ${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
329
339
 
330
340
  ${picocolors_1.default.cyan(picocolors_1.default.bold("📋 USAGE"))}
331
341
 
332
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.dim("→")} Interactive mode ${picocolors_1.default.yellow("(recommended)")}
333
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Create single example
334
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--category")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Create category project
335
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--add")} ${picocolors_1.default.dim("→")} Add to existing project
342
+ ${picocolors_1.default.dim("$")} npx create-fhevm-example ${picocolors_1.default.dim("→")} Interactive ${picocolors_1.default.yellow("(recommended)")}
343
+ ${picocolors_1.default.dim("$")} npx create-fhevm-example ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Single example
344
+ ${picocolors_1.default.dim("$")} npx create-fhevm-example ${picocolors_1.default.green("--category")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Category project
345
+ ${picocolors_1.default.dim("$")} npx create-fhevm-example ${picocolors_1.default.green("--add")} ${picocolors_1.default.dim("→")} Add to existing project
336
346
 
337
347
  ${picocolors_1.default.cyan(picocolors_1.default.bold("⚙️ OPTIONS"))}
338
348
 
339
- ${picocolors_1.default.green("--example")} ${picocolors_1.default.dim("<name>")} Create a single example project
340
- ${picocolors_1.default.green("--category")} ${picocolors_1.default.dim("<name>")} Create a category project
341
- ${picocolors_1.default.green("--add")} Add FHEVM to existing Hardhat project
342
- ${picocolors_1.default.green("--target")} ${picocolors_1.default.dim("<dir>")} Target directory for --add mode
343
- ${picocolors_1.default.green("--output")} ${picocolors_1.default.dim("<dir>")} Output directory
344
- ${picocolors_1.default.green("--install")} Auto-install dependencies
345
- ${picocolors_1.default.green("--test")} Auto-run tests (requires --install)
346
- ${picocolors_1.default.green("--help")}${picocolors_1.default.dim(", -h")} Show this help message
349
+ ${picocolors_1.default.green("--example")} ${picocolors_1.default.dim("<name>")} Single example project
350
+ ${picocolors_1.default.green("--category")} ${picocolors_1.default.dim("<name>")} Category project
351
+ ${picocolors_1.default.green("--add")} Add FHEVM to existing Hardhat project
352
+ ${picocolors_1.default.green("--output")} ${picocolors_1.default.dim("<dir>")} Output directory
353
+ ${picocolors_1.default.green("--install")} Auto-install dependencies
354
+ ${picocolors_1.default.green("--help")} Show this help
347
355
 
348
356
  ${picocolors_1.default.cyan(picocolors_1.default.bold("⚡ EXAMPLES"))}
349
357
 
350
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("fhe-counter")}
351
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--category")} ${picocolors_1.default.yellow("basic")} ${picocolors_1.default.green("--output")} ${picocolors_1.default.blue("./my-project")}
352
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--add")}
353
- ${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("fhe-counter")} ${picocolors_1.default.green("--install")} ${picocolors_1.default.green("--test")}
354
-
355
- ${picocolors_1.default.cyan(picocolors_1.default.bold("📦 AVAILABLE EXAMPLES"))}
358
+ ${picocolors_1.default.dim("$")} npx create-fhevm-example --example fhe-counter
359
+ ${picocolors_1.default.dim("$")} npx create-fhevm-example --category basic --output ./my-project
360
+ ${picocolors_1.default.dim("$")} npx create-fhevm-example --add
356
361
 
357
- ${picocolors_1.default.dim(Object.keys(config_1.EXAMPLES).slice(0, 10).join(", "))}
358
- ${picocolors_1.default.dim("...")} and ${picocolors_1.default.yellow(String(Object.keys(config_1.EXAMPLES).length - 10))} more
362
+ ${picocolors_1.default.cyan(picocolors_1.default.bold("📦 AVAILABLE"))}
359
363
 
360
- ${picocolors_1.default.cyan(picocolors_1.default.bold("📁 AVAILABLE CATEGORIES"))}
361
-
362
- ${Object.keys(config_1.CATEGORIES)
363
- .map((c) => picocolors_1.default.yellow(c))
364
- .join(", ")}
364
+ Examples: ${picocolors_1.default.dim(Object.keys(config_1.EXAMPLES).slice(0, 5).join(", "))} ${picocolors_1.default.dim("...")} (${Object.keys(config_1.EXAMPLES).length} total)
365
+ Categories: ${Object.keys(config_1.CATEGORIES)
366
+ .map((c) => picocolors_1.default.yellow(c))
367
+ .join(", ")}
365
368
 
366
369
  ${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
367
- ${picocolors_1.default.dim("📚 Documentation:")} ${picocolors_1.default.blue("https://github.com/NecipAkgz/fhevm-example-factory")}
370
+ ${picocolors_1.default.dim("📚 Docs:")} ${picocolors_1.default.blue("https://github.com/NecipAkgz/fhevm-example-factory")}
368
371
  `);
372
+ }
369
373
  }
370
374
  // =============================================================================
371
375
  // MAIN ENTRY POINT
@@ -7,11 +7,11 @@
7
7
  /**
8
8
  * Creates a single example project from the template
9
9
  */
10
- export declare function createSingleExample(exampleName: string, outputDir: string, tempRepoPath: string): Promise<void>;
10
+ export declare function createSingleExample(exampleName: string, outputDir: string): void;
11
11
  /**
12
12
  * Creates a category project with multiple examples
13
13
  */
14
- export declare function createCategoryProject(categoryName: string, outputDir: string, tempRepoPath: string): Promise<void>;
14
+ export declare function createCategoryProject(categoryName: string, outputDir: string): void;
15
15
  /**
16
16
  * Creates a temporary test project using LOCAL files (used by maintenance.ts)
17
17
  */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../../scripts/shared/builders.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6DH;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,IAAI,CAkDN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,IAAI,CAwEN;AAMD;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EAAE,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAuEf"}