hardhat 2.9.8 → 2.10.1

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 (97) hide show
  1. package/internal/cli/cli.js +37 -7
  2. package/internal/cli/cli.js.map +1 -1
  3. package/internal/cli/hardhat-vscode-installation.d.ts +8 -0
  4. package/internal/cli/hardhat-vscode-installation.d.ts.map +1 -0
  5. package/internal/cli/hardhat-vscode-installation.js +41 -0
  6. package/internal/cli/hardhat-vscode-installation.js.map +1 -0
  7. package/internal/cli/project-creation.d.ts +0 -1
  8. package/internal/cli/project-creation.d.ts.map +1 -1
  9. package/internal/cli/project-creation.js +87 -179
  10. package/internal/cli/project-creation.js.map +1 -1
  11. package/internal/cli/prompt.d.ts +14 -0
  12. package/internal/cli/prompt.d.ts.map +1 -0
  13. package/internal/cli/prompt.js +120 -0
  14. package/internal/cli/prompt.js.map +1 -0
  15. package/internal/cli/types.d.ts +4 -0
  16. package/internal/cli/types.d.ts.map +1 -0
  17. package/internal/cli/types.js +3 -0
  18. package/internal/cli/types.js.map +1 -0
  19. package/internal/core/config/config-loading.js +1 -1
  20. package/internal/core/errors-list.js +4 -4
  21. package/internal/core/errors-list.js.map +1 -1
  22. package/internal/core/providers/construction.d.ts.map +1 -1
  23. package/internal/core/providers/construction.js +0 -4
  24. package/internal/core/providers/construction.js.map +1 -1
  25. package/internal/core/providers/gas-providers.d.ts +0 -15
  26. package/internal/core/providers/gas-providers.d.ts.map +1 -1
  27. package/internal/core/providers/gas-providers.js +1 -33
  28. package/internal/core/providers/gas-providers.js.map +1 -1
  29. package/internal/hardhat-network/provider/modules/logger.js +1 -1
  30. package/internal/hardhat-network/provider/modules/logger.js.map +1 -1
  31. package/internal/hardhat-network/provider/node.js +1 -1
  32. package/internal/hardhat-network/provider/node.js.map +1 -1
  33. package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +1 -1
  34. package/internal/hardhat-network/stack-traces/error-inferrer.js +5 -0
  35. package/internal/hardhat-network/stack-traces/error-inferrer.js.map +1 -1
  36. package/internal/hardhat-network/stack-traces/solidity-errors.js +1 -1
  37. package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
  38. package/internal/util/global-dir.d.ts +5 -0
  39. package/internal/util/global-dir.d.ts.map +1 -1
  40. package/internal/util/global-dir.js +17 -1
  41. package/internal/util/global-dir.js.map +1 -1
  42. package/internal/util/keys-derivation.d.ts.map +1 -1
  43. package/internal/util/keys-derivation.js +3 -1
  44. package/internal/util/keys-derivation.js.map +1 -1
  45. package/package.json +19 -9
  46. package/recommended-gitignore.txt +2 -0
  47. package/sample-projects/{basic → javascript}/LICENSE.md +1 -1
  48. package/sample-projects/javascript/README.md +13 -0
  49. package/sample-projects/javascript/contracts/Lock.sol +34 -0
  50. package/sample-projects/javascript/hardhat.config.js +6 -0
  51. package/sample-projects/javascript/scripts/deploy.js +29 -0
  52. package/sample-projects/javascript/test/Lock.js +126 -0
  53. package/sample-projects/typescript/LICENSE.md +11 -0
  54. package/sample-projects/typescript/README.md +13 -0
  55. package/sample-projects/typescript/contracts/Lock.sol +34 -0
  56. package/sample-projects/typescript/hardhat.config.ts +8 -0
  57. package/sample-projects/typescript/scripts/deploy.ts +23 -0
  58. package/sample-projects/typescript/test/Lock.ts +124 -0
  59. package/sample-projects/typescript/tsconfig.json +10 -0
  60. package/src/internal/cli/cli.ts +55 -7
  61. package/src/internal/cli/hardhat-vscode-installation.ts +43 -0
  62. package/src/internal/cli/project-creation.ts +124 -290
  63. package/src/internal/cli/prompt.ts +143 -0
  64. package/src/internal/cli/types.ts +3 -0
  65. package/src/internal/core/config/config-loading.ts +1 -1
  66. package/src/internal/core/errors-list.ts +4 -4
  67. package/src/internal/core/providers/construction.ts +0 -9
  68. package/src/internal/core/providers/gas-providers.ts +0 -39
  69. package/src/internal/hardhat-network/provider/modules/logger.ts +1 -1
  70. package/src/internal/hardhat-network/provider/node.ts +1 -1
  71. package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +6 -0
  72. package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +1 -1
  73. package/src/internal/util/global-dir.ts +19 -0
  74. package/src/internal/util/keys-derivation.ts +3 -1
  75. package/sample-projects/advanced/.env.example +0 -3
  76. package/sample-projects/advanced/.eslintignore +0 -4
  77. package/sample-projects/advanced/.eslintrc.js +0 -22
  78. package/sample-projects/advanced/.prettierignore +0 -5
  79. package/sample-projects/advanced/.prettierrc +0 -1
  80. package/sample-projects/advanced/.solhint.json +0 -7
  81. package/sample-projects/advanced/.solhintignore +0 -1
  82. package/sample-projects/advanced/README.md +0 -42
  83. package/sample-projects/advanced/hardhat.config.js +0 -40
  84. package/sample-projects/advanced/npmignore +0 -3
  85. package/sample-projects/advanced/scripts/deploy.js +0 -30
  86. package/sample-projects/advanced-ts/.eslintrc.js +0 -24
  87. package/sample-projects/advanced-ts/README.md +0 -46
  88. package/sample-projects/advanced-ts/hardhat.config.ts +0 -43
  89. package/sample-projects/advanced-ts/npmignore +0 -3
  90. package/sample-projects/advanced-ts/scripts/deploy.ts +0 -30
  91. package/sample-projects/advanced-ts/test/index.ts +0 -19
  92. package/sample-projects/advanced-ts/tsconfig.json +0 -12
  93. package/sample-projects/basic/README.md +0 -15
  94. package/sample-projects/basic/contracts/Greeter.sol +0 -22
  95. package/sample-projects/basic/hardhat.config.js +0 -21
  96. package/sample-projects/basic/scripts/sample-script.js +0 -32
  97. package/sample-projects/basic/test/sample-test.js +0 -19
