@@ -3,8 +3,6 @@ import type { LoggerConfig } from "./types/logger.js";
3
3
import type { TracingConfig } from "./types/node-types.js" ;
4
4
import type { EdrNetworkConfig } from "../../../../types/config.js" ;
5
5
import type {
6
- EthSubscription ,
7
- FailedJsonRpcResponse ,
8
6
JsonRpcResponse ,
9
7
RequestArguments ,
10
8
SuccessfulJsonRpcResponse ,
@@ -15,7 +13,6 @@ import type {
15
13
SubscriptionEvent ,
16
14
Response ,
17
15
Provider ,
18
- DebugTraceResult ,
19
16
ProviderConfig ,
20
17
} from "@ignored/edr-optimism" ;
21
18
@@ -25,25 +22,20 @@ import {
25
22
l1GenesisState ,
26
23
l1HardforkFromString ,
27
24
} from "@ignored/edr-optimism" ;
25
+ import { assertHardhatInvariant } from "@ignored/hardhat-vnext-errors" ;
28
26
import { toSeconds } from "@ignored/hardhat-vnext-utils/date" ;
27
+ import { numberToHexString } from "@ignored/hardhat-vnext-utils/hex" ;
29
28
import { deepEqual } from "@ignored/hardhat-vnext-utils/lang" ;
30
29
import debug from "debug" ;
31
30
32
- import {
33
- EDR_NETWORK_RESET_EVENT ,
34
- EDR_NETWORK_REVERT_SNAPSHOT_EVENT ,
35
- } from "../../../constants.js" ;
31
+ import { EDR_NETWORK_REVERT_SNAPSHOT_EVENT } from "../../../constants.js" ;
36
32
import { DEFAULT_HD_ACCOUNTS_CONFIG_PARAMS } from "../accounts/constants.js" ;
37
33
import { BaseProvider } from "../base-provider.js" ;
38
34
import { getJsonRpcRequest , isFailedJsonRpcResponse } from "../json-rpc.js" ;
39
35
40
36
import { getGlobalEdrContext } from "./edr-context.js" ;
41
- import {
42
- InvalidArgumentsError ,
43
- InvalidInputError ,
44
- ProviderError ,
45
- } from "./errors.js" ;
46
- import { encodeSolidityStackTrace } from "./stack-traces/stack-trace-solidity-errors.js" ;
37
+ import { InvalidArgumentsError , ProviderError } from "./errors.js" ;
38
+ import { createSolidityErrorWithStackTrace } from "./stack-traces/stack-trace-solidity-errors.js" ;
47
39
import { clientVersion } from "./utils/client-version.js" ;
48
40
import { ConsoleLogger } from "./utils/console-logger.js" ;
49
41
import {
@@ -55,6 +47,7 @@ import {
55
47
hardhatChainsToEdrChains ,
56
48
hardhatForkingConfigToEdrForkConfig ,
57
49
hardhatChainTypeToEdrChainType ,
50
+ isDebugTraceResult ,
58
51
} from "./utils/convert-to-edr.js" ;
59
52
import { printLine , replaceLastLine } from "./utils/logger.js" ;
60
53
@@ -177,27 +170,22 @@ export class EdrProvider extends BaseProvider {
177
170
super ( ) ;
178
171
179
172
this . #provider = provider ;
180
-
181
173
this . #jsonRpcRequestWrapper = jsonRpcRequestWrapper ;
182
174
}
183
175
184
- public async request ( args : RequestArguments ) : Promise < unknown > {
185
- if ( args . params !== undefined && ! Array . isArray ( args . params ) ) {
186
- // eslint-disable-next-line no-restricted-syntax -- TODO: review whether this should be a HH error
187
- throw new InvalidInputError (
188
- "Hardhat Network doesn't support JSON-RPC params sent as an object" ,
189
- ) ;
190
- }
191
-
192
- const params = args . params ?? [ ] ;
176
+ public async request (
177
+ requestArguments : RequestArguments ,
178
+ ) : Promise < SuccessfulJsonRpcResponse [ "result" ] > {
179
+ const { method, params } = requestArguments ;
193
180
194
181
const jsonRpcRequest = getJsonRpcRequest (
195
182
this . #nextRequestId++ ,
196
- args . method ,
183
+ method ,
197
184
params ,
198
185
) ;
199
186
200
187
let jsonRpcResponse : JsonRpcResponse ;
188
+
201
189
if ( this . #jsonRpcRequestWrapper !== undefined ) {
202
190
jsonRpcResponse = await this . #jsonRpcRequestWrapper(
203
191
jsonRpcRequest ,
@@ -216,12 +204,6 @@ export class EdrProvider extends BaseProvider {
216
204
jsonRpcResponse = await this . #handleEdrResponse( edrResponse ) ;
217
205
}
218
206
219
- if ( args . method === "hardhat_reset" ) {
220
- this . emit ( EDR_NETWORK_RESET_EVENT ) ;
221
- } else if ( args . method === "evm_revert" ) {
222
- this . emit ( EDR_NETWORK_REVERT_SNAPSHOT_EVENT ) ;
223
- }
224
-
225
207
// this can only happen if a wrapper doesn't call the default
226
208
// behavior as the default throws on FailedJsonRpcResponse
227
209
if ( isFailedJsonRpcResponse ( jsonRpcResponse ) ) {
@@ -235,19 +217,27 @@ export class EdrProvider extends BaseProvider {
235
217
throw error ;
236
218
}
237
219
220
+ if ( jsonRpcRequest . method === "evm_revert" ) {
221
+ this . emit ( EDR_NETWORK_REVERT_SNAPSHOT_EVENT ) ;
222
+ }
223
+
238
224
// Override EDR version string with Hardhat version string with EDR backend,
239
225
// e.g. `HardhatNetwork/2.19.0/@ignored/edr-optimism/0.2.0-dev`
240
- if ( args . method === "web3_clientVersion" ) {
241
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO
242
- return clientVersion ( jsonRpcResponse . result as string ) ;
226
+ if ( jsonRpcRequest . method === "web3_clientVersion" ) {
227
+ assertHardhatInvariant (
228
+ typeof jsonRpcResponse . result === "string" ,
229
+ "Invalid client version response" ,
230
+ ) ;
231
+ return clientVersion ( jsonRpcResponse . result ) ;
243
232
} else if (
244
- args . method === "debug_traceTransaction" ||
245
- args . method === "debug_traceCall"
233
+ jsonRpcRequest . method === "debug_traceTransaction" ||
234
+ jsonRpcRequest . method === "debug_traceCall"
246
235
) {
247
- return edrRpcDebugTraceToHardhat (
248
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO
249
- jsonRpcResponse . result as DebugTraceResult ,
236
+ assertHardhatInvariant (
237
+ isDebugTraceResult ( jsonRpcResponse . result ) ,
238
+ "Invalid debug trace response" ,
250
239
) ;
240
+ return edrRpcDebugTraceToHardhat ( jsonRpcResponse . result ) ;
251
241
} else {
252
242
return jsonRpcResponse . result ;
253
243
}
@@ -257,10 +247,6 @@ export class EdrProvider extends BaseProvider {
257
247
// TODO: what needs cleaned up?
258
248
}
259
249
260
- #isErrorResponse( response : any ) : response is FailedJsonRpcResponse {
261
- return typeof response . error !== "undefined" ;
262
- }
263
-
264
250
async #handleEdrResponse(
265
251
edrResponse : Response ,
266
252
) : Promise < SuccessfulJsonRpcResponse > {
@@ -272,7 +258,8 @@ export class EdrProvider extends BaseProvider {
272
258
jsonRpcResponse = edrResponse . data ;
273
259
}
274
260
275
- if ( this . #isErrorResponse( jsonRpcResponse ) ) {
261
+ if ( isFailedJsonRpcResponse ( jsonRpcResponse ) ) {
262
+ const responseError = jsonRpcResponse . error ;
276
263
let error ;
277
264
278
265
let stackTrace : SolidityStackTrace | null = null ;
@@ -283,66 +270,61 @@ export class EdrProvider extends BaseProvider {
283
270
}
284
271
285
272
if ( stackTrace !== null ) {
286
- error = encodeSolidityStackTrace (
287
- jsonRpcResponse . error . message ,
273
+ // Pass data and transaction hash from the original error
274
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
275
+ -- If we have a stack trace, we know that the json rpc response data
276
+ is an object with the data and transactionHash fields */
277
+ const responseErrorData = responseError . data as {
278
+ data ?: string ;
279
+ transactionHash ?: string ;
280
+ } ;
281
+
282
+ error = createSolidityErrorWithStackTrace (
283
+ responseError . message ,
288
284
stackTrace ,
285
+ responseErrorData ?. data ,
286
+ responseErrorData ?. transactionHash ,
289
287
) ;
290
-
291
- // Pass data and transaction hash from the original error
292
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO: can we improve this `any
293
- ( error as any ) . data =
294
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO: can we improve this `any
295
- ( jsonRpcResponse as any ) . error . data ?. data ?? undefined ;
296
-
297
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO: can we improve this `any`
298
- ( error as any ) . transactionHash =
299
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO: this really needs fixed
300
- ( jsonRpcResponse as any ) . error . data ?. transactionHash ?? undefined ;
301
288
} else {
302
- if ( jsonRpcResponse . error . code === InvalidArgumentsError . CODE ) {
303
- error = new InvalidArgumentsError ( jsonRpcResponse . error . message ) ;
304
- } else {
305
- error = new ProviderError (
306
- jsonRpcResponse . error . message ,
307
- jsonRpcResponse . error . code ,
308
- ) ;
309
- }
310
- error . data = jsonRpcResponse . error . data ;
289
+ error =
290
+ responseError . code === InvalidArgumentsError . CODE
291
+ ? new InvalidArgumentsError ( responseError . message )
292
+ : new ProviderError ( responseError . message , responseError . code ) ;
293
+ error . data = responseError . data ;
311
294
}
312
295
313
- // eslint-disable-next-line no-restricted-syntax -- we may throw non-Hardaht errors inside of an EthereumProvider
296
+ /* eslint-disable-next-line no-restricted-syntax -- we may throw
297
+ non-Hardaht errors inside of an EthereumProvider */
314
298
throw error ;
315
299
}
316
300
317
301
return jsonRpcResponse ;
318
302
}
319
303
320
304
public onSubscriptionEvent ( event : SubscriptionEvent ) : void {
321
- const subscription = `0x ${ event . filterId . toString ( 16 ) } ` ;
305
+ const subscription = numberToHexString ( event . filterId ) ;
322
306
const results = Array . isArray ( event . result ) ? event . result : [ event . result ] ;
323
307
for ( const result of results ) {
324
308
this . #emitLegacySubscriptionEvent( subscription , result ) ;
325
309
this . #emitEip1193SubscriptionEvent( subscription , result ) ;
326
310
}
327
311
}
328
312
329
- #emitLegacySubscriptionEvent( subscription : string , result : any ) {
313
+ #emitLegacySubscriptionEvent( subscription : string , result : unknown ) {
330
314
this . emit ( "notification" , {
331
315
subscription,
332
316
result,
333
317
} ) ;
334
318
}
335
319
336
320
#emitEip1193SubscriptionEvent( subscription : string , result : unknown ) {
337
- const message : EthSubscription = {
321
+ this . emit ( " message" , {
338
322
type : "eth_subscription" ,
339
323
data : {
340
324
subscription,
341
325
result,
342
326
} ,
343
- } ;
344
-
345
- this . emit ( "message" , message ) ;
327
+ } ) ;
346
328
}
347
329
}
348
330
0 commit comments