1
1
import type { HardhatUserConfig } from "../../../config.js" ;
2
2
import type {
3
3
HardhatConfig ,
4
+ MultiVersionSolidityUserConfig ,
5
+ SingleVersionSolidityUserConfig ,
6
+ SolcConfig ,
7
+ SolcUserConfig ,
4
8
SolidityBuildProfileConfig ,
5
9
SolidityConfig ,
6
10
SolidityUserConfig ,
7
11
} from "../../../types/config.js" ;
8
12
import type { HardhatUserConfigValidationError } from "../../../types/hooks.js" ;
9
13
10
- import { isObject } from "@nomicfoundation/hardhat-utils/lang" ;
14
+ import os from "node:os" ;
15
+
16
+ import { deepMerge , isObject } from "@nomicfoundation/hardhat-utils/lang" ;
11
17
import { resolveFromRoot } from "@nomicfoundation/hardhat-utils/path" ;
12
18
import {
13
19
conditionalUnionType ,
@@ -213,126 +219,57 @@ function resolveSolidityConfig(
213
219
solidityConfig = [ solidityConfig ] ;
214
220
}
215
221
222
+ // user provided an array of versions or a single version
216
223
if ( Array . isArray ( solidityConfig ) ) {
217
- return {
218
- profiles : {
219
- default : {
220
- compilers : solidityConfig . map ( ( version ) => ( {
221
- version,
222
- settings : { } ,
223
- } ) ) ,
224
- overrides : { } ,
225
- isolated : false ,
226
- preferWasm : false ,
227
- } ,
228
- } ,
229
- npmFilesToBuild : [ ] ,
224
+ const defaultSolidityConfig = {
225
+ compilers : solidityConfig . map ( ( version ) => ( { version } ) ) ,
230
226
} ;
231
- }
232
-
233
- if ( "version" in solidityConfig ) {
234
227
return {
235
228
profiles : {
236
- default : {
237
- compilers : [
238
- {
239
- version : solidityConfig . version ,
240
- settings : solidityConfig . settings ?? { } ,
241
- } ,
242
- ] ,
243
- overrides : { } ,
244
- isolated : solidityConfig . isolated ?? false ,
245
- preferWasm : solidityConfig . preferWasm ?? false ,
246
- } ,
229
+ default : resolveBuildProfileConfig ( defaultSolidityConfig ) ,
230
+ production : resolveBuildProfileConfig (
231
+ copyFromDefault ( defaultSolidityConfig ) ,
232
+ true ,
233
+ ) ,
247
234
} ,
248
- npmFilesToBuild : solidityConfig . npmFilesToBuild ?? [ ] ,
235
+ npmFilesToBuild : [ ] ,
249
236
} ;
250
237
}
251
238
252
- if ( "compilers" in solidityConfig ) {
239
+ // user provided a single version config or a multi version config
240
+ if ( "version" in solidityConfig || "compilers" in solidityConfig ) {
253
241
return {
254
242
profiles : {
255
- default : {
256
- preferWasm : solidityConfig . preferWasm ?? false ,
257
- compilers : solidityConfig . compilers . map ( ( compiler ) => ( {
258
- version : compiler . version ,
259
- settings : compiler . settings ?? { } ,
260
- } ) ) ,
261
- overrides : Object . fromEntries (
262
- Object . entries ( solidityConfig . overrides ?? { } ) . map (
263
- ( [ userSourceName , override ] ) => {
264
- return [
265
- userSourceName ,
266
- {
267
- version : override . version ,
268
- settings : override . settings ?? { } ,
269
- } ,
270
- ] ;
271
- } ,
272
- ) ,
273
- ) ,
274
- isolated : solidityConfig . isolated ?? false ,
275
- } ,
243
+ default : resolveBuildProfileConfig ( solidityConfig ) ,
244
+ production : resolveBuildProfileConfig (
245
+ copyFromDefault ( solidityConfig ) ,
246
+ true ,
247
+ ) ,
276
248
} ,
277
249
npmFilesToBuild : solidityConfig . npmFilesToBuild ?? [ ] ,
278
250
} ;
279
251
}
280
252
253
+ // user provided a build profiles config
281
254
const profiles : Record < string , SolidityBuildProfileConfig > = { } ;
282
255
283
- // TODO: Merge the profiles
284
256
for ( const [ profileName , profile ] of Object . entries (
285
257
solidityConfig . profiles ,
286
258
) ) {
287
- const isolated = profile . isolated ?? profileName === "production" ;
288
- const preferWasm = profile . preferWasm ?? profileName === "production" ;
289
-
290
- if ( "version" in profile ) {
291
- profiles [ profileName ] = {
292
- compilers : [
293
- {
294
- version : profile . version ,
295
- settings : profile . settings ?? { } ,
296
- } ,
297
- ] ,
298
- overrides : { } ,
299
- isolated,
300
- preferWasm,
301
- } ;
302
- continue ;
303
- }
304
-
305
- profiles [ profileName ] = {
306
- compilers : profile . compilers . map ( ( compiler ) => ( {
307
- version : compiler . version ,
308
- settings : compiler . settings ?? { } ,
309
- } ) ) ,
310
- overrides : Object . fromEntries (
311
- Object . entries ( profile . overrides ?? { } ) . map (
312
- ( [ userSourceName , override ] ) => {
313
- return [
314
- userSourceName ,
315
- {
316
- version : override . version ,
317
- settings : override . settings ?? { } ,
318
- } ,
319
- ] ;
320
- } ,
321
- ) ,
322
- ) ,
323
- isolated,
324
- preferWasm,
325
- } ;
259
+ profiles [ profileName ] = resolveBuildProfileConfig (
260
+ profile ,
261
+ profileName === "production" ,
262
+ ) ;
326
263
}
327
264
328
- // This will generate default build profiles (e.g. production) when they are not specified in the config, cloning from 'default', which is always present
265
+ // This will generate default build profiles (e.g. production) when they are
266
+ // not specified in the config, cloning from 'default', which is always present
329
267
for ( const profile of DEFAULT_BUILD_PROFILES ) {
330
268
if ( ! ( profile in profiles ) ) {
331
- profiles [ profile ] = {
332
- ...profiles . default ,
333
- isolated : profile === "production" ,
334
- preferWasm : profile === "production" ,
335
- } ;
269
+ profiles [ profile ] = resolveBuildProfileConfig (
270
+ copyFromDefault ( solidityConfig . profiles . default ) ,
271
+ profile === "production" ,
272
+ ) ;
336
273
}
337
274
}
338
275
@@ -341,3 +278,99 @@ function resolveSolidityConfig(
341
278
npmFilesToBuild : solidityConfig . npmFilesToBuild ?? [ ] ,
342
279
} ;
343
280
}
281
+
282
+ function resolveBuildProfileConfig (
283
+ solidityConfig :
284
+ | SingleVersionSolidityUserConfig
285
+ | MultiVersionSolidityUserConfig ,
286
+ production : boolean = false ,
287
+ ) : SolidityBuildProfileConfig {
288
+ if ( "version" in solidityConfig ) {
289
+ return {
290
+ compilers : [ resolveSolcConfig ( solidityConfig , production ) ] ,
291
+ overrides : { } ,
292
+ isolated : solidityConfig . isolated ?? production ,
293
+ preferWasm : solidityConfig . preferWasm ?? ( production && shouldUseWasm ( ) ) ,
294
+ } ;
295
+ }
296
+
297
+ return {
298
+ compilers : solidityConfig . compilers . map ( ( compiler ) =>
299
+ resolveSolcConfig ( compiler , production ) ,
300
+ ) ,
301
+ overrides : Object . fromEntries (
302
+ Object . entries ( solidityConfig . overrides ?? { } ) . map (
303
+ ( [ userSourceName , override ] ) => [
304
+ userSourceName ,
305
+ resolveSolcConfig ( override , production ) ,
306
+ ] ,
307
+ ) ,
308
+ ) ,
309
+ isolated : solidityConfig . isolated ?? production ,
310
+ preferWasm : solidityConfig . preferWasm ?? ( production && shouldUseWasm ( ) ) ,
311
+ } ;
312
+ }
313
+
314
+ function resolveSolcConfig (
315
+ solcConfig : SolcUserConfig ,
316
+ production : boolean = false ,
317
+ ) : SolcConfig {
318
+ const defaultSolcConfigSettings : SolcConfig [ "settings" ] = {
319
+ outputSelection : {
320
+ "*" : {
321
+ "" : [ "ast" ] ,
322
+ "*" : [
323
+ "abi" ,
324
+ "evm.bytecode" ,
325
+ "evm.deployedBytecode" ,
326
+ "evm.methodIdentifiers" ,
327
+ "metadata" ,
328
+ ] ,
329
+ } ,
330
+ } ,
331
+ } ;
332
+
333
+ if ( production ) {
334
+ defaultSolcConfigSettings . optimizer = {
335
+ enabled : true ,
336
+ runs : 200 ,
337
+ } ;
338
+ }
339
+
340
+ return {
341
+ version : solcConfig . version ,
342
+ settings : deepMerge ( defaultSolcConfigSettings , solcConfig . settings ?? { } ) ,
343
+ } ;
344
+ }
345
+
346
+ function copyFromDefault (
347
+ defaultSolidityConfig :
348
+ | SingleVersionSolidityUserConfig
349
+ | MultiVersionSolidityUserConfig ,
350
+ ) : SingleVersionSolidityUserConfig | MultiVersionSolidityUserConfig {
351
+ if ( "version" in defaultSolidityConfig ) {
352
+ return {
353
+ version : defaultSolidityConfig . version ,
354
+ } ;
355
+ }
356
+
357
+ return {
358
+ compilers : defaultSolidityConfig . compilers . map ( ( c ) => ( {
359
+ version : c . version ,
360
+ } ) ) ,
361
+ overrides : Object . fromEntries (
362
+ Object . entries ( defaultSolidityConfig . overrides ?? { } ) . map (
363
+ ( [ userSourceName , override ] ) => [
364
+ userSourceName ,
365
+ { version : override . version } ,
366
+ ] ,
367
+ ) ,
368
+ ) ,
369
+ } ;
370
+ }
371
+
372
+ // We use wasm builds in production to avoid using unofficial builds for deployments
373
+ // This should change once https://github.com/ethereum/solidity/issues/11351 gets resolved
374
+ export function shouldUseWasm ( ) : boolean {
375
+ return os . platform ( ) === "linux" && os . arch ( ) === "arm64" ;
376
+ }
0 commit comments