@@ -4,7 +4,6 @@ import os from "os";
4
4
  import path from "path";
5
5
 
6
6
  import { HARDHAT_NAME } from "../constants";
7
- import { DEFAULT_SOLC_VERSION } from "../core/config/default-config";
8
7
  import { HardhatError } from "../core/errors";
9
8
  import { ERRORS } from "../core/errors-list";
10
9
  import { getRecommendedGitIgnore } from "../core/project-structure";
@@ -14,93 +13,59 @@ import {
14
13
  } from "../util/global-dir";
15
14
  import { fromEntries } from "../util/lang";
16
15
  import { getPackageJson, getPackageRoot } from "../util/packageInfo";
17
-
16
+ import { pluralize } from "../util/strings";
17
+ import {
18
+ confirmRecommendedDepsInstallation,
19
+ confirmTelemetryConsent,
20
+ confirmProjectCreation,
21
+ } from "./prompt";
18
22
  import { emoji } from "./emoji";
23
+ import { Dependencies } from "./types";
19
24
 
20
25
  enum Action {
21
- CREATE_BASIC_SAMPLE_PROJECT_ACTION = "Create a basic sample project",
22
- CREATE_ADVANCED_SAMPLE_PROJECT_ACTION = "Create an advanced sample project",
23
- CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_ACTION = "Create an advanced sample project that uses TypeScript",
26
+ CREATE_JAVASCRIPT_PROJECT_ACTION = "Create a JavaScript project",
27
+ CREATE_TYPESCRIPT_PROJECT_ACTION = "Create a TypeScript project",
24
28
  CREATE_EMPTY_HARDHAT_CONFIG_ACTION = "Create an empty hardhat.config.js",
25
29
  QUIT_ACTION = "Quit",
26
30
  }
