hardhat 2.13.0-dev.0 → 2.13.0-dev.2
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/builtin-tasks/compile.js +2 -11
- package/builtin-tasks/compile.js.map +1 -1
- package/builtin-tasks/flatten.js +9 -3
- package/builtin-tasks/flatten.js.map +1 -1
- package/builtin-tasks/task-names.d.ts +0 -1
- package/builtin-tasks/task-names.d.ts.map +1 -1
- package/builtin-tasks/task-names.js +2 -3
- package/builtin-tasks/task-names.js.map +1 -1
- package/internal/artifacts/caching.d.ts +28 -0
- package/internal/artifacts/caching.d.ts.map +1 -0
- package/internal/artifacts/caching.js +178 -0
- package/internal/artifacts/caching.js.map +1 -0
- package/internal/artifacts/index.d.ts +45 -0
- package/internal/artifacts/index.d.ts.map +1 -0
- package/internal/artifacts/index.js +191 -0
- package/internal/artifacts/index.js.map +1 -0
- package/internal/artifacts/mutable.d.ts +29 -0
- package/internal/artifacts/mutable.d.ts.map +1 -0
- package/internal/artifacts/mutable.js +226 -0
- package/internal/artifacts/mutable.js.map +1 -0
- package/internal/artifacts/readonly.d.ts +94 -0
- package/internal/artifacts/readonly.d.ts.map +1 -0
- package/internal/artifacts/readonly.js +343 -0
- package/internal/artifacts/readonly.js.map +1 -0
- package/internal/artifacts.d.ts +5 -0
- package/internal/artifacts.d.ts.map +1 -1
- package/internal/artifacts.js +29 -10
- package/internal/artifacts.js.map +1 -1
- package/internal/cli/cli.js +15 -3
- package/internal/cli/cli.js.map +1 -1
- package/internal/cli/project-creation.d.ts +1 -0
- package/internal/cli/project-creation.d.ts.map +1 -1
- package/internal/cli/project-creation.js +13 -2
- package/internal/cli/project-creation.js.map +1 -1
- package/internal/core/config/config-env.d.ts +7 -1
- package/internal/core/config/config-env.d.ts.map +1 -1
- package/internal/core/config/config-env.js +13 -2
- package/internal/core/config/config-env.js.map +1 -1
- package/internal/core/config/config-resolution.d.ts.map +1 -1
- package/internal/core/config/config-resolution.js +2 -1
- package/internal/core/config/config-resolution.js.map +1 -1
- package/internal/core/config/extenders.d.ts +7 -4
- package/internal/core/config/extenders.d.ts.map +1 -1
- package/internal/core/config/extenders.js +12 -5
- package/internal/core/config/extenders.js.map +1 -1
- package/internal/core/errors-list.d.ts +14 -0
- package/internal/core/errors-list.d.ts.map +1 -1
- package/internal/core/errors-list.js +93 -75
- package/internal/core/errors-list.js.map +1 -1
- package/internal/core/flamegraph.js +10 -10
- package/internal/core/jsonrpc/types/input/blockTag.d.ts +3 -3
- package/internal/core/jsonrpc/types/input/blockTag.d.ts.map +1 -1
- package/internal/core/jsonrpc/types/output/metadata.d.ts +13 -0
- package/internal/core/jsonrpc/types/output/metadata.d.ts.map +1 -0
- package/internal/core/jsonrpc/types/output/metadata.js +3 -0
- package/internal/core/jsonrpc/types/output/metadata.js.map +1 -0
- package/internal/core/providers/accounts.d.ts.map +1 -1
- package/internal/core/providers/accounts.js +4 -1
- package/internal/core/providers/accounts.js.map +1 -1
- package/internal/core/providers/backwards-compatibility.d.ts.map +1 -1
- package/internal/core/providers/backwards-compatibility.js +3 -0
- package/internal/core/providers/backwards-compatibility.js.map +1 -1
- package/internal/core/providers/gas-providers.d.ts +1 -1
- package/internal/core/providers/gas-providers.d.ts.map +1 -1
- package/internal/core/providers/gas-providers.js +1 -1
- package/internal/core/providers/gas-providers.js.map +1 -1
- package/internal/core/runtime-environment.d.ts +2 -2
- package/internal/core/runtime-environment.d.ts.map +1 -1
- package/internal/core/runtime-environment.js +2 -2
- package/internal/core/runtime-environment.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/client.d.ts.map +1 -1
- package/internal/hardhat-network/jsonrpc/client.js +5 -3
- package/internal/hardhat-network/jsonrpc/client.js.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js +9 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js.map +1 -1
- package/internal/hardhat-network/provider/modules/eth.js +4 -4
- package/internal/hardhat-network/provider/modules/hardhat.d.ts +2 -0
- package/internal/hardhat-network/provider/modules/hardhat.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/hardhat.js +9 -0
- package/internal/hardhat-network/provider/modules/hardhat.js.map +1 -1
- package/internal/hardhat-network/provider/modules/web3.d.ts +3 -0
- package/internal/hardhat-network/provider/modules/web3.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/web3.js +4 -4
- package/internal/hardhat-network/provider/modules/web3.js.map +1 -1
- package/internal/hardhat-network/provider/node.d.ts +5 -0
- package/internal/hardhat-network/provider/node.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.js +40 -3
- package/internal/hardhat-network/provider/node.js.map +1 -1
- package/internal/hardhat-network/provider/output.d.ts +1 -1
- package/internal/hardhat-network/provider/output.d.ts.map +1 -1
- package/internal/hardhat-network/provider/output.js +1 -1
- package/internal/hardhat-network/provider/output.js.map +1 -1
- package/internal/hardhat-network/provider/provider.js +1 -1
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.d.ts +32 -0
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.d.ts.map +1 -0
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.js +87 -0
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.js.map +1 -0
- package/internal/hardhat-network/provider/utils/makeForkClient.d.ts +1 -0
- package/internal/hardhat-network/provider/utils/makeForkClient.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.js +4 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.js.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.js +2 -5
- package/internal/hardhat-network/stack-traces/error-inferrer.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.js +2 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-debug-tracer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-debug-tracer.js +2 -1
- package/internal/hardhat-network/stack-traces/vm-debug-tracer.js.map +1 -1
- package/internal/lib/hardhat-lib.d.ts.map +1 -1
- package/internal/lib/hardhat-lib.js +4 -1
- package/internal/lib/hardhat-lib.js.map +1 -1
- package/internal/solidity/compiler/compiler-input.d.ts.map +1 -1
- package/internal/solidity/compiler/compiler-input.js +5 -1
- package/internal/solidity/compiler/compiler-input.js.map +1 -1
- package/internal/solidity/compiler/downloader.d.ts.map +1 -1
- package/internal/solidity/compiler/downloader.js +10 -12
- package/internal/solidity/compiler/downloader.js.map +1 -1
- package/internal/solidity/compiler/index.d.ts.map +1 -1
- package/internal/solidity/compiler/index.js +6 -0
- package/internal/solidity/compiler/index.js.map +1 -1
- package/internal/solidity/dependencyGraph.d.ts.map +1 -1
- package/internal/solidity/dependencyGraph.js +2 -0
- package/internal/solidity/dependencyGraph.js.map +1 -1
- package/internal/solidity/resolver.d.ts +3 -4
- package/internal/solidity/resolver.d.ts.map +1 -1
- package/internal/solidity/resolver.js +11 -5
- package/internal/solidity/resolver.js.map +1 -1
- package/internal/util/console.d.ts.map +1 -1
- package/internal/util/console.js +1 -1
- package/internal/util/console.js.map +1 -1
- package/internal/util/download.d.ts +3 -1
- package/internal/util/download.d.ts.map +1 -1
- package/internal/util/download.js +2 -1
- package/internal/util/download.js.map +1 -1
- package/internal/util/keys-derivation.d.ts.map +1 -1
- package/internal/util/keys-derivation.js +4 -1
- package/internal/util/keys-derivation.js.map +1 -1
- package/internal/util/packageInfo.d.ts +1 -0
- package/internal/util/packageInfo.d.ts.map +1 -1
- package/internal/util/packageInfo.js +10 -1
- package/internal/util/packageInfo.js.map +1 -1
- package/package.json +1 -1
- package/recommended-gitignore.txt +1 -1
- package/register.js +4 -1
- package/register.js.map +1 -1
- package/src/builtin-tasks/compile.ts +3 -20
- package/src/builtin-tasks/flatten.ts +14 -3
- package/src/builtin-tasks/task-names.ts +0 -2
- package/src/internal/artifacts/caching.ts +259 -0
- package/src/internal/artifacts/index.ts +302 -0
- package/src/internal/artifacts/mutable.ts +330 -0
- package/src/internal/artifacts/readonly.ts +470 -0
- package/src/internal/cli/cli.ts +22 -3
- package/src/internal/cli/project-creation.ts +17 -1
- package/src/internal/core/config/config-env.ts +13 -1
- package/src/internal/core/config/config-resolution.ts +4 -3
- package/src/internal/core/config/extenders.ts +15 -6
- package/src/internal/core/errors-list.ts +94 -75
- package/src/internal/core/flamegraph.ts +10 -10
- package/src/internal/core/jsonrpc/types/output/metadata.ts +32 -0
- package/src/internal/core/providers/accounts.ts +5 -2
- package/src/internal/core/providers/backwards-compatibility.ts +3 -0
- package/src/internal/core/providers/gas-providers.ts +1 -1
- package/src/internal/core/runtime-environment.ts +3 -1
- package/src/internal/hardhat-network/jsonrpc/client.ts +7 -4
- package/src/internal/hardhat-network/provider/fork/ForkBlockchain.ts +15 -3
- package/src/internal/hardhat-network/provider/modules/eth.ts +4 -4
- package/src/internal/hardhat-network/provider/modules/hardhat.ts +14 -0
- package/src/internal/hardhat-network/provider/modules/web3.ts +4 -4
- package/src/internal/hardhat-network/provider/node.ts +58 -0
- package/src/internal/hardhat-network/provider/output.ts +2 -2
- package/src/internal/hardhat-network/provider/provider.ts +1 -1
- package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.ts +162 -0
- package/src/internal/hardhat-network/provider/utils/makeForkClient.ts +10 -1
- package/src/internal/hardhat-network/stack-traces/compiler-to-model.ts +2 -2
- package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +2 -6
- package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +3 -1
- package/src/internal/hardhat-network/stack-traces/vm-debug-tracer.ts +4 -1
- package/src/internal/lib/hardhat-lib.ts +6 -1
- package/src/internal/solidity/compiler/compiler-input.ts +7 -1
- package/src/internal/solidity/compiler/downloader.ts +11 -11
- package/src/internal/solidity/compiler/index.ts +8 -0
- package/src/internal/solidity/dependencyGraph.ts +2 -0
- package/src/internal/solidity/resolver.ts +13 -8
- package/src/internal/util/console.ts +4 -2
- package/src/internal/util/download.ts +3 -1
- package/src/internal/util/keys-derivation.ts +4 -1
- package/src/internal/util/packageInfo.ts +9 -0
- package/src/register.ts +6 -1
- package/src/types/artifacts.ts +116 -4
- package/src/types/runtime.ts +7 -1
- package/src/utils/source-names.ts +15 -0
- package/types/artifacts.d.ts +100 -4
- package/types/artifacts.d.ts.map +1 -1
- package/types/runtime.d.ts +6 -1
- package/types/runtime.d.ts.map +1 -1
- package/utils/source-names.d.ts +5 -0
- package/utils/source-names.d.ts.map +1 -1
- package/utils/source-names.js +14 -1
- package/utils/source-names.js.map +1 -1
- package/internal/hardhat-network/provider/utils/convertToRethnet.d.ts +0 -4
- package/internal/hardhat-network/provider/utils/convertToRethnet.d.ts.map +0 -1
- package/internal/hardhat-network/provider/utils/convertToRethnet.js +0 -31
- package/internal/hardhat-network/provider/utils/convertToRethnet.js.map +0 -1
- package/src/internal/artifacts.ts +0 -918
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import * as os from "os";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
|
|
4
|
+
import fsExtra from "fs-extra";
|
|
5
|
+
|
|
6
|
+
import { Artifact, BuildInfo } from "../../types";
|
|
7
|
+
import {
|
|
8
|
+
getFullyQualifiedName,
|
|
9
|
+
isFullyQualifiedName,
|
|
10
|
+
parseFullyQualifiedName,
|
|
11
|
+
findDistance,
|
|
12
|
+
} from "../../utils/contract-names";
|
|
13
|
+
import { replaceBackslashes } from "../../utils/source-names";
|
|
14
|
+
|
|
15
|
+
import { BUILD_INFO_DIR_NAME, EDIT_DISTANCE_THRESHOLD } from "../constants";
|
|
16
|
+
import { HardhatError } from "../core/errors";
|
|
17
|
+
import { ERRORS } from "../core/errors-list";
|
|
18
|
+
import {
|
|
19
|
+
FileNotFoundError,
|
|
20
|
+
getAllFilesMatching,
|
|
21
|
+
getAllFilesMatchingSync,
|
|
22
|
+
getFileTrueCase,
|
|
23
|
+
getFileTrueCaseSync,
|
|
24
|
+
} from "../util/fs-utils";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The purpose of this class is to encapsulate JSON file I/O. It assumes that
|
|
28
|
+
* all input strings are simply paths, not contract names nor fully-qualified
|
|
29
|
+
* contract names like other interfaces around here accept.
|
|
30
|
+
*/
|
|
31
|
+
class ReadOnlyByPath {
|
|
32
|
+
protected async _readArtifactByPath(artifactPath: string): Promise<Artifact> {
|
|
33
|
+
return fsExtra.readJson(artifactPath);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
protected _readArtifactByPathSync(artifactPath: string): Artifact {
|
|
37
|
+
return fsExtra.readJsonSync(artifactPath);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
protected async _artifactPathExists(artifactPath: string): Promise<boolean> {
|
|
41
|
+
return fsExtra.pathExists(artifactPath);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected async _getBuildInfoByPath(
|
|
45
|
+
buildInfoPath: string
|
|
46
|
+
): Promise<BuildInfo | undefined> {
|
|
47
|
+
return fsExtra.readJSON(buildInfoPath);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
protected _getBuildInfoByPathSync(
|
|
51
|
+
buildInfoPath: string
|
|
52
|
+
): BuildInfo | undefined {
|
|
53
|
+
return fsExtra.readJSONSync(buildInfoPath);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Given the path to a debug file, returns the absolute path to its
|
|
58
|
+
* corresponding build info file if it exists, or undefined otherwise.
|
|
59
|
+
*/
|
|
60
|
+
protected static async _getBuildInfoFromDebugFile(
|
|
61
|
+
debugFilePath: string
|
|
62
|
+
): Promise<string | undefined> {
|
|
63
|
+
if (await fsExtra.pathExists(debugFilePath)) {
|
|
64
|
+
const { buildInfo } = await fsExtra.readJson(debugFilePath);
|
|
65
|
+
return path.resolve(path.dirname(debugFilePath), buildInfo);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Synchronous version of _getBuildInfoFromDebugFile
|
|
73
|
+
*/
|
|
74
|
+
protected static _getBuildInfoFromDebugFileSync(
|
|
75
|
+
debugFilePath: string
|
|
76
|
+
): string | undefined {
|
|
77
|
+
if (fsExtra.pathExistsSync(debugFilePath)) {
|
|
78
|
+
const { buildInfo } = fsExtra.readJsonSync(debugFilePath);
|
|
79
|
+
return path.resolve(path.dirname(debugFilePath), buildInfo);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
protected _getDebugFilePath(artifactPath: string): string {
|
|
86
|
+
return artifactPath.replace(/\.json$/, ".dbg.json");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* This class takes responsibility for the mappings between contract names,
|
|
92
|
+
* fully-qualified contract names, and file paths.
|
|
93
|
+
*/
|
|
94
|
+
export class ReadOnlySource extends ReadOnlyByPath {
|
|
95
|
+
constructor(protected _artifactsPath: string) {
|
|
96
|
+
super();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public async artifactExists(name: string): Promise<boolean> {
|
|
100
|
+
const artifactPath = await this._getArtifactPath(name);
|
|
101
|
+
|
|
102
|
+
if (artifactPath === undefined) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return super._artifactPathExists(artifactPath);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public async getArtifactPaths(): Promise<string[]> {
|
|
110
|
+
const buildInfosDir = path.join(this._artifactsPath, BUILD_INFO_DIR_NAME);
|
|
111
|
+
|
|
112
|
+
const paths = await getAllFilesMatching(
|
|
113
|
+
this._artifactsPath,
|
|
114
|
+
(f) =>
|
|
115
|
+
f.endsWith(".json") &&
|
|
116
|
+
!f.startsWith(buildInfosDir) &&
|
|
117
|
+
!f.endsWith(".dbg.json")
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
return paths.sort();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns the absolute path to the given artifact
|
|
125
|
+
*/
|
|
126
|
+
public formArtifactPathFromFullyQualifiedName(
|
|
127
|
+
fullyQualifiedName: string
|
|
128
|
+
): string {
|
|
129
|
+
const { sourceName, contractName } =
|
|
130
|
+
parseFullyQualifiedName(fullyQualifiedName);
|
|
131
|
+
|
|
132
|
+
return path.join(this._artifactsPath, sourceName, `${contractName}.json`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public async getAllFullyQualifiedNames(): Promise<string[]> {
|
|
136
|
+
const paths = await this.getArtifactPaths();
|
|
137
|
+
return paths.map((p) => this._getFullyQualifiedNameFromPath(p)).sort();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public async getBuildInfo(
|
|
141
|
+
fullyQualifiedName: string
|
|
142
|
+
): Promise<BuildInfo | undefined> {
|
|
143
|
+
const buildInfoPath = await this._getBuildInfoPath(fullyQualifiedName);
|
|
144
|
+
|
|
145
|
+
if (buildInfoPath === undefined) {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return super._getBuildInfoByPath(buildInfoPath);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public async getBuildInfoPaths(): Promise<string[]> {
|
|
153
|
+
const paths = await getAllFilesMatching(
|
|
154
|
+
path.join(this._artifactsPath, BUILD_INFO_DIR_NAME),
|
|
155
|
+
(f) => f.endsWith(".json")
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
return paths.sort();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public async getDebugFilePaths(): Promise<string[]> {
|
|
162
|
+
const paths = await getAllFilesMatching(
|
|
163
|
+
path.join(this._artifactsPath),
|
|
164
|
+
(f) => f.endsWith(".dbg.json")
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return paths.sort();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
public async readArtifact(name: string): Promise<Artifact | undefined> {
|
|
171
|
+
const artifactPath = await this._getArtifactPath(name);
|
|
172
|
+
if (artifactPath === undefined) {
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return super._readArtifactByPath(artifactPath);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public readArtifactSync(name: string): Artifact | undefined {
|
|
180
|
+
const artifactPath = this._getArtifactPathSync(name);
|
|
181
|
+
if (artifactPath === undefined) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return super._readArtifactByPathSync(artifactPath);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
public getSuggestions(name: string): string[] {
|
|
189
|
+
if (isFullyQualifiedName(name)) {
|
|
190
|
+
const fqns = this._getAllFullyQualifiedNamesSync();
|
|
191
|
+
|
|
192
|
+
return ReadOnlySource._getSimilarContractNames(name, fqns);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const files = this._getArtifactPathsSync();
|
|
196
|
+
const names = this._getAllContractNamesFromFiles(files);
|
|
197
|
+
|
|
198
|
+
let similarNames = ReadOnlySource._getSimilarContractNames(name, names);
|
|
199
|
+
|
|
200
|
+
if (similarNames.length > 1) {
|
|
201
|
+
similarNames = this._filterDuplicatesAsFullyQualifiedNames(
|
|
202
|
+
files,
|
|
203
|
+
similarNames
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return similarNames;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* If the project has these contracts:
|
|
212
|
+
* - 'contracts/Greeter.sol:Greeter'
|
|
213
|
+
* - 'contracts/Meeter.sol:Greeter'
|
|
214
|
+
* - 'contracts/Greater.sol:Greater'
|
|
215
|
+
* And the user tries to get an artifact with the name 'Greter', then
|
|
216
|
+
* the suggestions will be 'Greeter', 'Greeter', and 'Greater'.
|
|
217
|
+
*
|
|
218
|
+
* We don't want to show duplicates here, so we use FQNs for those. The
|
|
219
|
+
* suggestions will then be:
|
|
220
|
+
* - 'contracts/Greeter.sol:Greeter'
|
|
221
|
+
* - 'contracts/Meeter.sol:Greeter'
|
|
222
|
+
* - 'Greater'
|
|
223
|
+
*/
|
|
224
|
+
private _filterDuplicatesAsFullyQualifiedNames(
|
|
225
|
+
files: string[],
|
|
226
|
+
similarNames: string[]
|
|
227
|
+
): string[] {
|
|
228
|
+
const outputNames = [];
|
|
229
|
+
const groups = similarNames.reduce((obj, cur) => {
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
231
|
+
obj[cur] = obj[cur] ? obj[cur] + 1 : 1;
|
|
232
|
+
return obj;
|
|
233
|
+
}, {} as { [k: string]: number });
|
|
234
|
+
|
|
235
|
+
for (const [name, occurrences] of Object.entries(groups)) {
|
|
236
|
+
if (occurrences > 1) {
|
|
237
|
+
for (const file of files) {
|
|
238
|
+
if (path.basename(file) === `${name}.json`) {
|
|
239
|
+
outputNames.push(this._getFullyQualifiedNameFromPath(file));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
outputNames.push(name);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return outputNames;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private _getAllContractNamesFromFiles(files: string[]): string[] {
|
|
252
|
+
return files.map((file) => {
|
|
253
|
+
const fqn = this._getFullyQualifiedNameFromPath(file);
|
|
254
|
+
return parseFullyQualifiedName(fqn).contractName;
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private _getAllFullyQualifiedNamesSync(): string[] {
|
|
259
|
+
const paths = this._getArtifactPathsSync();
|
|
260
|
+
return paths.map((p) => this._getFullyQualifiedNameFromPath(p)).sort();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Returns the absolute path to the artifact that corresponds to the given
|
|
265
|
+
* name.
|
|
266
|
+
*
|
|
267
|
+
* If the name is fully qualified, the path is computed from it. If not, an
|
|
268
|
+
* artifact that matches the given name is searched in the existing artifacts.
|
|
269
|
+
* If there is an ambiguity, an error is thrown.
|
|
270
|
+
*/
|
|
271
|
+
protected async _getArtifactPath(name: string): Promise<string | undefined> {
|
|
272
|
+
let result: string | undefined;
|
|
273
|
+
if (isFullyQualifiedName(name)) {
|
|
274
|
+
result = await this._getValidArtifactPathFromFullyQualifiedName(name);
|
|
275
|
+
} else {
|
|
276
|
+
const files = await this.getArtifactPaths();
|
|
277
|
+
result = this._getArtifactPathFromFiles(name, files);
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
protected _getArtifactPathSync(name: string): string | undefined {
|
|
283
|
+
let result: string | undefined;
|
|
284
|
+
if (isFullyQualifiedName(name)) {
|
|
285
|
+
result = this._getValidArtifactPathFromFullyQualifiedNameSync(name);
|
|
286
|
+
} else {
|
|
287
|
+
const files = this._getArtifactPathsSync();
|
|
288
|
+
result = this._getArtifactPathFromFiles(name, files);
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private _getArtifactPathFromFiles(
|
|
294
|
+
contractName: string,
|
|
295
|
+
files: string[]
|
|
296
|
+
): string | undefined {
|
|
297
|
+
const matchingFiles = files.filter((file) => {
|
|
298
|
+
return path.basename(file) === `${contractName}.json`;
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
if (matchingFiles.length === 0) {
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (matchingFiles.length > 1) {
|
|
306
|
+
const candidates = matchingFiles.map((file) =>
|
|
307
|
+
this._getFullyQualifiedNameFromPath(file)
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
throw new HardhatError(ERRORS.ARTIFACTS.MULTIPLE_FOUND, {
|
|
311
|
+
contractName,
|
|
312
|
+
candidates: candidates.join(os.EOL),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return matchingFiles[0];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
protected _getArtifactPathsSync(): string[] {
|
|
320
|
+
const buildInfosDir = path.join(this._artifactsPath, BUILD_INFO_DIR_NAME);
|
|
321
|
+
|
|
322
|
+
const paths = getAllFilesMatchingSync(
|
|
323
|
+
this._artifactsPath,
|
|
324
|
+
(f) =>
|
|
325
|
+
f.endsWith(".json") &&
|
|
326
|
+
!f.startsWith(buildInfosDir) &&
|
|
327
|
+
!f.endsWith(".dbg.json")
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
return paths.sort();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
protected async _getBuildInfoPath(
|
|
334
|
+
fullyQualifiedName: string
|
|
335
|
+
): Promise<string | undefined> {
|
|
336
|
+
const artifactPath =
|
|
337
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
338
|
+
|
|
339
|
+
const debugFilePath = this._getDebugFilePath(artifactPath);
|
|
340
|
+
const buildInfoPath = await ReadOnlySource._getBuildInfoFromDebugFile(
|
|
341
|
+
debugFilePath
|
|
342
|
+
);
|
|
343
|
+
return buildInfoPath;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
protected _getBuildInfoPathSync(
|
|
347
|
+
fullyQualifiedName: string
|
|
348
|
+
): string | undefined {
|
|
349
|
+
const artifactPath =
|
|
350
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
351
|
+
|
|
352
|
+
const debugFilePath = this._getDebugFilePath(artifactPath);
|
|
353
|
+
const buildInfoPath =
|
|
354
|
+
ReadOnlySource._getBuildInfoFromDebugFileSync(debugFilePath);
|
|
355
|
+
return buildInfoPath;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Returns the FQN of a contract giving the absolute path to its artifact.
|
|
360
|
+
*
|
|
361
|
+
* For example, given a path like
|
|
362
|
+
* `/path/to/project/artifacts/contracts/Foo.sol/Bar.json`, it'll return the
|
|
363
|
+
* FQN `contracts/Foo.sol:Bar`
|
|
364
|
+
*/
|
|
365
|
+
private _getFullyQualifiedNameFromPath(absolutePath: string): string {
|
|
366
|
+
const sourceName = replaceBackslashes(
|
|
367
|
+
path.relative(this._artifactsPath, path.dirname(absolutePath))
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
const contractName = path.basename(absolutePath).replace(".json", "");
|
|
371
|
+
|
|
372
|
+
return getFullyQualifiedName(sourceName, contractName);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
*
|
|
377
|
+
* @param givenName can be FQN or contract name
|
|
378
|
+
* @param names MUST match type of givenName (i.e. array of FQN's if givenName is FQN)
|
|
379
|
+
* @returns
|
|
380
|
+
*/
|
|
381
|
+
private static _getSimilarContractNames(
|
|
382
|
+
givenName: string,
|
|
383
|
+
names: string[]
|
|
384
|
+
): string[] {
|
|
385
|
+
let shortestDistance = EDIT_DISTANCE_THRESHOLD;
|
|
386
|
+
let mostSimilarNames: string[] = [];
|
|
387
|
+
for (const name of names) {
|
|
388
|
+
const distance = findDistance(givenName, name);
|
|
389
|
+
|
|
390
|
+
if (distance < shortestDistance) {
|
|
391
|
+
shortestDistance = distance;
|
|
392
|
+
mostSimilarNames = [name];
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (distance === shortestDistance) {
|
|
397
|
+
mostSimilarNames.push(name);
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return mostSimilarNames;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
private async _getValidArtifactPathFromFullyQualifiedName(
|
|
406
|
+
fullyQualifiedName: string
|
|
407
|
+
): Promise<string | undefined> {
|
|
408
|
+
const artifactPath =
|
|
409
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
const trueCasePath = path.join(
|
|
413
|
+
this._artifactsPath,
|
|
414
|
+
await getFileTrueCase(
|
|
415
|
+
this._artifactsPath,
|
|
416
|
+
path.relative(this._artifactsPath, artifactPath)
|
|
417
|
+
)
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
if (artifactPath !== trueCasePath) {
|
|
421
|
+
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
422
|
+
correct: this._getFullyQualifiedNameFromPath(trueCasePath),
|
|
423
|
+
incorrect: fullyQualifiedName,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return trueCasePath;
|
|
428
|
+
} catch (e) {
|
|
429
|
+
if (e instanceof FileNotFoundError) {
|
|
430
|
+
return undefined;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
434
|
+
throw e;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
private _getValidArtifactPathFromFullyQualifiedNameSync(
|
|
439
|
+
fullyQualifiedName: string
|
|
440
|
+
): string | undefined {
|
|
441
|
+
const artifactPath =
|
|
442
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
443
|
+
|
|
444
|
+
try {
|
|
445
|
+
const trueCasePath = path.join(
|
|
446
|
+
this._artifactsPath,
|
|
447
|
+
getFileTrueCaseSync(
|
|
448
|
+
this._artifactsPath,
|
|
449
|
+
path.relative(this._artifactsPath, artifactPath)
|
|
450
|
+
)
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
if (artifactPath !== trueCasePath) {
|
|
454
|
+
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
455
|
+
correct: this._getFullyQualifiedNameFromPath(trueCasePath),
|
|
456
|
+
incorrect: fullyQualifiedName,
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return trueCasePath;
|
|
461
|
+
} catch (e) {
|
|
462
|
+
if (e instanceof FileNotFoundError) {
|
|
463
|
+
return undefined;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
467
|
+
throw e;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
package/src/internal/cli/cli.ts
CHANGED
|
@@ -39,7 +39,7 @@ import { saveFlamegraph } from "../core/flamegraph";
|
|
|
39
39
|
import { Analytics } from "./analytics";
|
|
40
40
|
import { ArgumentsParser } from "./ArgumentsParser";
|
|
41
41
|
import { enableEmoji } from "./emoji";
|
|
42
|
-
import { createProject } from "./project-creation";
|
|
42
|
+
import { createProject, showSoliditySurveyMessage } from "./project-creation";
|
|
43
43
|
import { confirmHHVSCodeInstallation, confirmTelemetryConsent } from "./prompt";
|
|
44
44
|
import {
|
|
45
45
|
InstallationState,
|
|
@@ -171,7 +171,11 @@ async function main() {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
if (
|
|
174
|
+
if (
|
|
175
|
+
process.env.HARDHAT_EXPERIMENTAL_ALLOW_NON_LOCAL_INSTALLATION !==
|
|
176
|
+
"true" &&
|
|
177
|
+
!isHardhatInstalledLocallyOrLinked()
|
|
178
|
+
) {
|
|
175
179
|
throw new HardhatError(ERRORS.GENERAL.NON_LOCAL_INSTALLATION);
|
|
176
180
|
}
|
|
177
181
|
|
|
@@ -223,7 +227,7 @@ async function main() {
|
|
|
223
227
|
Reporter.setEnabled(true);
|
|
224
228
|
}
|
|
225
229
|
|
|
226
|
-
const envExtenders = ctx.extendersManager.
|
|
230
|
+
const envExtenders = ctx.extendersManager.getEnvironmentExtenders();
|
|
227
231
|
const taskDefinitions = ctx.tasksDSL.getTaskDefinitions();
|
|
228
232
|
|
|
229
233
|
const [abortAnalytics, hitPromise] = await analytics.sendTaskHit(taskName);
|
|
@@ -255,11 +259,16 @@ async function main() {
|
|
|
255
259
|
);
|
|
256
260
|
}
|
|
257
261
|
|
|
262
|
+
const artifactsExtensions = ctx.extendersManager
|
|
263
|
+
.getArtifactsExtenders()
|
|
264
|
+
.map((artifactsExtender) => artifactsExtender(resolvedConfig));
|
|
265
|
+
|
|
258
266
|
const env = new Environment(
|
|
259
267
|
resolvedConfig,
|
|
260
268
|
hardhatArguments,
|
|
261
269
|
taskDefinitions,
|
|
262
270
|
envExtenders,
|
|
271
|
+
artifactsExtensions,
|
|
263
272
|
ctx.experimentalHardhatNetworkMessageTraceHooks,
|
|
264
273
|
userConfig
|
|
265
274
|
);
|
|
@@ -301,6 +310,16 @@ async function main() {
|
|
|
301
310
|
process.stdout.isTTY === true
|
|
302
311
|
) {
|
|
303
312
|
await suggestInstallingHardhatVscode();
|
|
313
|
+
|
|
314
|
+
// we show the solidity survey message if the tests failed and only
|
|
315
|
+
// 1/3 of the time
|
|
316
|
+
if (
|
|
317
|
+
process.exitCode !== 0 &&
|
|
318
|
+
Math.random() < 0.3333 &&
|
|
319
|
+
process.env.HARDHAT_HIDE_SOLIDITY_SURVEY_MESSAGE !== "true"
|
|
320
|
+
) {
|
|
321
|
+
showSoliditySurveyMessage();
|
|
322
|
+
}
|
|
304
323
|
}
|
|
305
324
|
|
|
306
325
|
log(`Killing Hardhat after successfully running task ${taskName}`);
|
|
@@ -138,7 +138,7 @@ async function copySampleProject(
|
|
|
138
138
|
"this file already exists",
|
|
139
139
|
"these files already exist"
|
|
140
140
|
)}: ${existingFiles.join(", ")}
|
|
141
|
-
|
|
141
|
+
|
|
142
142
|
Please delete or move them and try again.`;
|
|
143
143
|
console.log(chalk.red(errorMsg));
|
|
144
144
|
process.exit(1);
|
|
@@ -252,6 +252,20 @@ function showStarOnGitHubMessage() {
|
|
|
252
252
|
console.log(chalk.cyan(" https://github.com/NomicFoundation/hardhat"));
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
+
export function showSoliditySurveyMessage() {
|
|
256
|
+
if (new Date() > new Date("2023-07-01 23:39")) {
|
|
257
|
+
// the survey has finished
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
console.log();
|
|
262
|
+
console.log(
|
|
263
|
+
chalk.cyan(
|
|
264
|
+
"Please take a moment to complete the 2022 Solidity Survey: https://hardhat.org/solidity-survey-2022"
|
|
265
|
+
)
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
255
269
|
export async function createProject() {
|
|
256
270
|
printAsciiLogo();
|
|
257
271
|
|
|
@@ -287,6 +301,7 @@ export async function createProject() {
|
|
|
287
301
|
|
|
288
302
|
console.log();
|
|
289
303
|
showStarOnGitHubMessage();
|
|
304
|
+
showSoliditySurveyMessage();
|
|
290
305
|
|
|
291
306
|
return;
|
|
292
307
|
}
|
|
@@ -387,6 +402,7 @@ export async function createProject() {
|
|
|
387
402
|
console.log("See the README.md file for some example tasks you can run");
|
|
388
403
|
console.log();
|
|
389
404
|
showStarOnGitHubMessage();
|
|
405
|
+
showSoliditySurveyMessage();
|
|
390
406
|
}
|
|
391
407
|
|
|
392
408
|
async function canInstallRecommendedDeps() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ActionType,
|
|
3
|
+
ArtifactsExtender,
|
|
3
4
|
ConfigExtender,
|
|
4
5
|
ConfigurableTaskDefinition,
|
|
5
6
|
EnvironmentExtender,
|
|
@@ -127,7 +128,7 @@ export const types = argumentTypes;
|
|
|
127
128
|
export function extendEnvironment(extender: EnvironmentExtender) {
|
|
128
129
|
const ctx = HardhatContext.getHardhatContext();
|
|
129
130
|
const extenderManager = ctx.extendersManager;
|
|
130
|
-
extenderManager.
|
|
131
|
+
extenderManager.addEnvironmentExtender(extender);
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
export function extendConfig(extender: ConfigExtender) {
|
|
@@ -135,6 +136,17 @@ export function extendConfig(extender: ConfigExtender) {
|
|
|
135
136
|
ctx.configExtenders.push(extender);
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Accepts a function that receives the resolved configuration and returns an
|
|
141
|
+
* extra source of artifacts. This source has to implement the ArtifactsSource
|
|
142
|
+
* interface.
|
|
143
|
+
*/
|
|
144
|
+
export function extendArtifacts(artifactsExtender: ArtifactsExtender) {
|
|
145
|
+
const ctx = HardhatContext.getHardhatContext();
|
|
146
|
+
const extenderManager = ctx.extendersManager;
|
|
147
|
+
extenderManager.addArtifactsExtender(artifactsExtender);
|
|
148
|
+
}
|
|
149
|
+
|
|
138
150
|
// NOTE: This is experimental and will be removed. Please contact our team
|
|
139
151
|
// if you are planning to use it.
|
|
140
152
|
export function experimentalAddHardhatNetworkMessageTraceHook(
|
|
@@ -408,9 +408,10 @@ function resolveCompiler(compiler: SolcUserConfig): SolcConfig {
|
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
for (const output of outputs) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
411
|
+
const includesOutput: boolean =
|
|
412
|
+
resolved.settings.outputSelection[file][contract].includes(output);
|
|
413
|
+
|
|
414
|
+
if (!includesOutput) {
|
|
414
415
|
resolved.settings.outputSelection[file][contract].push(output);
|
|
415
416
|
}
|
|
416
417
|
}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
import { EnvironmentExtender } from "../../../types";
|
|
1
|
+
import { ArtifactsExtender, EnvironmentExtender } from "../../../types";
|
|
2
2
|
|
|
3
3
|
export class ExtenderManager {
|
|
4
|
-
private readonly
|
|
4
|
+
private readonly _environmentExtenders: EnvironmentExtender[] = [];
|
|
5
|
+
private readonly _artifactsExtenders: ArtifactsExtender[] = [];
|
|
5
6
|
|
|
6
|
-
public
|
|
7
|
-
this.
|
|
7
|
+
public addEnvironmentExtender(environmentExtender: EnvironmentExtender) {
|
|
8
|
+
this._environmentExtenders.push(environmentExtender);
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
public
|
|
11
|
-
|
|
11
|
+
public addArtifactsExtender(artifactsExtender: ArtifactsExtender) {
|
|
12
|
+
this._artifactsExtenders.push(artifactsExtender);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public getEnvironmentExtenders(): EnvironmentExtender[] {
|
|
16
|
+
return this._environmentExtenders;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public getArtifactsExtenders(): ArtifactsExtender[] {
|
|
20
|
+
return this._artifactsExtenders;
|
|
12
21
|
}
|
|
13
22
|
}
|