create-fhevm-example 1.2.2 → 1.3.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.
- package/README.md +74 -148
- package/dist/scripts/add-mode.d.ts +8 -0
- package/dist/scripts/add-mode.d.ts.map +1 -0
- package/dist/{add-mode.js → scripts/add-mode.js} +81 -58
- package/dist/scripts/builders.d.ts +20 -0
- package/dist/scripts/builders.d.ts.map +1 -0
- package/dist/scripts/builders.js +160 -0
- package/dist/{config.d.ts → scripts/config.d.ts} +24 -3
- package/dist/scripts/config.d.ts.map +1 -0
- package/dist/scripts/config.js +465 -0
- package/dist/scripts/doctor.d.ts +3 -0
- package/dist/scripts/doctor.d.ts.map +1 -0
- package/dist/scripts/doctor.js +157 -0
- package/dist/scripts/generate-config.d.ts +9 -0
- package/dist/scripts/generate-config.d.ts.map +1 -0
- package/dist/scripts/generate-config.js +315 -0
- package/dist/scripts/generate-docs.d.ts +9 -0
- package/dist/scripts/generate-docs.d.ts.map +1 -0
- package/dist/scripts/generate-docs.js +189 -0
- package/dist/scripts/index.d.ts +12 -0
- package/dist/scripts/index.d.ts.map +1 -0
- package/dist/scripts/index.js +360 -0
- package/dist/scripts/maintenance.d.ts +12 -0
- package/dist/scripts/maintenance.d.ts.map +1 -0
- package/dist/scripts/maintenance.js +320 -0
- package/dist/{ui.d.ts → scripts/ui.d.ts} +0 -1
- package/dist/scripts/ui.d.ts.map +1 -0
- package/dist/scripts/ui.js +197 -0
- package/dist/scripts/utils.d.ts +79 -0
- package/dist/scripts/utils.d.ts.map +1 -0
- package/dist/scripts/utils.js +504 -0
- package/package.json +24 -12
- package/dist/add-mode.d.ts +0 -21
- package/dist/add-mode.d.ts.map +0 -1
- package/dist/add-mode.js.map +0 -1
- package/dist/builders.d.ts +0 -30
- package/dist/builders.d.ts.map +0 -1
- package/dist/builders.js +0 -195
- package/dist/builders.js.map +0 -1
- package/dist/commands.d.ts +0 -19
- package/dist/commands.d.ts.map +0 -1
- package/dist/commands.js +0 -91
- package/dist/commands.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -403
- package/dist/config.js.map +0 -1
- package/dist/constants.d.ts +0 -16
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -40
- package/dist/constants.js.map +0 -1
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -337
- package/dist/index.js.map +0 -1
- package/dist/prompts.d.ts +0 -26
- package/dist/prompts.d.ts.map +0 -1
- package/dist/prompts.js +0 -79
- package/dist/prompts.js.map +0 -1
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js +0 -155
- package/dist/ui.js.map +0 -1
- package/dist/utils.d.ts +0 -99
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -285
- package/dist/utils.js.map +0 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project Builders
|
|
4
|
+
*
|
|
5
|
+
* Creates single example and category projects from templates.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.createSingleExample = createSingleExample;
|
|
42
|
+
exports.createCategoryProject = createCategoryProject;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const config_1 = require("./config");
|
|
46
|
+
const utils_1 = require("./utils");
|
|
47
|
+
// =============================================================================
|
|
48
|
+
// Helper Functions
|
|
49
|
+
// =============================================================================
|
|
50
|
+
/**
|
|
51
|
+
* Downloads contract dependencies to the output directory
|
|
52
|
+
*/
|
|
53
|
+
async function downloadDependencies(dependencies, outputDir) {
|
|
54
|
+
for (const depPath of dependencies) {
|
|
55
|
+
const relativePath = depPath.replace(/^contracts\//, "");
|
|
56
|
+
const depDestPath = path.join(outputDir, "contracts", relativePath);
|
|
57
|
+
const depDestDir = path.dirname(depDestPath);
|
|
58
|
+
if (!fs.existsSync(depDestDir)) {
|
|
59
|
+
fs.mkdirSync(depDestDir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
await (0, utils_1.downloadFileFromGitHub)(depPath, depDestPath);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Initializes git repository (optional, fails silently)
|
|
66
|
+
*/
|
|
67
|
+
async function initGitRepo(outputDir) {
|
|
68
|
+
try {
|
|
69
|
+
await (0, utils_1.runCommand)("git", ["init"], outputDir);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
// Git init is optional
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// =============================================================================
|
|
76
|
+
// Single Example Builder
|
|
77
|
+
// =============================================================================
|
|
78
|
+
/**
|
|
79
|
+
* Creates a single example project from the template
|
|
80
|
+
* @param exampleName - Name of the example to create
|
|
81
|
+
* @param outputDir - Target directory for the project
|
|
82
|
+
* @param tempRepoPath - Path to cloned template repository
|
|
83
|
+
*/
|
|
84
|
+
async function createSingleExample(exampleName, outputDir, tempRepoPath) {
|
|
85
|
+
const example = config_1.EXAMPLES[exampleName];
|
|
86
|
+
if (!example) {
|
|
87
|
+
throw new Error(`Unknown example: ${exampleName}`);
|
|
88
|
+
}
|
|
89
|
+
const templateDir = path.join(tempRepoPath, utils_1.TEMPLATE_DIR_NAME);
|
|
90
|
+
const contractName = (0, utils_1.getContractName)(example.contract);
|
|
91
|
+
if (!contractName) {
|
|
92
|
+
throw new Error("Could not extract contract name");
|
|
93
|
+
}
|
|
94
|
+
// Step 1: Copy template and clean up
|
|
95
|
+
(0, utils_1.copyDirectoryRecursive)(templateDir, outputDir);
|
|
96
|
+
(0, utils_1.cleanupTemplate)(outputDir);
|
|
97
|
+
// Step 2: Download example contract
|
|
98
|
+
await (0, utils_1.downloadFileFromGitHub)(example.contract, path.join(outputDir, "contracts", `${contractName}.sol`));
|
|
99
|
+
// Download contract dependencies if specified
|
|
100
|
+
if (example.dependencies) {
|
|
101
|
+
await downloadDependencies(example.dependencies, outputDir);
|
|
102
|
+
}
|
|
103
|
+
// Step 3: Download test file
|
|
104
|
+
await (0, utils_1.downloadFileFromGitHub)(example.test, path.join(outputDir, "test", path.basename(example.test)));
|
|
105
|
+
// Step 4: Update deploy script and package.json
|
|
106
|
+
fs.writeFileSync(path.join(outputDir, "deploy", "deploy.ts"), (0, utils_1.generateDeployScript)(contractName));
|
|
107
|
+
(0, utils_1.updateProjectPackageJson)(outputDir, `fhevm-example-${exampleName}`, example.description, example.npmDependencies);
|
|
108
|
+
// Initialize git repository
|
|
109
|
+
await initGitRepo(outputDir);
|
|
110
|
+
}
|
|
111
|
+
// =============================================================================
|
|
112
|
+
// Category Project Builder
|
|
113
|
+
// =============================================================================
|
|
114
|
+
/**
|
|
115
|
+
* Creates a category project with multiple examples
|
|
116
|
+
* @param categoryName - Name of the category to create
|
|
117
|
+
* @param outputDir - Target directory for the project
|
|
118
|
+
* @param tempRepoPath - Path to cloned template repository
|
|
119
|
+
*/
|
|
120
|
+
async function createCategoryProject(categoryName, outputDir, tempRepoPath) {
|
|
121
|
+
const category = config_1.CATEGORIES[categoryName];
|
|
122
|
+
if (!category) {
|
|
123
|
+
throw new Error(`Unknown category: ${categoryName}`);
|
|
124
|
+
}
|
|
125
|
+
const templateDir = path.join(tempRepoPath, utils_1.TEMPLATE_DIR_NAME);
|
|
126
|
+
// Step 1: Copy template and clean up
|
|
127
|
+
(0, utils_1.copyDirectoryRecursive)(templateDir, outputDir);
|
|
128
|
+
(0, utils_1.cleanupTemplate)(outputDir);
|
|
129
|
+
// Step 2: Download all contracts and tests
|
|
130
|
+
for (const item of category.contracts) {
|
|
131
|
+
const contractName = (0, utils_1.getContractName)(item.sol);
|
|
132
|
+
if (contractName) {
|
|
133
|
+
await (0, utils_1.downloadFileFromGitHub)(item.sol, path.join(outputDir, "contracts", `${contractName}.sol`));
|
|
134
|
+
}
|
|
135
|
+
if (item.test) {
|
|
136
|
+
await (0, utils_1.downloadFileFromGitHub)(item.test, path.join(outputDir, "test", path.basename(item.test)));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Collect dependencies from all examples in this category
|
|
140
|
+
const allDependencies = new Set();
|
|
141
|
+
const allNpmDependencies = {};
|
|
142
|
+
for (const [exampleName, exampleConfig] of Object.entries(config_1.EXAMPLES)) {
|
|
143
|
+
if (exampleConfig.category === category.name.replace(" Examples", "")) {
|
|
144
|
+
if (exampleConfig.dependencies) {
|
|
145
|
+
exampleConfig.dependencies.forEach((dep) => allDependencies.add(dep));
|
|
146
|
+
}
|
|
147
|
+
if (exampleConfig.npmDependencies) {
|
|
148
|
+
Object.assign(allNpmDependencies, exampleConfig.npmDependencies);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Download all collected dependencies
|
|
153
|
+
if (allDependencies.size > 0) {
|
|
154
|
+
await downloadDependencies(Array.from(allDependencies), outputDir);
|
|
155
|
+
}
|
|
156
|
+
// Step 3: Update package.json
|
|
157
|
+
(0, utils_1.updateProjectPackageJson)(outputDir, `fhevm-examples-${categoryName}`, undefined, allNpmDependencies);
|
|
158
|
+
// Initialize git repository
|
|
159
|
+
await initGitRepo(outputDir);
|
|
160
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ⚠️ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY ⚠️
|
|
3
3
|
*
|
|
4
|
-
* This file is auto-generated by
|
|
5
|
-
* Run 'npm run
|
|
4
|
+
* This file is auto-generated by cli/generate-config.ts
|
|
5
|
+
* Run 'npm run generate:config' to regenerate
|
|
6
6
|
*/
|
|
7
7
|
export interface ExampleConfig {
|
|
8
8
|
/** Path to the Solidity contract file */
|
|
@@ -17,6 +17,8 @@ export interface ExampleConfig {
|
|
|
17
17
|
description: string;
|
|
18
18
|
/** Category for grouping */
|
|
19
19
|
category: string;
|
|
20
|
+
/** Output path for generated documentation */
|
|
21
|
+
docsOutput: string;
|
|
20
22
|
/** Title for documentation */
|
|
21
23
|
title: string;
|
|
22
24
|
}
|
|
@@ -31,7 +33,26 @@ export interface CategoryConfig {
|
|
|
31
33
|
}
|
|
32
34
|
export declare const REPO_URL = "https://github.com/NecipAkgz/fhevm-example-factory";
|
|
33
35
|
export declare const REPO_BRANCH = "main";
|
|
34
|
-
export declare const TEMPLATE_SUBMODULE_PATH = "fhevm-hardhat-template";
|
|
35
36
|
export declare const EXAMPLES: Record<string, ExampleConfig>;
|
|
36
37
|
export declare const CATEGORIES: Record<string, CategoryConfig>;
|
|
38
|
+
/**
|
|
39
|
+
* Get list of example names
|
|
40
|
+
*/
|
|
41
|
+
export declare function getExampleNames(): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Get list of category names
|
|
44
|
+
*/
|
|
45
|
+
export declare function getCategoryNames(): string[];
|
|
46
|
+
/**
|
|
47
|
+
* Get example by name
|
|
48
|
+
*/
|
|
49
|
+
export declare function getExample(name: string): ExampleConfig | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Get category by name
|
|
52
|
+
*/
|
|
53
|
+
export declare function getCategory(name: string): CategoryConfig | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Generate consistent docs filename with fhe- prefix
|
|
56
|
+
*/
|
|
57
|
+
export declare function getDocsFileName(exampleName: string): string;
|
|
37
58
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../scripts/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAMD,eAAO,MAAM,QAAQ,uDAAuD,CAAC;AAC7E,eAAO,MAAM,WAAW,SAAS,CAAC;AAMlC,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CA6RlD,CAAC;AAMF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAoJrD,CAAC;AAMF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ⚠️ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY ⚠️
|
|
4
|
+
*
|
|
5
|
+
* This file is auto-generated by cli/generate-config.ts
|
|
6
|
+
* Run 'npm run generate:config' to regenerate
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CATEGORIES = exports.EXAMPLES = exports.REPO_BRANCH = exports.REPO_URL = void 0;
|
|
10
|
+
exports.getExampleNames = getExampleNames;
|
|
11
|
+
exports.getCategoryNames = getCategoryNames;
|
|
12
|
+
exports.getExample = getExample;
|
|
13
|
+
exports.getCategory = getCategory;
|
|
14
|
+
exports.getDocsFileName = getDocsFileName;
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// GitHub Repository Configuration
|
|
17
|
+
// =============================================================================
|
|
18
|
+
exports.REPO_URL = "https://github.com/NecipAkgz/fhevm-example-factory";
|
|
19
|
+
exports.REPO_BRANCH = "main";
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// Example Configurations
|
|
22
|
+
// =============================================================================
|
|
23
|
+
exports.EXAMPLES = {
|
|
24
|
+
"blind-auction": {
|
|
25
|
+
contract: "contracts/advanced/BlindAuction.sol",
|
|
26
|
+
test: "test/advanced/BlindAuction.ts",
|
|
27
|
+
description: "Blind Auction with encrypted bids - only the winning price is revealed",
|
|
28
|
+
category: "Advanced",
|
|
29
|
+
docsOutput: "docs/advanced/blind-auction.md",
|
|
30
|
+
title: "Blind Auction"
|
|
31
|
+
},
|
|
32
|
+
"encrypted-escrow": {
|
|
33
|
+
contract: "contracts/advanced/EncryptedEscrow.sol",
|
|
34
|
+
test: "test/advanced/EncryptedEscrow.ts",
|
|
35
|
+
description: "Encrypted Escrow service - amounts hidden until release!",
|
|
36
|
+
category: "Advanced",
|
|
37
|
+
docsOutput: "docs/advanced/encrypted-escrow.md",
|
|
38
|
+
title: "Encrypted Escrow"
|
|
39
|
+
},
|
|
40
|
+
"hidden-voting": {
|
|
41
|
+
contract: "contracts/advanced/HiddenVoting.sol",
|
|
42
|
+
test: "test/advanced/HiddenVoting.ts",
|
|
43
|
+
description: "Hidden Voting with encrypted ballots and homomorphic tallying",
|
|
44
|
+
category: "Advanced",
|
|
45
|
+
docsOutput: "docs/advanced/hidden-voting.md",
|
|
46
|
+
title: "Hidden Voting"
|
|
47
|
+
},
|
|
48
|
+
"private-kyc": {
|
|
49
|
+
contract: "contracts/advanced/PrivateKYC.sol",
|
|
50
|
+
test: "test/advanced/PrivateKYC.ts",
|
|
51
|
+
description: "Private KYC - verify identity without revealing personal data!",
|
|
52
|
+
category: "Advanced",
|
|
53
|
+
docsOutput: "docs/advanced/private-kyc.md",
|
|
54
|
+
title: "Private KYC"
|
|
55
|
+
},
|
|
56
|
+
"private-payroll": {
|
|
57
|
+
contract: "contracts/advanced/PrivatePayroll.sol",
|
|
58
|
+
test: "test/advanced/PrivatePayroll.ts",
|
|
59
|
+
description: "Private Payroll system - salaries stay encrypted, only employees see their own!",
|
|
60
|
+
category: "Advanced",
|
|
61
|
+
docsOutput: "docs/advanced/private-payroll.md",
|
|
62
|
+
title: "Private Payroll"
|
|
63
|
+
},
|
|
64
|
+
"public-decrypt-multiple-values": {
|
|
65
|
+
contract: "contracts/basic/decryption/PublicDecryptMultipleValues.sol",
|
|
66
|
+
test: "test/basic/decryption/PublicDecryptMultipleValues.ts",
|
|
67
|
+
description: "Implements a simple 8-sided Die Roll game demonstrating public, permissionless decryption",
|
|
68
|
+
category: "Basic - Decryption",
|
|
69
|
+
docsOutput: "docs/basic/decryption/public-decrypt-multiple-values.md",
|
|
70
|
+
title: "Public Decrypt Multiple Values"
|
|
71
|
+
},
|
|
72
|
+
"public-decrypt-single-value": {
|
|
73
|
+
contract: "contracts/basic/decryption/PublicDecryptSingleValue.sol",
|
|
74
|
+
test: "test/basic/decryption/PublicDecryptSingleValue.ts",
|
|
75
|
+
description: "Implements a simple Heads or Tails game demonstrating public, permissionless decryption",
|
|
76
|
+
category: "Basic - Decryption",
|
|
77
|
+
docsOutput: "docs/basic/decryption/public-decrypt-single-value.md",
|
|
78
|
+
title: "Public Decrypt Single Value"
|
|
79
|
+
},
|
|
80
|
+
"user-decrypt-multiple-values": {
|
|
81
|
+
contract: "contracts/basic/decryption/UserDecryptMultipleValues.sol",
|
|
82
|
+
test: "test/basic/decryption/UserDecryptMultipleValues.ts",
|
|
83
|
+
description: "Demonstrates user decryption of multiple encrypted values",
|
|
84
|
+
category: "Basic - Decryption",
|
|
85
|
+
docsOutput: "docs/basic/decryption/user-decrypt-multiple-values.md",
|
|
86
|
+
title: "User Decrypt Multiple Values"
|
|
87
|
+
},
|
|
88
|
+
"user-decrypt-single-value": {
|
|
89
|
+
contract: "contracts/basic/decryption/UserDecryptSingleValue.sol",
|
|
90
|
+
test: "test/basic/decryption/UserDecryptSingleValue.ts",
|
|
91
|
+
description: "Demonstrates the FHE decryption mechanism and highlights common pitfalls",
|
|
92
|
+
category: "Basic - Decryption",
|
|
93
|
+
docsOutput: "docs/basic/decryption/user-decrypt-single-value.md",
|
|
94
|
+
title: "User Decrypt Single Value"
|
|
95
|
+
},
|
|
96
|
+
"encrypt-multiple-values": {
|
|
97
|
+
contract: "contracts/basic/encryption/EncryptMultipleValues.sol",
|
|
98
|
+
test: "test/basic/encryption/EncryptMultipleValues.ts",
|
|
99
|
+
description: "Encrypting and handling multiple values in a single transaction efficiently.",
|
|
100
|
+
category: "Basic - Encryption",
|
|
101
|
+
docsOutput: "docs/basic/encryption/encrypt-multiple-values.md",
|
|
102
|
+
title: "Encrypt Multiple Values"
|
|
103
|
+
},
|
|
104
|
+
"encrypt-single-value": {
|
|
105
|
+
contract: "contracts/basic/encryption/EncryptSingleValue.sol",
|
|
106
|
+
test: "test/basic/encryption/EncryptSingleValue.ts",
|
|
107
|
+
description: "FHE encryption mechanism with single values, including common pitfalls and best practices for developers.",
|
|
108
|
+
category: "Basic - Encryption",
|
|
109
|
+
docsOutput: "docs/basic/encryption/encrypt-single-value.md",
|
|
110
|
+
title: "Encrypt Single Value"
|
|
111
|
+
},
|
|
112
|
+
"fhe-counter": {
|
|
113
|
+
contract: "contracts/basic/encryption/FHECounter.sol",
|
|
114
|
+
test: "test/basic/encryption/FHECounter.ts",
|
|
115
|
+
description: "Confidential counter implementation using FHEVM, compared with a standard counter to highlight encryption benefits.",
|
|
116
|
+
category: "Basic - Encryption",
|
|
117
|
+
docsOutput: "docs/basic/encryption/fhe-counter.md",
|
|
118
|
+
title: "FHE Counter"
|
|
119
|
+
},
|
|
120
|
+
"fhe-add": {
|
|
121
|
+
contract: "contracts/basic/fhe-operations/FHEAdd.sol",
|
|
122
|
+
test: "test/basic/fhe-operations/FHEAdd.ts",
|
|
123
|
+
description: "Simple example: adding two encrypted values (a + b)",
|
|
124
|
+
category: "Basic - FHE Operations",
|
|
125
|
+
docsOutput: "docs/basic/fhe-operations/fhe-add.md",
|
|
126
|
+
title: "FHE Add"
|
|
127
|
+
},
|
|
128
|
+
"fhe-arithmetic": {
|
|
129
|
+
contract: "contracts/basic/fhe-operations/FHEArithmetic.sol",
|
|
130
|
+
test: "test/basic/fhe-operations/FHEArithmetic.ts",
|
|
131
|
+
description: "Demonstrates all FHE arithmetic operations on encrypted integers",
|
|
132
|
+
category: "Basic - FHE Operations",
|
|
133
|
+
docsOutput: "docs/basic/fhe-operations/fhe-arithmetic.md",
|
|
134
|
+
title: "FHE Arithmetic"
|
|
135
|
+
},
|
|
136
|
+
"fhe-comparison": {
|
|
137
|
+
contract: "contracts/basic/fhe-operations/FHEComparison.sol",
|
|
138
|
+
test: "test/basic/fhe-operations/FHEComparison.ts",
|
|
139
|
+
description: "Demonstrates all FHE comparison operations on encrypted integers",
|
|
140
|
+
category: "Basic - FHE Operations",
|
|
141
|
+
docsOutput: "docs/basic/fhe-operations/fhe-comparison.md",
|
|
142
|
+
title: "FHE Comparison"
|
|
143
|
+
},
|
|
144
|
+
"fhe-if-then-else": {
|
|
145
|
+
contract: "contracts/basic/fhe-operations/FHEIfThenElse.sol",
|
|
146
|
+
test: "test/basic/fhe-operations/FHEIfThenElse.ts",
|
|
147
|
+
description: "Demonstrates conditional logic: max(a, b) using encrypted comparison",
|
|
148
|
+
category: "Basic - FHE Operations",
|
|
149
|
+
docsOutput: "docs/basic/fhe-operations/fhe-if-then-else.md",
|
|
150
|
+
title: "FHE If Then Else"
|
|
151
|
+
},
|
|
152
|
+
"fhe-access-control": {
|
|
153
|
+
contract: "contracts/concepts/FHEAccessControl.sol",
|
|
154
|
+
test: "test/concepts/FHEAccessControl.ts",
|
|
155
|
+
description: "Critical access control patterns in FHEVM: FHE.allow, FHE.allowThis, FHE.allowTransient. Includes common mistakes and correct implementations.",
|
|
156
|
+
category: "Concepts",
|
|
157
|
+
docsOutput: "docs/concepts/fhe-access-control.md",
|
|
158
|
+
title: "FHE Access Control"
|
|
159
|
+
},
|
|
160
|
+
"fhe-anti-patterns": {
|
|
161
|
+
contract: "contracts/concepts/FHEAntiPatterns.sol",
|
|
162
|
+
test: "test/concepts/FHEAntiPatterns.ts",
|
|
163
|
+
description: "Common FHE mistakes and their correct alternatives. Covers: branching, permissions, require/revert, re-encryption, loops, noise, and deprecated APIs.",
|
|
164
|
+
category: "Concepts",
|
|
165
|
+
docsOutput: "docs/concepts/fhe-anti-patterns.md",
|
|
166
|
+
title: "FHE Anti Patterns"
|
|
167
|
+
},
|
|
168
|
+
"fhe-handles": {
|
|
169
|
+
contract: "contracts/concepts/FHEHandles.sol",
|
|
170
|
+
test: "test/concepts/FHEHandles.ts",
|
|
171
|
+
description: "Understanding FHE handles: creation, computation, immutability, and symbolic execution in mock mode.",
|
|
172
|
+
category: "Concepts",
|
|
173
|
+
docsOutput: "docs/concepts/fhe-handles.md",
|
|
174
|
+
title: "FHE Handles"
|
|
175
|
+
},
|
|
176
|
+
"fhe-input-proof": {
|
|
177
|
+
contract: "contracts/concepts/FHEInputProof.sol",
|
|
178
|
+
test: "test/concepts/FHEInputProof.ts",
|
|
179
|
+
description: "Explains input proof validation in FHEVM: what proofs are, why they are needed, and how to use them correctly with single and batched inputs.",
|
|
180
|
+
category: "Concepts",
|
|
181
|
+
docsOutput: "docs/concepts/fhe-input-proof.md",
|
|
182
|
+
title: "FHE Input Proof"
|
|
183
|
+
},
|
|
184
|
+
"encrypted-lottery": {
|
|
185
|
+
contract: "contracts/gaming/EncryptedLottery.sol",
|
|
186
|
+
test: "test/gaming/EncryptedLottery.ts",
|
|
187
|
+
description: "Encrypted Lottery with private ticket numbers - fair and verifiable!",
|
|
188
|
+
category: "Gaming",
|
|
189
|
+
docsOutput: "docs/gaming/encrypted-lottery.md",
|
|
190
|
+
title: "Encrypted Lottery"
|
|
191
|
+
},
|
|
192
|
+
"encrypted-poker": {
|
|
193
|
+
contract: "contracts/gaming/EncryptedPoker.sol",
|
|
194
|
+
test: "test/gaming/EncryptedPoker.ts",
|
|
195
|
+
description: "Encrypted Poker - Texas Hold'em with hidden hole cards!",
|
|
196
|
+
category: "Gaming",
|
|
197
|
+
docsOutput: "docs/gaming/encrypted-poker.md",
|
|
198
|
+
title: "Encrypted Poker"
|
|
199
|
+
},
|
|
200
|
+
"rock-paper-scissors": {
|
|
201
|
+
contract: "contracts/gaming/RockPaperScissors.sol",
|
|
202
|
+
test: "test/gaming/RockPaperScissors.ts",
|
|
203
|
+
description: "Rock-Paper-Scissors game with encrypted moves - fair play guaranteed!",
|
|
204
|
+
category: "Gaming",
|
|
205
|
+
docsOutput: "docs/gaming/rock-paper-scissors.md",
|
|
206
|
+
title: "Rock Paper Scissors"
|
|
207
|
+
},
|
|
208
|
+
"erc7984": {
|
|
209
|
+
contract: "contracts/openzeppelin/ERC7984.sol",
|
|
210
|
+
test: "test/openzeppelin/ERC7984.ts",
|
|
211
|
+
npmDependencies: {
|
|
212
|
+
"@openzeppelin/contracts": "^5.4.0",
|
|
213
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
214
|
+
},
|
|
215
|
+
description: "Confidential token using OpenZeppelin's ERC7984 standard",
|
|
216
|
+
category: "Openzeppelin",
|
|
217
|
+
docsOutput: "docs/openzeppelin/erc7984.md",
|
|
218
|
+
title: "ERC7984"
|
|
219
|
+
},
|
|
220
|
+
"erc7984-erc20-wrapper": {
|
|
221
|
+
contract: "contracts/openzeppelin/ERC7984ERC20Wrapper.sol",
|
|
222
|
+
test: "test/openzeppelin/ERC7984ERC20Wrapper.ts",
|
|
223
|
+
npmDependencies: {
|
|
224
|
+
"@openzeppelin/contracts": "^5.4.0",
|
|
225
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
226
|
+
},
|
|
227
|
+
dependencies: [
|
|
228
|
+
"contracts/openzeppelin/mocks/ERC20Mock.sol"
|
|
229
|
+
],
|
|
230
|
+
description: "Wraps ERC20 tokens into confidential ERC7984 tokens",
|
|
231
|
+
category: "Openzeppelin",
|
|
232
|
+
docsOutput: "docs/openzeppelin/erc7984-erc20-wrapper.md",
|
|
233
|
+
title: "ERC7984 ERC20 Wrapper"
|
|
234
|
+
},
|
|
235
|
+
"swap-erc7984-to-erc20": {
|
|
236
|
+
contract: "contracts/openzeppelin/SwapERC7984ToERC20.sol",
|
|
237
|
+
test: "test/openzeppelin/SwapERC7984ToERC20.ts",
|
|
238
|
+
npmDependencies: {
|
|
239
|
+
"@openzeppelin/contracts": "^5.4.0",
|
|
240
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
241
|
+
},
|
|
242
|
+
dependencies: [
|
|
243
|
+
"contracts/openzeppelin/mocks/ERC20Mock.sol",
|
|
244
|
+
"contracts/openzeppelin/ERC7984.sol"
|
|
245
|
+
],
|
|
246
|
+
description: "Swap confidential ERC7984 tokens to regular ERC20 tokens",
|
|
247
|
+
category: "Openzeppelin",
|
|
248
|
+
docsOutput: "docs/openzeppelin/swap-erc7984-to-erc20.md",
|
|
249
|
+
title: "Swap ERC7984 To ERC20"
|
|
250
|
+
},
|
|
251
|
+
"swap-erc7984-to-erc7984": {
|
|
252
|
+
contract: "contracts/openzeppelin/SwapERC7984ToERC7984.sol",
|
|
253
|
+
test: "test/openzeppelin/SwapERC7984ToERC7984.ts",
|
|
254
|
+
npmDependencies: {
|
|
255
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
256
|
+
},
|
|
257
|
+
dependencies: [
|
|
258
|
+
"contracts/openzeppelin/ERC7984.sol"
|
|
259
|
+
],
|
|
260
|
+
description: "Fully confidential swap between two ERC7984 tokens",
|
|
261
|
+
category: "Openzeppelin",
|
|
262
|
+
docsOutput: "docs/openzeppelin/swap-erc7984-to-erc7984.md",
|
|
263
|
+
title: "Swap ERC7984 To ERC7984"
|
|
264
|
+
},
|
|
265
|
+
"vesting-wallet": {
|
|
266
|
+
contract: "contracts/openzeppelin/VestingWallet.sol",
|
|
267
|
+
test: "test/openzeppelin/VestingWallet.ts",
|
|
268
|
+
npmDependencies: {
|
|
269
|
+
"@openzeppelin/contracts": "^5.4.0",
|
|
270
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
271
|
+
},
|
|
272
|
+
dependencies: [
|
|
273
|
+
"contracts/openzeppelin/ERC7984.sol"
|
|
274
|
+
],
|
|
275
|
+
description: "Linear vesting wallet for ERC7984 tokens - amounts stay encrypted!",
|
|
276
|
+
category: "Openzeppelin",
|
|
277
|
+
docsOutput: "docs/openzeppelin/vesting-wallet.md",
|
|
278
|
+
title: "Vesting Wallet"
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
// =============================================================================
|
|
282
|
+
// Category Configurations
|
|
283
|
+
// =============================================================================
|
|
284
|
+
exports.CATEGORIES = {
|
|
285
|
+
advanced: {
|
|
286
|
+
name: "Advanced Examples",
|
|
287
|
+
contracts: [
|
|
288
|
+
{
|
|
289
|
+
sol: "contracts/advanced/BlindAuction.sol",
|
|
290
|
+
test: "test/advanced/BlindAuction.ts",
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
sol: "contracts/advanced/EncryptedEscrow.sol",
|
|
294
|
+
test: "test/advanced/EncryptedEscrow.ts",
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
sol: "contracts/advanced/HiddenVoting.sol",
|
|
298
|
+
test: "test/advanced/HiddenVoting.ts",
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
sol: "contracts/advanced/PrivateKYC.sol",
|
|
302
|
+
test: "test/advanced/PrivateKYC.ts",
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
sol: "contracts/advanced/PrivatePayroll.sol",
|
|
306
|
+
test: "test/advanced/PrivatePayroll.ts",
|
|
307
|
+
}
|
|
308
|
+
],
|
|
309
|
+
},
|
|
310
|
+
basicdecryption: {
|
|
311
|
+
name: "Basic - Decryption Examples",
|
|
312
|
+
contracts: [
|
|
313
|
+
{
|
|
314
|
+
sol: "contracts/basic/decryption/PublicDecryptMultipleValues.sol",
|
|
315
|
+
test: "test/basic/decryption/PublicDecryptMultipleValues.ts",
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
sol: "contracts/basic/decryption/PublicDecryptSingleValue.sol",
|
|
319
|
+
test: "test/basic/decryption/PublicDecryptSingleValue.ts",
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
sol: "contracts/basic/decryption/UserDecryptMultipleValues.sol",
|
|
323
|
+
test: "test/basic/decryption/UserDecryptMultipleValues.ts",
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
sol: "contracts/basic/decryption/UserDecryptSingleValue.sol",
|
|
327
|
+
test: "test/basic/decryption/UserDecryptSingleValue.ts",
|
|
328
|
+
}
|
|
329
|
+
],
|
|
330
|
+
},
|
|
331
|
+
basicencryption: {
|
|
332
|
+
name: "Basic - Encryption Examples",
|
|
333
|
+
contracts: [
|
|
334
|
+
{
|
|
335
|
+
sol: "contracts/basic/encryption/EncryptMultipleValues.sol",
|
|
336
|
+
test: "test/basic/encryption/EncryptMultipleValues.ts",
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
sol: "contracts/basic/encryption/EncryptSingleValue.sol",
|
|
340
|
+
test: "test/basic/encryption/EncryptSingleValue.ts",
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
sol: "contracts/basic/encryption/FHECounter.sol",
|
|
344
|
+
test: "test/basic/encryption/FHECounter.ts",
|
|
345
|
+
}
|
|
346
|
+
],
|
|
347
|
+
},
|
|
348
|
+
basicfheoperations: {
|
|
349
|
+
name: "Basic - FHE Operations Examples",
|
|
350
|
+
contracts: [
|
|
351
|
+
{
|
|
352
|
+
sol: "contracts/basic/fhe-operations/FHEAdd.sol",
|
|
353
|
+
test: "test/basic/fhe-operations/FHEAdd.ts",
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
sol: "contracts/basic/fhe-operations/FHEArithmetic.sol",
|
|
357
|
+
test: "test/basic/fhe-operations/FHEArithmetic.ts",
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
sol: "contracts/basic/fhe-operations/FHEComparison.sol",
|
|
361
|
+
test: "test/basic/fhe-operations/FHEComparison.ts",
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
sol: "contracts/basic/fhe-operations/FHEIfThenElse.sol",
|
|
365
|
+
test: "test/basic/fhe-operations/FHEIfThenElse.ts",
|
|
366
|
+
}
|
|
367
|
+
],
|
|
368
|
+
},
|
|
369
|
+
concepts: {
|
|
370
|
+
name: "Concepts Examples",
|
|
371
|
+
contracts: [
|
|
372
|
+
{
|
|
373
|
+
sol: "contracts/concepts/FHEAccessControl.sol",
|
|
374
|
+
test: "test/concepts/FHEAccessControl.ts",
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
sol: "contracts/concepts/FHEAntiPatterns.sol",
|
|
378
|
+
test: "test/concepts/FHEAntiPatterns.ts",
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
sol: "contracts/concepts/FHEHandles.sol",
|
|
382
|
+
test: "test/concepts/FHEHandles.ts",
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
sol: "contracts/concepts/FHEInputProof.sol",
|
|
386
|
+
test: "test/concepts/FHEInputProof.ts",
|
|
387
|
+
}
|
|
388
|
+
],
|
|
389
|
+
},
|
|
390
|
+
gaming: {
|
|
391
|
+
name: "Gaming Examples",
|
|
392
|
+
contracts: [
|
|
393
|
+
{
|
|
394
|
+
sol: "contracts/gaming/EncryptedLottery.sol",
|
|
395
|
+
test: "test/gaming/EncryptedLottery.ts",
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
sol: "contracts/gaming/EncryptedPoker.sol",
|
|
399
|
+
test: "test/gaming/EncryptedPoker.ts",
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
sol: "contracts/gaming/RockPaperScissors.sol",
|
|
403
|
+
test: "test/gaming/RockPaperScissors.ts",
|
|
404
|
+
}
|
|
405
|
+
],
|
|
406
|
+
},
|
|
407
|
+
openzeppelin: {
|
|
408
|
+
name: "Openzeppelin Examples",
|
|
409
|
+
contracts: [
|
|
410
|
+
{
|
|
411
|
+
sol: "contracts/openzeppelin/ERC7984.sol",
|
|
412
|
+
test: "test/openzeppelin/ERC7984.ts",
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
sol: "contracts/openzeppelin/ERC7984ERC20Wrapper.sol",
|
|
416
|
+
test: "test/openzeppelin/ERC7984ERC20Wrapper.ts",
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
sol: "contracts/openzeppelin/SwapERC7984ToERC20.sol",
|
|
420
|
+
test: "test/openzeppelin/SwapERC7984ToERC20.ts",
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
sol: "contracts/openzeppelin/SwapERC7984ToERC7984.sol",
|
|
424
|
+
test: "test/openzeppelin/SwapERC7984ToERC7984.ts",
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
sol: "contracts/openzeppelin/VestingWallet.sol",
|
|
428
|
+
test: "test/openzeppelin/VestingWallet.ts",
|
|
429
|
+
}
|
|
430
|
+
],
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
// =============================================================================
|
|
434
|
+
// Helper Functions
|
|
435
|
+
// =============================================================================
|
|
436
|
+
/**
|
|
437
|
+
* Get list of example names
|
|
438
|
+
*/
|
|
439
|
+
function getExampleNames() {
|
|
440
|
+
return Object.keys(exports.EXAMPLES);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Get list of category names
|
|
444
|
+
*/
|
|
445
|
+
function getCategoryNames() {
|
|
446
|
+
return Object.keys(exports.CATEGORIES);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Get example by name
|
|
450
|
+
*/
|
|
451
|
+
function getExample(name) {
|
|
452
|
+
return exports.EXAMPLES[name];
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Get category by name
|
|
456
|
+
*/
|
|
457
|
+
function getCategory(name) {
|
|
458
|
+
return exports.CATEGORIES[name];
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Generate consistent docs filename with fhe- prefix
|
|
462
|
+
*/
|
|
463
|
+
function getDocsFileName(exampleName) {
|
|
464
|
+
return exampleName.startsWith("fhe-") ? exampleName : `fhe-${exampleName}`;
|
|
465
|
+
}
|