27
31
 
28
32
  type SampleProjectTypeCreationAction =
29
- | Action.CREATE_BASIC_SAMPLE_PROJECT_ACTION
30
- | Action.CREATE_ADVANCED_SAMPLE_PROJECT_ACTION
31
- | Action.CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_ACTION;
32
-
33
- interface Dependencies {
34
- [name: string]: string;
35
- }
33
+ | Action.CREATE_JAVASCRIPT_PROJECT_ACTION
34
+ | Action.CREATE_TYPESCRIPT_PROJECT_ACTION;
36
35
 
37
36
  const HARDHAT_PACKAGE_NAME = "hardhat";
38
37
 
39
- const BASIC_SAMPLE_PROJECT_DEPENDENCIES: Dependencies = {
40
- "@nomiclabs/hardhat-waffle": "^2.0.0",
41
- "ethereum-waffle": "^3.0.0",
42
- chai: "^4.2.0",
43
- "@nomiclabs/hardhat-ethers": "^2.0.0",
44
- ethers: "^5.0.0",
38
+ const PROJECT_DEPENDENCIES: Dependencies = {
39
+ "@nomicfoundation/hardhat-toolbox": "^1.0.1",
45
40
  };
46
41
 
47
- const ADVANCED_SAMPLE_PROJECT_DEPENDENCIES: Dependencies = {
48
- ...BASIC_SAMPLE_PROJECT_DEPENDENCIES,
42
+ const PEER_DEPENDENCIES: Dependencies = {
43
+ hardhat: "^2.9.9",
44
+ "@nomicfoundation/hardhat-network-helpers": "^1.0.0",
45
+ "@nomicfoundation/hardhat-chai-matchers": "^1.0.0",
46
+ "@nomiclabs/hardhat-ethers": "^2.0.0",
49
47
  "@nomiclabs/hardhat-etherscan": "^3.0.0",
50
- dotenv: "^16.0.0",
51
- eslint: "^7.29.0",
52
- "eslint-config-prettier": "^8.3.0",
53
- "eslint-config-standard": "^16.0.3",
54
- "eslint-plugin-import": "^2.23.4",
55
- "eslint-plugin-node": "^11.1.0",
56
- "eslint-plugin-prettier": "^3.4.0",
57
- "eslint-plugin-promise": "^5.1.0",
58
- "hardhat-gas-reporter": "^1.0.4",
59
- prettier: "^2.3.2",
60
- "prettier-plugin-solidity": "^1.0.0-beta.13",
61
- solhint: "^3.3.6",
62
- "solidity-coverage": "^0.7.16",
48
+ chai: "^4.2.0",
49
+ ethers: "^5.4.7",
50
+ "hardhat-gas-reporter": "^1.0.8",
51
+ "solidity-coverage": "^0.7.21",
52
+ "@typechain/hardhat": "^6.1.2",
53
+ typechain: "^8.1.0",
54
+ "@typechain/ethers-v5": "^10.1.0",
55
+ "@ethersproject/abi": "^5.4.7",
56
+ "@ethersproject/providers": "^5.4.7",
63
57
  };
64
58
 
65
- const ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_DEPENDENCIES: Dependencies = {
66
- ...ADVANCED_SAMPLE_PROJECT_DEPENDENCIES,
67
- "@typechain/ethers-v5": "^7.0.1",
68
- "@typechain/hardhat": "^2.3.0",
69
- "@typescript-eslint/eslint-plugin": "^4.29.1",
70
- "@typescript-eslint/parser": "^4.29.1",
71
- "@types/chai": "^4.2.21",
72
- "@types/node": "^12.0.0",
73
- "@types/mocha": "^9.0.0",
74
- "ts-node": "^10.1.0",
75
- typechain: "^5.1.2", // a workaround. see https://github.com/nomiclabs/hardhat/issues/1672#issuecomment-894497156
76
- typescript: "^4.5.2",
77
- };
59
+ const TYPESCRIPT_DEPENDENCIES: Dependencies = {};
78
60
 
79
- const SAMPLE_PROJECT_DEPENDENCIES: {
80
- [K in SampleProjectTypeCreationAction]: Dependencies;
81
- } = {
82
- [Action.CREATE_BASIC_SAMPLE_PROJECT_ACTION]:
83
- BASIC_SAMPLE_PROJECT_DEPENDENCIES,
84
- [Action.CREATE_ADVANCED_SAMPLE_PROJECT_ACTION]:
85
- ADVANCED_SAMPLE_PROJECT_DEPENDENCIES,
86
- [Action.CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_ACTION]:
87
- ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_DEPENDENCIES,
61
+ const TYPESCRIPT_PEER_DEPENDENCIES: Dependencies = {
62
+ "@types/chai": "^4.2.0",
63
+ "@types/mocha": "^9.1.0",
64
+ "@types/node": ">=12.0.0",
65
+ "ts-node": ">=8.0.0",
66
+ typescript: ">=4.5.0",
88
67
  };
89
68
 
90
- const TELEMETRY_CONSENT_TIMEOUT = 10000;
91
-
92
- async function removeProjectDirIfPresent(projectRoot: string, dirName: string) {
93
- const dirPath = path.join(projectRoot, dirName);
94
- if (await fsExtra.pathExists(dirPath)) {
95
- await fsExtra.remove(dirPath);
96
- }
97
- }
98
-
99
- async function removeTempFilesIfPresent(projectRoot: string) {
100
- await removeProjectDirIfPresent(projectRoot, "cache");
101
- await removeProjectDirIfPresent(projectRoot, "artifacts");
102
- }
103
-
104
69
  // generated with the "colossal" font
105
70
  function printAsciiLogo() {
106
71
  console.log(
@@ -142,100 +107,47 @@ async function printWelcomeMessage() {
142
107
  );
143
108
  }
144
109
 
145
- async function checkForDuplicates(
146
- projectRoot: string,
147
- projectType: SampleProjectTypeCreationAction
148
- ): Promise<void> {
149
- const { intersection, union } = await import("lodash");
150
-
151
- const packageRoot = getPackageRoot();
152
-
153
- const srcPath = path.join(packageRoot, "sample-projects");
154
- const destFiles = fsExtra.readdirSync(projectRoot);
155
- let srcFiles: string[] = fsExtra.readdirSync(path.join(srcPath, "basic"));
156
-
157
- switch (projectType) {
158
- case Action.CREATE_ADVANCED_SAMPLE_PROJECT_ACTION:
159
- srcFiles = union(
160
- srcFiles,
161
- fsExtra.readdirSync(path.join(srcPath, "advanced"))
162
- );
163
- break;
164
- case Action.CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_ACTION:
165
- srcFiles = union(
166
- srcFiles,
167
- fsExtra.readdirSync(path.join(srcPath, "advanced")),
168
- fsExtra.readdirSync(path.join(srcPath, "advanced-ts"))
169
- );
170
- break;
171
- }
172
-
173
- const duplicates = intersection(srcFiles, destFiles);
174
-
175
- if (duplicates.length > 0) {
176
- throw new HardhatError(ERRORS.GENERAL.CONFLICTING_FILES, {
177
- dest: projectRoot,
178
- conflicts: duplicates.map((n) => ` ${n}`).join(os.EOL),
179
- });
180
- }
181
- }
182
-
183
110
  async function copySampleProject(
184
111
  projectRoot: string,
185
112
  projectType: SampleProjectTypeCreationAction
186
113
  ) {
187
114
  const packageRoot = getPackageRoot();
188
115
 
189
- // first copy the basic project, then, if an advanced project is what was
190
- // requested, overlay the advanced files on top of the basic ones. then, if
191
- // the advanced TypeScript project is what was requested, overlay those files
192
- // on top of the advanced ones.
193
-
194
- await checkForDuplicates(projectRoot, projectType);
116
+ const sampleProjectName =
117
+ projectType === Action.CREATE_JAVASCRIPT_PROJECT_ACTION
118
+ ? "javascript"
119
+ : "typescript";
195
120
 
196
121
  await fsExtra.ensureDir(projectRoot);
197
- await fsExtra.copy(
198
- path.join(packageRoot, "sample-projects", "basic"),
199
- projectRoot
200
- );
201
122
 
202
- if (
203
- projectType === Action.CREATE_ADVANCED_SAMPLE_PROJECT_ACTION ||
204
- projectType === Action.CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_ACTION
205
- ) {
206
- await fsExtra.copy(
207
- path.join(packageRoot, "sample-projects", "advanced"),
208
- projectRoot
209
- );
210
- await fsExtra.remove(path.join(projectRoot, "scripts", "sample-script.js"));
211
- await fsExtra.move(
212
- path.join(projectRoot, "npmignore"),
213
- path.join(projectRoot, ".npmignore"),
214
- { overwrite: true }
215
- );
216
- }
123
+ const sampleProjectPath = path.join(
124
+ packageRoot,
125
+ "sample-projects",
126
+ sampleProjectName
127
+ );
217
128
 
218
- if (projectType === Action.CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_ACTION) {
219
- await fsExtra.copy(
220
- path.join(packageRoot, "sample-projects", "advanced-ts"),
221
- projectRoot
222
- );
223
- for (const jsFile of [
224
- "hardhat.config.js",
225
- path.join("scripts", "deploy.js"),
226
- path.join("test", "sample-test.js"),
227
- ]) {
228
- await fsExtra.remove(jsFile);
229
- }
230
- await fsExtra.move(
231
- path.join(projectRoot, "npmignore"),
232
- path.join(projectRoot, ".npmignore"),
233
- { overwrite: true }
234
- );
129
+ const sampleProjectRootFiles = fsExtra.readdirSync(sampleProjectPath);
130
+ const existingFiles = sampleProjectRootFiles
131
+ .map((f) => path.join(projectRoot, f))
132
+ .filter((f) => fsExtra.pathExistsSync(f))
133
+ .map((f) => path.relative(process.cwd(), f));
134
+
135
+ if (existingFiles.length > 0) {
136
+ const errorMsg = `We couldn't initialize the sample project because ${pluralize(
137
+ existingFiles.length,
138
+ "this file already exists",
139
+ "these files already exist"
140
+ )}: ${existingFiles.join(", ")}
141
+
142
+ Please delete or move them and try again.`;
143
+ console.log(chalk.red(errorMsg));
144
+ process.exit(1);
235
145
  }
236
146
 
237
- // This is just in case we have been using the sample project for dev/testing
238
- await removeTempFilesIfPresent(projectRoot);
147
+ await fsExtra.copy(
148
+ path.join(packageRoot, "sample-projects", sampleProjectName),
149
+ projectRoot
150
+ );
239
151
 
240
152
  await fsExtra.remove(path.join(projectRoot, "LICENSE.md"));
241
153
  }
@@ -271,11 +183,9 @@ async function printRecommendedDepsInstallationInstructions(
271
183
  async function writeEmptyHardhatConfig() {
272
184
  return fsExtra.writeFile(
273
185
  "hardhat.config.js",
274
- `/**
275
- * @type import('hardhat/config').HardhatUserConfig
276
- */
186
+ `/** @type import('hardhat/config').HardhatUserConfig */
277
187
  module.exports = {
278
- solidity: "${DEFAULT_SOLC_VERSION}",
188
+ solidity: "0.8.9",
279
189
  };
280
190
  `,
281
191
  "utf-8"
@@ -284,20 +194,13 @@ module.exports = {
284
194
 
285
195
  async function getAction(): Promise<Action> {
286
196
  if (
287
- process.env.HARDHAT_CREATE_BASIC_SAMPLE_PROJECT_WITH_DEFAULTS !== undefined
288
- ) {
289
- return Action.CREATE_BASIC_SAMPLE_PROJECT_ACTION;
290
- } else if (
291
- process.env.HARDHAT_CREATE_ADVANCED_SAMPLE_PROJECT_WITH_DEFAULTS !==
292
- undefined
197
+ process.env.HARDHAT_CREATE_JAVASCRIPT_PROJECT_WITH_DEFAULTS !== undefined
293
198
  ) {
294
- return Action.CREATE_ADVANCED_SAMPLE_PROJECT_ACTION;
199
+ return Action.CREATE_JAVASCRIPT_PROJECT_ACTION;
295
200
  } else if (
296
- process.env
297
- .HARDHAT_CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_WITH_DEFAULTS !==
298
- undefined
201
+ process.env.HARDHAT_CREATE_TYPESCRIPT_PROJECT_WITH_DEFAULTS !== undefined
299
202
  ) {
300
- return Action.CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_ACTION;
203
+ return Action.CREATE_TYPESCRIPT_PROJECT_ACTION;
301
204
  }
302
205
 
303
206
  const { default: enquirer } = await import("enquirer");
@@ -341,8 +244,16 @@ async function createPackageJson() {
341
244
  );
342
245
  }
343
246
 
247
+ function showStarOnGitHubMessage() {
248
+ console.log(
249
+ chalk.cyan("Give Hardhat a star on Github if you're enjoying it!") +
250
+ emoji(" 💞✨")
251
+ );
252
+ console.log();
253
+ console.log(chalk.cyan(" https://github.com/NomicFoundation/hardhat"));
254
+ }
255
+
344
256
  export async function createProject() {
345
- const { default: enquirer } = await import("enquirer");
346
257
  printAsciiLogo();
347
258
 
348
259
  await printWelcomeMessage();
@@ -375,6 +286,9 @@ export async function createProject() {
375
286
  console.log("");
376
287
  }
377
288
 
289
+ console.log();
290
+ showStarOnGitHubMessage();
291
+
378
292
  return;
379
293
  }
380
294
 
@@ -384,13 +298,8 @@ export async function createProject() {
384
298
  };
385
299
 
386
300
  const useDefaultPromptResponses =
387
- process.env.HARDHAT_CREATE_BASIC_SAMPLE_PROJECT_WITH_DEFAULTS !==
388
- undefined ||
389
- process.env.HARDHAT_CREATE_ADVANCED_SAMPLE_PROJECT_WITH_DEFAULTS !==
390
- undefined ||
391
- process.env
392
- .HARDHAT_CREATE_ADVANCED_TYPESCRIPT_SAMPLE_PROJECT_WITH_DEFAULTS !==
393
- undefined;
301
+ process.env.HARDHAT_CREATE_JAVASCRIPT_PROJECT_WITH_DEFAULTS !== undefined ||
302
+ process.env.HARDHAT_CREATE_TYPESCRIPT_PROJECT_WITH_DEFAULTS !== undefined;
394
303
 
395
304
  if (useDefaultPromptResponses) {
396
305
  responses = {
@@ -399,18 +308,7 @@ export async function createProject() {
399
308
  };
400
309
  } else {
401
310
  try {
402
- responses = await enquirer.prompt<typeof responses>([
403
- {
404
- name: "projectRoot",
405
- type: "input",
406
- initial: process.cwd(),
407
- message: "Hardhat project root:",
408
- },
409
- createConfirmationPrompt(
410
- "shouldAddGitIgnore",
411
- "Do you want to add a .gitignore?"
412
- ),
413
- ]);
311
+ responses = await confirmProjectCreation();
414
312
  } catch (e) {
415
313
  if (e === "") {
416
314
  return;
@@ -423,8 +321,6 @@ export async function createProject() {
423
321
 
424
322
  const { projectRoot, shouldAddGitIgnore } = responses;
425
323
 
426
- await copySampleProject(projectRoot, action);
427
-
428
324
  if (shouldAddGitIgnore) {
429
325
  await addGitIgnore(projectRoot);
430
326
  }
@@ -437,13 +333,12 @@ export async function createProject() {
437
333
  }
438
334
  }
439
335
 
336
+ await copySampleProject(projectRoot, action);
337
+
440
338
  let shouldShowInstallationInstructions = true;
441
339
 
442
340
  if (await canInstallRecommendedDeps()) {
443
- const dependencies = await getDependencies(
444
- action as SampleProjectTypeCreationAction /* type cast feels okay here
445
- because we already returned from this function if it isn't valid. */
446
- );
341
+ const dependencies = await getDependencies(action);
447
342
 
448
343
  const recommendedDeps = Object.keys(dependencies);
449
344
 
@@ -461,7 +356,10 @@ export async function createProject() {
461
356
  } else if (installedExceptHardhat.length === 0) {
462
357
  const shouldInstall =
463
358
  useDefaultPromptResponses ||
464
- (await confirmRecommendedDepsInstallation(dependenciesToInstall));
359
+ (await confirmRecommendedDepsInstallation(
360
+ dependenciesToInstall,
361
+ await isYarnProject()
362
+ ));
465
363
  if (shouldInstall) {
466
364
  const installed = await installRecommendedDependencies(
467
365
  dependenciesToInstall
@@ -486,42 +384,10 @@ export async function createProject() {
486
384
  console.log(
487
385
  `\n${emoji("✨ ")}${chalk.cyan("Project created")}${emoji(" ✨")}`
488
386
  );
489
-
490
- console.log("See the README.md file for some example tasks you can run.");
491
- }
492
-
493
- function createConfirmationPrompt(name: string, message: string) {
494
- return {
495
- type: "confirm",
496
- name,
497
- message,
498
- initial: "y",
499
- default: "(Y/n)",
500
- isTrue(input: string | boolean) {
501
- if (typeof input === "string") {
502
- return input.toLowerCase() === "y";
503
- }
504
-
505
- return input;
506
- },
507
- isFalse(input: string | boolean) {
508
- if (typeof input === "string") {
509
- return input.toLowerCase() === "n";
510
- }
511
-
512
- return input;
513
- },
514
- format(): string {
515
- const that = this as any;
516
- const value = that.value === true ? "y" : "n";
517
-
518
- if (that.state.submitted === true) {
519
- return that.styles.submitted(value);
520
- }
521
-
522
- return value;
523
- },
524
- };
387
+ console.log();
388
+ console.log("See the README.md file for some example tasks you can run");
389
+ console.log();
390
+ showStarOnGitHubMessage();
525
391
  }
526
392
 
527
393
  async function canInstallRecommendedDeps() {
@@ -549,6 +415,16 @@ async function isYarnProject() {
549
415
  return fsExtra.pathExists("yarn.lock");
550
416
  }
551
417
 
418
+ async function doesNpmAutoInstallPeerDependencies() {
419
+ const { execSync } = require("child_process");
420
+ try {
421
+ const version: string = execSync("npm --version").toString();
422
+ return parseInt(version.split(".")[0], 10) >= 7;
423
+ } catch (_) {
424
+ return false;
425
+ }
426
+ }
427
+
552
428
  async function installRecommendedDependencies(dependencies: Dependencies) {
553
429
  console.log("");
554
430
 
@@ -562,64 +438,6 @@ async function installRecommendedDependencies(dependencies: Dependencies) {
562
438
  return installDependencies(installCmd[0], installCmd.slice(1));
563
439
  }
564
440
 
565
- async function confirmRecommendedDepsInstallation(
566
- depsToInstall: Dependencies
567
- ): Promise<boolean> {
568
- const { default: enquirer } = await import("enquirer");
569
-
570
- let responses: {
571
- shouldInstallPlugin: boolean;
572
- };
573
-
574
- const packageManager = (await isYarnProject()) ? "yarn" : "npm";
575
-
576
- try {
577
- responses = await enquirer.prompt<typeof responses>([
578
- createConfirmationPrompt(
579
- "shouldInstallPlugin",
580
- `Do you want to install this sample project's dependencies with ${packageManager} (${Object.keys(
581
- depsToInstall
582
- ).join(" ")})?`
583
- ),
584
- ]);
585
- } catch (e) {
586
- if (e === "") {
587
- return false;
588
- }
589
-
590
- // eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
591
- throw e;
592
- }
593
-
594
- return responses.shouldInstallPlugin;
595
- }
596
-
597
- export async function confirmTelemetryConsent(): Promise<boolean | undefined> {
598
- const enquirer = require("enquirer");
599
-
600
- const prompt = new enquirer.prompts.Confirm({
601
- name: "telemetryConsent",
602
- type: "confirm",
603
- initial: true,
604
- message:
605
- "Help us improve Hardhat with anonymous crash reports & basic usage data?",
606
- });
607
-
608
- let timeout;
609
- const timeoutPromise = new Promise((resolve) => {
610
- timeout = setTimeout(resolve, TELEMETRY_CONSENT_TIMEOUT);
611
- });
612
-
613
- const result = await Promise.race([prompt.run(), timeoutPromise]);
614
-
615
- clearTimeout(timeout);
616
- if (result === undefined) {
617
- await prompt.cancel();
618
- }
619
-
620
- return result;
621
- }
622
-
623
441
  async function installDependencies(
624
442
  packageManager: string,
625
443
  args: string[]
@@ -629,7 +447,7 @@ async function installDependencies(
629
447
  console.log(`${packageManager} ${args.join(" ")}`);
630
448
 
631
449
  const childProcess = spawn(packageManager, args, {
632
- stdio: "inherit" as any, // There's an error in the TS definition of ForkOptions
450
+ stdio: "inherit",
633
451
  });
634
452
 
635
453
  return new Promise((resolve, reject) => {
@@ -666,9 +484,25 @@ async function getRecommendedDependenciesInstallationCommand(
666
484
  return ["npm", "install", "--save-dev", ...deps];
667
485
  }
668
486
 
669
- async function getDependencies(projectType: SampleProjectTypeCreationAction) {
487
+ async function getDependencies(
488
+ projectType: SampleProjectTypeCreationAction
489
+ ): Promise<Dependencies> {
490
+ const shouldInstallPeerDependencies =
491
+ (await isYarnProject()) || !(await doesNpmAutoInstallPeerDependencies());
492
+
493
+ const shouldInstallTypescriptDependencies =
494
+ projectType === Action.CREATE_TYPESCRIPT_PROJECT_ACTION;
495
+
496
+ const shouldInstallTypescriptPeerDependencies =
497
+ shouldInstallTypescriptDependencies && shouldInstallPeerDependencies;
498
+
670
499
  return {
671
500
  [HARDHAT_PACKAGE_NAME]: `^${(await getPackageJson()).version}`,
672
- ...SAMPLE_PROJECT_DEPENDENCIES[projectType],
501
+ ...PROJECT_DEPENDENCIES,
502
+ ...(shouldInstallPeerDependencies ? PEER_DEPENDENCIES : {}),
503
+ ...(shouldInstallTypescriptDependencies ? TYPESCRIPT_DEPENDENCIES : {}),
504
+ ...(shouldInstallTypescriptPeerDependencies
505
+ ? TYPESCRIPT_PEER_DEPENDENCIES
506
+ : {}),
673
507
  };
674
508
  }