create-fhevm-example 1.2.3 → 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 -13
- 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 -398
- 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
package/README.md
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
# create-fhevm-example
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Create FHEVM example projects with a single command</strong>
|
|
5
|
+
</p>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://docs.zama.org/protocol"><img src="https://img.shields.io/badge/docs-fhevm-blue" alt="FHEVM Docs"></a>
|
|
9
|
+
<a href="https://github.com/NecipAkgz/fhevm-example-factory/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-BSD--3--Clause--Clear-green" alt="License"></a>
|
|
10
|
+
<a href="#"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="Node"></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## 🚀 Quick Start
|
|
17
|
+
|
|
18
|
+
Launch the interactive CLI to create your project:
|
|
6
19
|
|
|
7
20
|
```bash
|
|
8
21
|
npx create-fhevm-example
|
|
@@ -10,9 +23,29 @@ npx create-fhevm-example
|
|
|
10
23
|
|
|
11
24
|

|
|
12
25
|
|
|
13
|
-
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 🔧 Add to Existing Hardhat Project
|
|
14
29
|
|
|
15
|
-
|
|
30
|
+
Already have a Hardhat project? Inject FHEVM capabilities without starting from scratch:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx create-fhevm-example --add
|
|
34
|
+
npx create-fhevm-example --add --target ./my-existing-project
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This will:
|
|
38
|
+
- ✅ Detect your Hardhat project
|
|
39
|
+
- ✅ Add FHEVM dependencies to `package.json`
|
|
40
|
+
- ✅ Update `hardhat.config.ts` with FHEVM plugin
|
|
41
|
+
- ✅ Add an example contract and test of your choice
|
|
42
|
+
- ✅ Handle file conflicts intelligently (skip/overwrite/rename)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## ⚡ Quick Commands
|
|
47
|
+
|
|
48
|
+
Skip the prompts and create projects directly:
|
|
16
49
|
|
|
17
50
|
```bash
|
|
18
51
|
# Create single example
|
|
@@ -25,183 +58,76 @@ npx create-fhevm-example --category basic
|
|
|
25
58
|
npx create-fhevm-example --add
|
|
26
59
|
npx create-fhevm-example --add --target ./my-existing-project
|
|
27
60
|
|
|
28
|
-
# With
|
|
29
|
-
npx create-fhevm-example --example fhe-counter --output ./my-project --install
|
|
61
|
+
# With auto-install and testing
|
|
62
|
+
npx create-fhevm-example --example fhe-counter --output ./my-project --install --test
|
|
30
63
|
```
|
|
31
64
|
|
|
32
|
-
|
|
65
|
+
---
|
|
33
66
|
|
|
34
|
-
|
|
35
|
-
|--------|-------------|
|
|
36
|
-
| `--example <name>` | Create a single example project |
|
|
37
|
-
| `--category <name>` | Create a category project |
|
|
38
|
-
| `--add` | Add FHEVM to existing Hardhat project |
|
|
39
|
-
| `--target <dir>` | Target directory for --add mode (default: current dir) |
|
|
40
|
-
| `--output <dir>` | Output directory |
|
|
41
|
-
| `--install` | Auto-install dependencies |
|
|
42
|
-
| `--test` | Auto-run tests |
|
|
43
|
-
| `--help` | Show help |
|
|
67
|
+
## 📋 CLI Options
|
|
44
68
|
|
|
45
|
-
|
|
69
|
+
`--example <name>` - Create a single example project
|
|
70
|
+
`--category <name>` - Create a category project
|
|
71
|
+
`--add` - Add FHEVM to existing Hardhat project
|
|
72
|
+
`--target <dir>` - Target directory for --add mode (default: current dir)
|
|
73
|
+
`--output <dir>` - Output directory
|
|
74
|
+
`--install` - Auto-install dependencies
|
|
75
|
+
`--test` - Auto-run tests
|
|
76
|
+
`--help` - Show help
|
|
46
77
|
|
|
47
|
-
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 📦 Available Examples
|
|
48
81
|
|
|
49
|
-
**
|
|
82
|
+
**Basic Encryption** (3): `fhe-counter`, `encrypt-single-value`, `encrypt-multiple-values`
|
|
50
83
|
|
|
51
|
-
**
|
|
84
|
+
**Decryption** (4): `user-decrypt-single-value`, `user-decrypt-multiple-values`, `public-decrypt-single-value`, `public-decrypt-multiple-values`
|
|
52
85
|
|
|
53
|
-
**
|
|
86
|
+
**FHE Operations** (4): `fhe-add`, `fhe-if-then-else`, `fhe-arithmetic`, `fhe-comparison`
|
|
54
87
|
|
|
55
|
-
**
|
|
88
|
+
**Concepts** (4): `fhe-access-control`, `fhe-input-proof`, `fhe-handles`, `fhe-anti-patterns`
|
|
56
89
|
|
|
57
|
-
**
|
|
90
|
+
**Gaming** (3): `rock-paper-scissors`, `encrypted-lottery`, `encrypted-poker`
|
|
58
91
|
|
|
59
|
-
|
|
92
|
+
**OpenZeppelin** (5): `erc7984`, `erc7984-erc20-wrapper`, `swap-erc7984-to-erc20`, `swap-erc7984-to-erc7984`, `vesting-wallet`
|
|
60
93
|
|
|
61
|
-
|
|
62
|
-
|----------|-------------|
|
|
63
|
-
| `basic` | Basic encryption and counter examples (1 contract) |
|
|
64
|
-
| `basicencryption` | Single and multiple value encryption (2 contracts) |
|
|
65
|
-
| `basicdecryption` | Public and user decryption examples (4 contracts) |
|
|
66
|
-
| `basicfheoperations` | FHE arithmetic and comparison (4 contracts) |
|
|
67
|
-
| `concepts` | Access control, proofs, handles, anti-patterns (4 contracts) |
|
|
68
|
-
| `gaming` | Rock-paper-scissors, lottery, poker (3 contracts) |
|
|
69
|
-
| `openzeppelin` | ERC7984, wrappers, swaps, vesting (5 contracts) |
|
|
70
|
-
| `advanced` | Blind auction, voting, payroll, escrow, KYC (5 contracts) |
|
|
94
|
+
**Advanced** (5): `blind-auction`, `hidden-voting`, `private-payroll`, `encrypted-escrow`, `private-kyc`
|
|
71
95
|
|
|
72
|
-
|
|
96
|
+
---
|
|
73
97
|
|
|
74
|
-
|
|
98
|
+
## ✅ What Gets Created
|
|
99
|
+
|
|
100
|
+
### New Projects (`--example` / `--category`)
|
|
75
101
|
|
|
76
102
|
- ✅ Hardhat configuration for FHEVM
|
|
77
|
-
- ✅ Smart contracts and
|
|
103
|
+
- ✅ Smart contracts and comprehensive tests
|
|
78
104
|
- ✅ Deployment scripts
|
|
79
105
|
- ✅ All dependencies configured
|
|
80
106
|
|
|
81
|
-
### Existing Projects (
|
|
107
|
+
### Existing Projects (`--add`)
|
|
82
108
|
|
|
83
109
|
- ✅ FHEVM dependencies added to `package.json`
|
|
84
110
|
- ✅ FHEVM plugin imported in `hardhat.config.ts`
|
|
85
111
|
- ✅ Example contract and test of your choice
|
|
86
|
-
- ✅ Intelligent
|
|
112
|
+
- ✅ Intelligent conflict handling (skip/overwrite/rename)
|
|
113
|
+
|
|
114
|
+
---
|
|
87
115
|
|
|
88
|
-
## Requirements
|
|
116
|
+
## 💻 Requirements
|
|
89
117
|
|
|
90
118
|
- Node.js >= 20
|
|
91
119
|
- Git
|
|
92
120
|
|
|
93
121
|
---
|
|
94
122
|
|
|
95
|
-
##
|
|
96
|
-
|
|
97
|
-
>This section is for contributors and maintainers of the package.
|
|
98
|
-
|
|
99
|
-
### File Structure
|
|
100
|
-
|
|
101
|
-
The package follows a modular structure similar to the main project's `scripts/` directory:
|
|
123
|
+
## 🔗 Learn More
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
├── builders.ts # createSingleExample, createCategoryProject (~250 lines)
|
|
107
|
-
├── ui.ts # Interactive prompts + install/test commands (~180 lines)
|
|
108
|
-
├── utils.ts # Utilities + constants + validation + logging (~350 lines)
|
|
109
|
-
├── config.ts # Auto-generated examples & categories (~440 lines)
|
|
110
|
-
└── add-mode.ts # Add FHEVM to existing projects (~370 lines)
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**Key Components:**
|
|
114
|
-
- `index.ts` - Main CLI entry point, handles interactive and direct modes
|
|
115
|
-
- `builders.ts` - Project creation logic (single example, category project)
|
|
116
|
-
- `ui.ts` - User interface (prompts + commands, replaces old prompts.ts + commands.ts)
|
|
117
|
-
- `utils.ts` - File operations, constants, validation, logging utilities
|
|
118
|
-
- `config.ts` - Auto-generated configuration from monorepo contracts
|
|
119
|
-
- `add-mode.ts` - Add FHEVM to existing Hardhat projects
|
|
120
|
-
|
|
121
|
-
**Design Principles:**
|
|
122
|
-
- **Modular**: Each file has a single responsibility
|
|
123
|
-
- **Aligned**: Mirrors main project's `scripts/` structure
|
|
124
|
-
- **Maintainable**: Easy to understand and update
|
|
125
|
-
- **Type-safe**: Full TypeScript coverage
|
|
126
|
-
- **Consistent**: Standardized logging, error handling, validation
|
|
127
|
-
|
|
128
|
-
### Configuration
|
|
129
|
-
|
|
130
|
-
The CLI uses a configuration file that defines all available examples and categories. This file is **auto-generated** by scanning the monorepo's contracts directory.
|
|
131
|
-
|
|
132
|
-
**Generated File**: `src/config.ts` (do not edit manually)
|
|
133
|
-
|
|
134
|
-
To customize the repository URL or branch:
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
// In src/config.ts
|
|
138
|
-
export const REPO_URL = "https://github.com/YourUsername/your-repo";
|
|
139
|
-
export const REPO_BRANCH = "main";
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Adding New Examples
|
|
143
|
-
|
|
144
|
-
To add a new example to the CLI:
|
|
145
|
-
|
|
146
|
-
1. **Create contract with `@notice` tag** in the main repository:
|
|
147
|
-
```solidity
|
|
148
|
-
/**
|
|
149
|
-
* @notice Your example description - auto-discovered!
|
|
150
|
-
*/
|
|
151
|
-
contract YourExample { }
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
2. **Update package config** (from monorepo):
|
|
155
|
-
```bash
|
|
156
|
-
cd packages/create-fhevm-example
|
|
157
|
-
npm run update:config # Scans ../../contracts, generates src/config.ts
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
3. **Publish**:
|
|
161
|
-
```bash
|
|
162
|
-
npm version patch # Increments version
|
|
163
|
-
npm publish # Auto-runs: update:config → build → publish
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
The `prepublishOnly` hook automatically:
|
|
167
|
-
- Updates config by scanning monorepo contracts (if available)
|
|
168
|
-
- Builds TypeScript to `dist/`
|
|
169
|
-
- Publishes to NPM
|
|
170
|
-
|
|
171
|
-
### Local Development
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
# Clone and setup
|
|
175
|
-
git clone https://github.com/NecipAkgz/fhevm-example-factory.git
|
|
176
|
-
cd fhevm-example-factory/packages/create-fhevm-example
|
|
177
|
-
npm install
|
|
178
|
-
|
|
179
|
-
# Build
|
|
180
|
-
npm run build
|
|
181
|
-
|
|
182
|
-
# Test locally
|
|
183
|
-
npm link
|
|
184
|
-
create-fhevm-example --help
|
|
185
|
-
|
|
186
|
-
# Unlink when done
|
|
187
|
-
npm unlink -g create-fhevm-example
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Scripts
|
|
191
|
-
|
|
192
|
-
- `npm run build` - Compile TypeScript to `dist/`
|
|
193
|
-
- `npm run dev` - Watch mode for development
|
|
194
|
-
- `npm run update:config` - Regenerate config from monorepo contracts
|
|
195
|
-
- `npm run prepublishOnly` - Auto-runs before publish (update:config + build)
|
|
125
|
+
- 📖 [FHEVM Documentation](https://docs.zama.org/protocol)
|
|
126
|
+
- 💻 [Source Repository](https://github.com/NecipAkgz/fhevm-example-factory)
|
|
127
|
+
- 🌐 [Zama](https://www.zama.ai/)
|
|
196
128
|
|
|
197
129
|
---
|
|
198
130
|
|
|
199
|
-
##
|
|
200
|
-
|
|
201
|
-
- [FHEVM Documentation](https://docs.zama.org/protocol)
|
|
202
|
-
- [Example Repository](https://github.com/NecipAkgz/fhevm-example-factory)
|
|
203
|
-
- [Zama](https://www.zama.ai/)
|
|
204
|
-
|
|
205
|
-
## License
|
|
131
|
+
## 📄 License
|
|
206
132
|
|
|
207
133
|
BSD-3-Clause-Clear
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-mode.d.ts","sourceRoot":"","sources":["../../scripts/add-mode.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkRH;;GAEG;AACH,wBAAsB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8ElE"}
|
|
@@ -1,19 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Add Mode - Add FHEVM to existing Hardhat projects
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.runAddMode = runAddMode;
|
|
43
|
+
const p = __importStar(require("@clack/prompts"));
|
|
44
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const config_1 = require("./config");
|
|
48
|
+
const utils_1 = require("./utils");
|
|
7
49
|
// =============================================================================
|
|
8
50
|
// PROJECT DETECTION
|
|
9
51
|
// =============================================================================
|
|
10
52
|
/**
|
|
11
53
|
* Detects if the target directory is a valid Hardhat project
|
|
12
54
|
*/
|
|
13
|
-
|
|
55
|
+
function detectHardhatProject(targetDir) {
|
|
14
56
|
const packageJsonPath = path.join(targetDir, "package.json");
|
|
15
57
|
const hardhatConfigTs = path.join(targetDir, "hardhat.config.ts");
|
|
16
|
-
const hardhatConfigJs = path.join(targetDir, "hardhat.config
|
|
58
|
+
const hardhatConfigJs = path.join(targetDir, "hardhat.config");
|
|
17
59
|
if (!fs.existsSync(packageJsonPath)) {
|
|
18
60
|
return false;
|
|
19
61
|
}
|
|
@@ -33,20 +75,16 @@ export function detectHardhatProject(targetDir) {
|
|
|
33
75
|
/**
|
|
34
76
|
* Updates package.json with FHEVM dependencies
|
|
35
77
|
*/
|
|
36
|
-
|
|
78
|
+
function updatePackageJson(targetDir) {
|
|
37
79
|
const packageJsonPath = path.join(targetDir, "package.json");
|
|
38
80
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
39
|
-
// Add dependencies
|
|
40
81
|
packageJson.dependencies = {
|
|
41
82
|
...packageJson.dependencies,
|
|
42
|
-
|
|
43
|
-
"@fhevm/solidity": "^0.9.1",
|
|
83
|
+
...utils_1.FHEVM_DEPENDENCIES.dependencies,
|
|
44
84
|
};
|
|
45
|
-
// Add devDependencies
|
|
46
85
|
packageJson.devDependencies = {
|
|
47
86
|
...packageJson.devDependencies,
|
|
48
|
-
|
|
49
|
-
"@zama-fhe/relayer-sdk": "^0.3.0-5",
|
|
87
|
+
...utils_1.FHEVM_DEPENDENCIES.devDependencies,
|
|
50
88
|
};
|
|
51
89
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
|
|
52
90
|
}
|
|
@@ -56,9 +94,9 @@ export function updatePackageJson(targetDir) {
|
|
|
56
94
|
/**
|
|
57
95
|
* Updates hardhat.config.ts/js with FHEVM plugin import
|
|
58
96
|
*/
|
|
59
|
-
|
|
97
|
+
function updateHardhatConfig(targetDir) {
|
|
60
98
|
const configPathTs = path.join(targetDir, "hardhat.config.ts");
|
|
61
|
-
const configPathJs = path.join(targetDir, "hardhat.config
|
|
99
|
+
const configPathJs = path.join(targetDir, "hardhat.config");
|
|
62
100
|
const actualPath = fs.existsSync(configPathTs)
|
|
63
101
|
? configPathTs
|
|
64
102
|
: fs.existsSync(configPathJs)
|
|
@@ -68,13 +106,10 @@ export function updateHardhatConfig(targetDir) {
|
|
|
68
106
|
throw new Error("hardhat.config.ts or hardhat.config.js not found");
|
|
69
107
|
}
|
|
70
108
|
let content = fs.readFileSync(actualPath, "utf-8");
|
|
71
|
-
// Check if already has FHEVM plugin
|
|
72
109
|
if (content.includes("@fhevm/hardhat-plugin")) {
|
|
73
|
-
return;
|
|
110
|
+
return;
|
|
74
111
|
}
|
|
75
|
-
// Add import at the top (after other imports)
|
|
76
112
|
const importStatement = 'import "@fhevm/hardhat-plugin";\n';
|
|
77
|
-
// Find the last import statement
|
|
78
113
|
const lines = content.split("\n");
|
|
79
114
|
let lastImportIndex = -1;
|
|
80
115
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -87,7 +122,6 @@ export function updateHardhatConfig(targetDir) {
|
|
|
87
122
|
lines.splice(lastImportIndex + 1, 0, importStatement);
|
|
88
123
|
}
|
|
89
124
|
else {
|
|
90
|
-
// No imports found, add at the beginning
|
|
91
125
|
lines.unshift(importStatement);
|
|
92
126
|
}
|
|
93
127
|
content = lines.join("\n");
|
|
@@ -99,12 +133,12 @@ export function updateHardhatConfig(targetDir) {
|
|
|
99
133
|
/**
|
|
100
134
|
* Adds example contract and test files to the project
|
|
101
135
|
*/
|
|
102
|
-
|
|
103
|
-
const example = EXAMPLES[exampleName];
|
|
136
|
+
async function addExampleFiles(exampleName, targetDir) {
|
|
137
|
+
const example = config_1.EXAMPLES[exampleName];
|
|
104
138
|
if (!example) {
|
|
105
139
|
throw new Error(`Unknown example: ${exampleName}`);
|
|
106
140
|
}
|
|
107
|
-
const contractName = getContractName(example.contract);
|
|
141
|
+
const contractName = (0, utils_1.getContractName)(example.contract);
|
|
108
142
|
if (!contractName) {
|
|
109
143
|
throw new Error("Could not extract contract name");
|
|
110
144
|
}
|
|
@@ -130,21 +164,20 @@ export async function addExampleFiles(exampleName, targetDir) {
|
|
|
130
164
|
}
|
|
131
165
|
else if (action === "rename") {
|
|
132
166
|
contractDest = path.join(targetDir, "contracts", `${contractName}_fhevm.sol`);
|
|
133
|
-
await downloadFileFromGitHub(example.contract, contractDest);
|
|
167
|
+
await (0, utils_1.downloadFileFromGitHub)(example.contract, contractDest);
|
|
134
168
|
p.log.success(`Added: ${contractName}_fhevm.sol`);
|
|
135
169
|
}
|
|
136
170
|
else {
|
|
137
|
-
await downloadFileFromGitHub(example.contract, contractDest);
|
|
171
|
+
await (0, utils_1.downloadFileFromGitHub)(example.contract, contractDest);
|
|
138
172
|
p.log.success(`Overwritten: ${contractName}.sol`);
|
|
139
173
|
}
|
|
140
174
|
}
|
|
141
175
|
else {
|
|
142
|
-
// Ensure contracts directory exists
|
|
143
176
|
const contractsDir = path.join(targetDir, "contracts");
|
|
144
177
|
if (!fs.existsSync(contractsDir)) {
|
|
145
178
|
fs.mkdirSync(contractsDir, { recursive: true });
|
|
146
179
|
}
|
|
147
|
-
await downloadFileFromGitHub(example.contract, contractDest);
|
|
180
|
+
await (0, utils_1.downloadFileFromGitHub)(example.contract, contractDest);
|
|
148
181
|
p.log.success(`Added: ${contractName}.sol`);
|
|
149
182
|
}
|
|
150
183
|
// Handle test file
|
|
@@ -165,29 +198,27 @@ export async function addExampleFiles(exampleName, targetDir) {
|
|
|
165
198
|
p.log.info(`Skipped: ${testFileName}`);
|
|
166
199
|
}
|
|
167
200
|
else {
|
|
168
|
-
await downloadFileFromGitHub(example.test, testDest);
|
|
201
|
+
await (0, utils_1.downloadFileFromGitHub)(example.test, testDest);
|
|
169
202
|
p.log.success(`Overwritten: ${testFileName}`);
|
|
170
203
|
}
|
|
171
204
|
}
|
|
172
205
|
else {
|
|
173
|
-
// Ensure test directory exists
|
|
174
206
|
const testDir = path.join(targetDir, "test");
|
|
175
207
|
if (!fs.existsSync(testDir)) {
|
|
176
208
|
fs.mkdirSync(testDir, { recursive: true });
|
|
177
209
|
}
|
|
178
|
-
await downloadFileFromGitHub(example.test, testDest);
|
|
210
|
+
await (0, utils_1.downloadFileFromGitHub)(example.test, testDest);
|
|
179
211
|
p.log.success(`Added: ${testFileName}`);
|
|
180
212
|
}
|
|
181
213
|
// Handle contract dependencies
|
|
182
214
|
if (example.dependencies) {
|
|
183
215
|
p.log.message("");
|
|
184
|
-
p.log.message(
|
|
216
|
+
p.log.message(picocolors_1.default.bold("Downloading contract dependencies..."));
|
|
185
217
|
for (const depPath of example.dependencies) {
|
|
186
218
|
const relativePath = depPath.replace(/^contracts\//, "");
|
|
187
219
|
const depDestPath = path.join(targetDir, "contracts", relativePath);
|
|
188
220
|
const depDestDir = path.dirname(depDestPath);
|
|
189
221
|
const depName = path.basename(depPath);
|
|
190
|
-
// Create directory if needed
|
|
191
222
|
if (!fs.existsSync(depDestDir)) {
|
|
192
223
|
fs.mkdirSync(depDestDir, { recursive: true });
|
|
193
224
|
}
|
|
@@ -195,7 +226,7 @@ export async function addExampleFiles(exampleName, targetDir) {
|
|
|
195
226
|
p.log.info(`Skipped (exists): ${depName}`);
|
|
196
227
|
}
|
|
197
228
|
else {
|
|
198
|
-
await downloadFileFromGitHub(depPath, depDestPath);
|
|
229
|
+
await (0, utils_1.downloadFileFromGitHub)(depPath, depDestPath);
|
|
199
230
|
p.log.success(`Added: ${depName}`);
|
|
200
231
|
}
|
|
201
232
|
}
|
|
@@ -203,7 +234,7 @@ export async function addExampleFiles(exampleName, targetDir) {
|
|
|
203
234
|
// Handle npm dependencies
|
|
204
235
|
if (example.npmDependencies) {
|
|
205
236
|
p.log.message("");
|
|
206
|
-
p.log.message(
|
|
237
|
+
p.log.message(picocolors_1.default.bold("Adding npm dependencies to package.json..."));
|
|
207
238
|
const packageJsonPath = path.join(targetDir, "package.json");
|
|
208
239
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
209
240
|
if (!packageJson.dependencies) {
|
|
@@ -231,26 +262,23 @@ export async function addExampleFiles(exampleName, targetDir) {
|
|
|
231
262
|
/**
|
|
232
263
|
* Main function to add FHEVM capabilities to an existing Hardhat project
|
|
233
264
|
*/
|
|
234
|
-
|
|
265
|
+
async function runAddMode(targetDir) {
|
|
235
266
|
console.clear();
|
|
236
|
-
p.intro(
|
|
237
|
-
// Determine target directory
|
|
267
|
+
p.intro(picocolors_1.default.bgCyan(picocolors_1.default.black(" ⚡ FHEVM Example Factory - Add Mode ")));
|
|
238
268
|
const projectDir = targetDir || process.cwd();
|
|
239
269
|
const absoluteDir = path.resolve(projectDir);
|
|
240
|
-
// Step 1: Detect Hardhat project
|
|
241
270
|
const s = p.spinner();
|
|
242
271
|
s.start("Detecting Hardhat project...");
|
|
243
272
|
if (!detectHardhatProject(absoluteDir)) {
|
|
244
|
-
s.stop(
|
|
273
|
+
s.stop(picocolors_1.default.red("✗ Not a valid Hardhat project"));
|
|
245
274
|
p.log.error("This directory does not contain a valid Hardhat project.");
|
|
246
|
-
p.log.message(
|
|
275
|
+
p.log.message(picocolors_1.default.dim("Make sure package.json and hardhat.config.ts/js exist and hardhat is installed."));
|
|
247
276
|
process.exit(1);
|
|
248
277
|
}
|
|
249
|
-
s.stop(
|
|
250
|
-
// Step 2: Select example
|
|
278
|
+
s.stop(picocolors_1.default.green("✓ Valid Hardhat project detected"));
|
|
251
279
|
const exampleName = await p.select({
|
|
252
280
|
message: "Which FHEVM example would you like to add?",
|
|
253
|
-
options: Object.entries(EXAMPLES).map(([key, config]) => ({
|
|
281
|
+
options: Object.entries(config_1.EXAMPLES).map(([key, config]) => ({
|
|
254
282
|
value: key,
|
|
255
283
|
label: config.title,
|
|
256
284
|
hint: config.category,
|
|
@@ -261,29 +289,26 @@ export async function runAddMode(targetDir) {
|
|
|
261
289
|
process.exit(0);
|
|
262
290
|
}
|
|
263
291
|
p.log.message("");
|
|
264
|
-
// Step 3: Update package.json
|
|
265
292
|
s.start("Updating package.json with FHEVM dependencies...");
|
|
266
293
|
try {
|
|
267
294
|
updatePackageJson(absoluteDir);
|
|
268
|
-
s.stop(
|
|
295
|
+
s.stop(picocolors_1.default.green("✓ package.json updated"));
|
|
269
296
|
}
|
|
270
297
|
catch (error) {
|
|
271
|
-
s.stop(
|
|
298
|
+
s.stop(picocolors_1.default.red("✗ Failed to update package.json"));
|
|
272
299
|
throw error;
|
|
273
300
|
}
|
|
274
|
-
// Step 4: Update hardhat.config
|
|
275
301
|
s.start("Updating hardhat.config with FHEVM plugin...");
|
|
276
302
|
try {
|
|
277
303
|
updateHardhatConfig(absoluteDir);
|
|
278
|
-
s.stop(
|
|
304
|
+
s.stop(picocolors_1.default.green("✓ hardhat.config updated"));
|
|
279
305
|
}
|
|
280
306
|
catch (error) {
|
|
281
|
-
s.stop(
|
|
307
|
+
s.stop(picocolors_1.default.red("✗ Failed to update hardhat.config"));
|
|
282
308
|
throw error;
|
|
283
309
|
}
|
|
284
|
-
// Step 5: Add example files
|
|
285
310
|
p.log.message("");
|
|
286
|
-
p.log.message(
|
|
311
|
+
p.log.message(picocolors_1.default.bold("Adding example files..."));
|
|
287
312
|
try {
|
|
288
313
|
await addExampleFiles(exampleName, absoluteDir);
|
|
289
314
|
}
|
|
@@ -291,11 +316,9 @@ export async function runAddMode(targetDir) {
|
|
|
291
316
|
p.log.error("Failed to add example files");
|
|
292
317
|
throw error;
|
|
293
318
|
}
|
|
294
|
-
// Success!
|
|
295
319
|
p.log.message("");
|
|
296
|
-
p.log.success(
|
|
320
|
+
p.log.success(picocolors_1.default.green("✨ FHEVM capabilities added successfully!"));
|
|
297
321
|
p.log.message("");
|
|
298
|
-
p.note(`${
|
|
299
|
-
p.outro(
|
|
322
|
+
p.note(`${picocolors_1.default.dim("$")} npm install\n${picocolors_1.default.dim("$")} npm run compile\n${picocolors_1.default.dim("$")} npm run test`, "🚀 Next Steps");
|
|
323
|
+
p.outro(picocolors_1.default.green("✅ Setup complete. Happy encrypting!"));
|
|
300
324
|
}
|
|
301
|
-
//# sourceMappingURL=add-mode.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Builders
|
|
3
|
+
*
|
|
4
|
+
* Creates single example and category projects from templates.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Creates a single example project from the template
|
|
8
|
+
* @param exampleName - Name of the example to create
|
|
9
|
+
* @param outputDir - Target directory for the project
|
|
10
|
+
* @param tempRepoPath - Path to cloned template repository
|
|
11
|
+
*/
|
|
12
|
+
export declare function createSingleExample(exampleName: string, outputDir: string, tempRepoPath: string): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a category project with multiple examples
|
|
15
|
+
* @param categoryName - Name of the category to create
|
|
16
|
+
* @param outputDir - Target directory for the project
|
|
17
|
+
* @param tempRepoPath - Path to cloned template repository
|
|
18
|
+
*/
|
|
19
|
+
export declare function createCategoryProject(categoryName: string, outputDir: string, tempRepoPath: string): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=builders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../scripts/builders.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuDH;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAgDf;AAMD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Df"}
|