@nomicfoundation/edr 0.12.0-next.2 → 0.12.0-next.4

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/index.d.ts CHANGED
@@ -812,14 +812,36 @@ export interface PathPermission {
812
812
  /** The targeted path guarded by the permission */
813
813
  path: string
814
814
  }
815
- /** Determines the status of file system access */
815
+ /**
816
+ * Determines the level of file system access for the given path.
817
+ *
818
+ * Exact path matching is used for file permissions. Prefix matching is used
819
+ * for directory permissions.
820
+ *
821
+ * Giving write access to configuration files, source files or executables
822
+ * in a project is considered dangerous, because it can be used by malicious
823
+ * Solidity dependencies to escape the EVM sandbox. It is therefore
824
+ * recommended to give write access to specific safe files only. If write
825
+ * access to a directory is needed, please make sure that it doesn't contain
826
+ * configuration files, source files or executables neither in the top level
827
+ * directory, nor in any subdirectories.
828
+ */
816
829
  export enum FsAccessPermission {
817
- /** FS access is allowed with `read` + `write` permission */
818
- ReadWrite = 0,
819
- /** Only reading is allowed */
820
- Read = 1,
821
- /** Only writing is allowed */
822
- Write = 2
830
+ /** Allows reading and writing the file */
831
+ ReadWriteFile = 0,
832
+ /** Only allows reading the file */
833
+ ReadFile = 1,
834
+ /** Only allows writing the file */
835
+ WriteFile = 2,
836
+ /**
837
+ * Allows reading and writing all files in the directory and its
838
+ * subdirectories
839
+ */
840
+ DangerouslyReadWriteDirectory = 3,
841
+ /** Allows reading all files in the directory and its subdirectories */
842
+ ReadDirectory = 4,
843
+ /** Allows writing all files in the directory and its subdirectories */
844
+ DangerouslyWriteDirectory = 5
823
845
  }
824
846
  export interface AddressLabel {
825
847
  /** The address to label */
@@ -1115,7 +1137,8 @@ export enum StackTraceEntryType {
1115
1137
  UNMAPPED_SOLC_0_6_3_REVERT_ERROR = 20,
1116
1138
  CONTRACT_TOO_LARGE_ERROR = 21,
1117
1139
  INTERNAL_FUNCTION_CALLSTACK_ENTRY = 22,
1118
- CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR = 23
1140
+ CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR = 23,
1141
+ CHEATCODE_ERROR = 24
1119
1142
  }
1120
1143
  export declare function stackTraceEntryTypeToString(val: StackTraceEntryType): string
1121
1144
  export const FALLBACK_FUNCTION_NAME: string
@@ -1245,6 +1268,11 @@ export interface ContractCallRunOutOfGasError {
1245
1268
  type: StackTraceEntryType.CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR
1246
1269
  sourceReference?: SourceReference
1247
1270
  }
1271
+ export interface CheatcodeErrorStackTraceEntry {
1272
+ type: StackTraceEntryType.CHEATCODE_ERROR
1273
+ message: string
1274
+ sourceReference: SourceReference
1275
+ }
1248
1276
  export interface TracingMessage {
1249
1277
  /** Sender address */
1250
1278
  readonly caller: Uint8Array
@@ -1336,6 +1364,12 @@ export declare class Response {
1336
1364
  }
1337
1365
  /** A JSON-RPC provider for Ethereum. */
1338
1366
  export declare class Provider {
1367
+ /**
1368
+ *Adds a compilation result to the instance.
1369
+ *
1370
+ *For internal use only. Support for this method may be removed in the future.
1371
+ */
1372
+ addCompilationResult(solcVersion: string, compilerInput: any, compilerOutput: any): Promise<boolean>
1339
1373
  /**Handles a JSON-RPC request and returns a JSON-RPC response. */
1340
1374
  handleRequest(request: string): Promise<Response>
1341
1375
  setCallOverrideCallback(callOverrideCallback: (contract_address: ArrayBuffer, data: ArrayBuffer) => Promise<CallOverrideResult | undefined>): Promise<void>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomicfoundation/edr",
3
- "version": "0.12.0-next.2",
3
+ "version": "0.12.0-next.4",
4
4
  "devDependencies": {
5
5
  "@napi-rs/cli": "^2.18.4",
6
6
  "@nomicfoundation/ethereumjs-util": "^9.0.4",
@@ -13,6 +13,7 @@
13
13
  "@typescript-eslint/parser": "5.61.0",
14
14
  "chai": "^4.3.6",
15
15
  "chai-as-promised": "^7.1.1",
16
+ "chalk": "^2.4.2",
16
17
  "eslint": "^8.44.0",
17
18
  "eslint-config-prettier": "9.1.0",
18
19
  "eslint-plugin-import": "2.27.5",
@@ -58,13 +59,13 @@
58
59
  "repository": "NomicFoundation/edr.git",
59
60
  "types": "index.d.ts",
60
61
  "optionalDependencies": {
61
- "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.2",
62
- "@nomicfoundation/edr-darwin-x64": "0.12.0-next.2",
63
- "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.2",
64
- "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.2",
65
- "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.2",
66
- "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.2",
67
- "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.2"
62
+ "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.4",
63
+ "@nomicfoundation/edr-darwin-x64": "0.12.0-next.4",
64
+ "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.4",
65
+ "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.4",
66
+ "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.4",
67
+ "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.4",
68
+ "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.4"
68
69
  },
69
70
  "scripts": {
70
71
  "artifacts": "napi artifacts",
@@ -82,7 +83,7 @@
82
83
  "pretest": "pnpm build:dev",
83
84
  "prettier": "prettier --check \"test/**.ts\"",
84
85
  "test": "node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/*.ts\"",
85
- "testNoBuild": "node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(mock)}.ts\"",
86
+ "testNoBuild": "node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(logs|mock)}.ts\"",
86
87
  "universal": "napi universal",
87
88
  "version": "napi version"
88
89
  }
@@ -5,9 +5,9 @@ use edr_generic::GenericChainSpec;
5
5
  use edr_napi_core::{
6
6
  logger::{self, Logger},
7
7
  provider::{self, ProviderBuilder, SyncProviderFactory},
8
- spec::SyncNapiSpec as _,
9
8
  subscription,
10
9
  };
10
+ use edr_provider::time::CurrentTime;
11
11
  use edr_solidity::contract_decoder::ContractDecoder;
12
12
  use napi_derive::napi;
13
13
 
@@ -24,7 +24,10 @@ impl SyncProviderFactory for GenericChainProviderFactory {
24
24
  subscription_config: subscription::Config,
25
25
  contract_decoder: Arc<ContractDecoder>,
26
26
  ) -> napi::Result<Box<dyn provider::Builder>> {
27
- let logger = Logger::<GenericChainSpec>::new(logger_config, Arc::clone(&contract_decoder))?;
27
+ let logger = Logger::<GenericChainSpec, CurrentTime>::new(
28
+ logger_config,
29
+ Arc::clone(&contract_decoder),
30
+ )?;
28
31
 
29
32
  let provider_config =
30
33
  edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
@@ -42,7 +45,7 @@ impl SyncProviderFactory for GenericChainProviderFactory {
42
45
  }
43
46
 
44
47
  #[napi]
45
- pub const GENERIC_CHAIN_TYPE: &str = GenericChainSpec::CHAIN_TYPE;
48
+ pub const GENERIC_CHAIN_TYPE: &str = edr_generic::CHAIN_TYPE;
46
49
 
47
50
  #[napi(catch_unwind)]
48
51
  pub fn generic_chain_provider_factory() -> ProviderFactory {
package/src/chains/l1.rs CHANGED
@@ -8,9 +8,9 @@ use edr_evm::eips::{
8
8
  use edr_napi_core::{
9
9
  logger::Logger,
10
10
  provider::{self, ProviderBuilder, SyncProviderFactory},
11
- spec::SyncNapiSpec as _,
12
11
  subscription,
13
12
  };
13
+ use edr_provider::time::CurrentTime;
14
14
  use edr_solidity::contract_decoder::ContractDecoder;
15
15
  use napi::bindgen_prelude::{BigInt, Uint8Array};
16
16
  use napi_derive::napi;
@@ -28,7 +28,8 @@ impl SyncProviderFactory for L1ProviderFactory {
28
28
  subscription_config: edr_napi_core::subscription::Config,
29
29
  contract_decoder: Arc<ContractDecoder>,
30
30
  ) -> napi::Result<Box<dyn provider::Builder>> {
31
- let logger = Logger::<L1ChainSpec>::new(logger_config, Arc::clone(&contract_decoder))?;
31
+ let logger =
32
+ Logger::<L1ChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
32
33
 
33
34
  let provider_config =
34
35
  edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
@@ -46,7 +47,7 @@ impl SyncProviderFactory for L1ProviderFactory {
46
47
  }
47
48
 
48
49
  #[napi]
49
- pub const L1_CHAIN_TYPE: &str = L1ChainSpec::CHAIN_TYPE;
50
+ pub const L1_CHAIN_TYPE: &str = edr_eth::l1::CHAIN_TYPE;
50
51
 
51
52
  #[napi(catch_unwind)]
52
53
  pub fn l1_genesis_state(hardfork: SpecId) -> Vec<AccountOverride> {
package/src/chains/op.rs CHANGED
@@ -7,6 +7,7 @@ use edr_napi_core::{
7
7
  subscription,
8
8
  };
9
9
  use edr_op::{predeploys::GAS_PRICE_ORACLE_ADDRESS, OpChainSpec, OpSpecId};
10
+ use edr_provider::time::CurrentTime;
10
11
  use edr_solidity::contract_decoder::ContractDecoder;
11
12
  use napi::bindgen_prelude::{BigInt, Uint8Array};
12
13
  use napi_derive::napi;
@@ -27,7 +28,8 @@ impl SyncProviderFactory for OpProviderFactory {
27
28
  subscription_config: subscription::Config,
28
29
  contract_decoder: Arc<ContractDecoder>,
29
30
  ) -> napi::Result<Box<dyn provider::Builder>> {
30
- let logger = Logger::<OpChainSpec>::new(logger_config, Arc::clone(&contract_decoder))?;
31
+ let logger =
32
+ Logger::<OpChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
31
33
 
32
34
  let provider_config = edr_provider::ProviderConfig::<OpSpecId>::try_from(provider_config)?;
33
35
 
package/src/config.rs CHANGED
@@ -385,10 +385,10 @@ impl ObservabilityConfig {
385
385
  Ok(())
386
386
  });
387
387
 
388
- let () = receiver.recv().expect("Receive can only fail if the channel is closed")?;
389
-
390
388
  assert_eq!(status, napi::Status::Ok);
391
389
 
390
+ let () = receiver.recv().expect("Receive can only fail if the channel is closed")?;
391
+
392
392
  Ok(())
393
393
  });
394
394
 
package/src/lib.rs CHANGED
@@ -26,7 +26,7 @@ pub mod log;
26
26
  pub mod logger;
27
27
  /// Types for mocking provider behavior.
28
28
  #[cfg(feature = "test-mock")]
29
- mod mock;
29
+ pub mod mock;
30
30
  /// Types for precompiles.
31
31
  pub mod precompile;
32
32
  /// Types for Ethereum RPC providers.
package/src/logger.rs CHANGED
@@ -65,7 +65,9 @@ impl LoggerConfig {
65
65
  );
66
66
  assert_eq!(status, Status::Ok);
67
67
 
68
- receiver.recv().unwrap()
68
+ receiver
69
+ .recv()
70
+ .expect("Receive can only fail if the channel is closed")
69
71
  });
70
72
 
71
73
  let mut print_line_callback: ThreadsafeFunction<_, ErrorStrategy::Fatal> = self
@@ -0,0 +1,142 @@
1
+ use std::sync::Arc;
2
+
3
+ use edr_eth::{spec::ChainSpec, B256};
4
+ use edr_evm::spec::RuntimeSpec;
5
+ use edr_generic::GenericChainSpec;
6
+ use edr_napi_core::logger::Logger;
7
+ use edr_rpc_eth::RpcSpec;
8
+ use edr_solidity::contract_decoder::ContractDecoder;
9
+ use napi::{bindgen_prelude::BigInt, tokio::runtime, Env, JsObject};
10
+ use napi_derive::napi;
11
+
12
+ use crate::{
13
+ cast::TryCast as _,
14
+ config::{ProviderConfig, TracingConfigWithBuffers},
15
+ logger::LoggerConfig,
16
+ provider::Provider,
17
+ subscription::SubscriptionConfig,
18
+ };
19
+
20
+ #[napi]
21
+ pub struct MockTime {
22
+ inner: Arc<edr_provider::time::MockTime>,
23
+ }
24
+
25
+ #[napi]
26
+ impl MockTime {
27
+ #[doc = "Creates a new instance of `MockTime` with the current time."]
28
+ #[napi(factory, catch_unwind)]
29
+ pub fn now() -> Self {
30
+ Self {
31
+ inner: Arc::new(edr_provider::time::MockTime::now()),
32
+ }
33
+ }
34
+
35
+ #[doc = "Adds the specified number of seconds to the current time."]
36
+ #[napi(catch_unwind)]
37
+ pub fn add_seconds(&self, seconds: BigInt) -> napi::Result<()> {
38
+ let seconds = seconds.try_cast()?;
39
+
40
+ self.inner.add_seconds(seconds);
41
+ Ok(())
42
+ }
43
+ }
44
+
45
+ #[doc = "Creates a provider with a mock timer."]
46
+ #[doc = "For testing purposes."]
47
+ #[napi(catch_unwind, ts_return_type = "Promise<Provider>")]
48
+ pub fn create_provider_with_mock_timer(
49
+ env: Env,
50
+ provider_config: ProviderConfig,
51
+ logger_config: LoggerConfig,
52
+ subscription_config: SubscriptionConfig,
53
+ tracing_config: TracingConfigWithBuffers,
54
+ time: &MockTime,
55
+ ) -> napi::Result<JsObject> {
56
+ let (deferred, promise) = env.create_deferred()?;
57
+
58
+ macro_rules! try_or_reject_promise {
59
+ ($expr:expr) => {
60
+ match $expr {
61
+ Ok(value) => value,
62
+ Err(error) => {
63
+ deferred.reject(error);
64
+ return Ok(promise);
65
+ }
66
+ }
67
+ };
68
+ }
69
+
70
+ let runtime = runtime::Handle::current();
71
+ let provider_config = try_or_reject_promise!(provider_config.resolve(&env, runtime.clone()));
72
+
73
+ let logger_config = try_or_reject_promise!(logger_config.resolve(&env));
74
+
75
+ // TODO: https://github.com/NomicFoundation/edr/issues/760
76
+ let build_info_config = try_or_reject_promise!(
77
+ edr_solidity::artifacts::BuildInfoConfig::parse_from_buffers(
78
+ (&edr_napi_core::solidity::config::TracingConfigWithBuffers::from(tracing_config))
79
+ .into(),
80
+ )
81
+ .map_err(|error| napi::Error::from_reason(error.to_string()))
82
+ );
83
+
84
+ let contract_decoder = try_or_reject_promise!(ContractDecoder::new(&build_info_config)
85
+ .map_or_else(
86
+ |error| Err(napi::Error::from_reason(error.to_string())),
87
+ |contract_decoder| Ok(Arc::new(contract_decoder))
88
+ ));
89
+
90
+ let subscription_config = edr_napi_core::subscription::Config::from(subscription_config);
91
+ let subscription_callback = try_or_reject_promise!(edr_napi_core::subscription::Callback::new(
92
+ &env,
93
+ subscription_config.subscription_callback,
94
+ ));
95
+
96
+ let logger = try_or_reject_promise!(Logger::<
97
+ GenericChainSpec,
98
+ Arc<edr_provider::time::MockTime>,
99
+ >::new(logger_config, Arc::clone(&contract_decoder),));
100
+
101
+ let provider_config = try_or_reject_promise!(
102
+ edr_provider::ProviderConfig::<edr_eth::l1::SpecId>::try_from(provider_config)
103
+ );
104
+
105
+ let timer = Arc::clone(&time.inner);
106
+
107
+ runtime.clone().spawn_blocking(move || {
108
+ let result =
109
+ edr_provider::Provider::<GenericChainSpec, Arc<edr_provider::time::MockTime>>::new(
110
+ runtime.clone(),
111
+ Box::new(logger),
112
+ Box::new(move |event| {
113
+ let event = edr_napi_core::subscription::SubscriptionEvent::new::<
114
+ <GenericChainSpec as RuntimeSpec>::Block,
115
+ <GenericChainSpec as RpcSpec>::RpcBlock<B256>,
116
+ <GenericChainSpec as ChainSpec>::SignedTransaction,
117
+ >(event);
118
+
119
+ subscription_callback.call(event);
120
+ }),
121
+ provider_config,
122
+ contract_decoder.clone(),
123
+ timer,
124
+ )
125
+ .map_or_else(
126
+ |error| Err(napi::Error::from_reason(error.to_string())),
127
+ |provider| {
128
+ Ok(Provider::new(
129
+ Arc::new(provider),
130
+ runtime,
131
+ contract_decoder,
132
+ #[cfg(feature = "scenarios")]
133
+ None,
134
+ ))
135
+ },
136
+ );
137
+
138
+ deferred.resolve(|_env| result);
139
+ });
140
+
141
+ Ok(promise)
142
+ }
package/src/mock.rs CHANGED
@@ -1,3 +1,5 @@
1
+ pub mod time;
2
+
1
3
  use std::sync::Arc;
2
4
 
3
5
  use edr_napi_core::provider::SyncProvider;
@@ -20,6 +22,15 @@ impl MockProvider {
20
22
  }
21
23
 
22
24
  impl SyncProvider for MockProvider {
25
+ fn add_compilation_result(
26
+ &self,
27
+ _solc_version: String,
28
+ _compiler_input: edr_solidity::artifacts::CompilerInput,
29
+ _compiler_output: edr_solidity::artifacts::CompilerOutput,
30
+ ) -> napi::Result<bool> {
31
+ Ok(false) // Mock provider does not handle compilation results
32
+ }
33
+
23
34
  fn handle_request(
24
35
  &self,
25
36
  _request: String,
package/src/provider.rs CHANGED
@@ -45,6 +45,32 @@ impl Provider {
45
45
 
46
46
  #[napi]
47
47
  impl Provider {
48
+ #[doc = "Adds a compilation result to the instance."]
49
+ #[doc = ""]
50
+ #[doc = "For internal use only. Support for this method may be removed in the future."]
51
+ #[napi(catch_unwind)]
52
+ pub async fn add_compilation_result(
53
+ &self,
54
+ solc_version: String,
55
+ compiler_input: serde_json::Value,
56
+ compiler_output: serde_json::Value,
57
+ ) -> napi::Result<bool> {
58
+ let provider = self.provider.clone();
59
+
60
+ self.runtime
61
+ .spawn_blocking(move || {
62
+ let compiler_input = serde_json::from_value(compiler_input)
63
+ .map_err(|error| napi::Error::from_reason(error.to_string()))?;
64
+
65
+ let compiler_output = serde_json::from_value(compiler_output)
66
+ .map_err(|error| napi::Error::from_reason(error.to_string()))?;
67
+
68
+ provider.add_compilation_result(solc_version, compiler_input, compiler_output)
69
+ })
70
+ .await
71
+ .map_err(|error| napi::Error::new(Status::GenericFailure, error.to_string()))?
72
+ }
73
+
48
74
  #[doc = "Handles a JSON-RPC request and returns a JSON-RPC response."]
49
75
  #[napi(catch_unwind)]
50
76
  pub async fn handle_request(&self, request: String) -> napi::Result<Response> {
@@ -657,24 +657,55 @@ impl From<PathPermission> for foundry_cheatcodes::PathPermission {
657
657
  }
658
658
  }
659
659
 
660
- /// Determines the status of file system access
660
+ /**
661
+ * Determines the level of file system access for the given path.
662
+ *
663
+ * Exact path matching is used for file permissions. Prefix matching is used
664
+ * for directory permissions.
665
+ *
666
+ * Giving write access to configuration files, source files or executables
667
+ * in a project is considered dangerous, because it can be used by malicious
668
+ * Solidity dependencies to escape the EVM sandbox. It is therefore
669
+ * recommended to give write access to specific safe files only. If write
670
+ * access to a directory is needed, please make sure that it doesn't contain
671
+ * configuration files, source files or executables neither in the top level
672
+ * directory, nor in any subdirectories.
673
+ */
661
674
  #[napi]
662
675
  #[derive(Debug, serde::Serialize)]
663
676
  pub enum FsAccessPermission {
664
- /// FS access is allowed with `read` + `write` permission
665
- ReadWrite,
666
- /// Only reading is allowed
667
- Read,
668
- /// Only writing is allowed
669
- Write,
677
+ /// Allows reading and writing the file
678
+ ReadWriteFile,
679
+ /// Only allows reading the file
680
+ ReadFile,
681
+ /// Only allows writing the file
682
+ WriteFile,
683
+ /// Allows reading and writing all files in the directory and its
684
+ /// subdirectories
685
+ DangerouslyReadWriteDirectory,
686
+ /// Allows reading all files in the directory and its subdirectories
687
+ ReadDirectory,
688
+ /// Allows writing all files in the directory and its subdirectories
689
+ DangerouslyWriteDirectory,
670
690
  }
671
691
 
672
692
  impl From<FsAccessPermission> for foundry_cheatcodes::FsAccessPermission {
673
693
  fn from(value: FsAccessPermission) -> Self {
674
694
  match value {
675
- FsAccessPermission::ReadWrite => foundry_cheatcodes::FsAccessPermission::ReadWrite,
676
- FsAccessPermission::Read => foundry_cheatcodes::FsAccessPermission::Read,
677
- FsAccessPermission::Write => foundry_cheatcodes::FsAccessPermission::Write,
695
+ FsAccessPermission::ReadWriteFile => {
696
+ foundry_cheatcodes::FsAccessPermission::ReadWriteFile
697
+ }
698
+ FsAccessPermission::ReadFile => foundry_cheatcodes::FsAccessPermission::ReadFile,
699
+ FsAccessPermission::WriteFile => foundry_cheatcodes::FsAccessPermission::WriteFile,
700
+ FsAccessPermission::DangerouslyReadWriteDirectory => {
701
+ foundry_cheatcodes::FsAccessPermission::DangerouslyReadWriteDirectory
702
+ }
703
+ FsAccessPermission::ReadDirectory => {
704
+ foundry_cheatcodes::FsAccessPermission::ReadDirectory
705
+ }
706
+ FsAccessPermission::DangerouslyWriteDirectory => {
707
+ foundry_cheatcodes::FsAccessPermission::DangerouslyWriteDirectory
708
+ }
678
709
  }
679
710
  }
680
711
  }
@@ -1,6 +1,6 @@
1
1
  //! Port of `hardhat-network/stack-traces/debug.ts` from Hardhat.
2
2
 
3
- use napi::bindgen_prelude::Either24;
3
+ use napi::bindgen_prelude::Either25;
4
4
  use napi_derive::napi;
5
5
 
6
6
  use super::solidity_stack_trace::{RevertErrorStackTraceEntry, SolidityStackTrace};
@@ -11,31 +11,32 @@ fn print_stack_trace(trace: SolidityStackTrace) -> napi::Result<()> {
11
11
  let entry_values = trace
12
12
  .into_iter()
13
13
  .map(|entry| match entry {
14
- Either24::A(entry) => serde_json::to_value(entry),
15
- Either24::B(entry) => serde_json::to_value(entry),
16
- Either24::C(entry) => serde_json::to_value(entry),
17
- Either24::D(entry) => serde_json::to_value(entry),
18
- Either24::F(entry) => serde_json::to_value(entry),
19
- Either24::G(entry) => serde_json::to_value(entry),
20
- Either24::H(entry) => serde_json::to_value(entry),
21
- Either24::I(entry) => serde_json::to_value(entry),
22
- Either24::J(entry) => serde_json::to_value(entry),
23
- Either24::K(entry) => serde_json::to_value(entry),
24
- Either24::L(entry) => serde_json::to_value(entry),
25
- Either24::M(entry) => serde_json::to_value(entry),
26
- Either24::N(entry) => serde_json::to_value(entry),
27
- Either24::O(entry) => serde_json::to_value(entry),
28
- Either24::P(entry) => serde_json::to_value(entry),
29
- Either24::Q(entry) => serde_json::to_value(entry),
30
- Either24::R(entry) => serde_json::to_value(entry),
31
- Either24::S(entry) => serde_json::to_value(entry),
32
- Either24::T(entry) => serde_json::to_value(entry),
33
- Either24::U(entry) => serde_json::to_value(entry),
34
- Either24::V(entry) => serde_json::to_value(entry),
35
- Either24::W(entry) => serde_json::to_value(entry),
36
- Either24::X(entry) => serde_json::to_value(entry),
14
+ Either25::A(entry) => serde_json::to_value(entry),
15
+ Either25::B(entry) => serde_json::to_value(entry),
16
+ Either25::C(entry) => serde_json::to_value(entry),
17
+ Either25::D(entry) => serde_json::to_value(entry),
18
+ Either25::F(entry) => serde_json::to_value(entry),
19
+ Either25::G(entry) => serde_json::to_value(entry),
20
+ Either25::H(entry) => serde_json::to_value(entry),
21
+ Either25::I(entry) => serde_json::to_value(entry),
22
+ Either25::J(entry) => serde_json::to_value(entry),
23
+ Either25::K(entry) => serde_json::to_value(entry),
24
+ Either25::L(entry) => serde_json::to_value(entry),
25
+ Either25::M(entry) => serde_json::to_value(entry),
26
+ Either25::N(entry) => serde_json::to_value(entry),
27
+ Either25::O(entry) => serde_json::to_value(entry),
28
+ Either25::P(entry) => serde_json::to_value(entry),
29
+ Either25::Q(entry) => serde_json::to_value(entry),
30
+ Either25::R(entry) => serde_json::to_value(entry),
31
+ Either25::S(entry) => serde_json::to_value(entry),
32
+ Either25::T(entry) => serde_json::to_value(entry),
33
+ Either25::U(entry) => serde_json::to_value(entry),
34
+ Either25::V(entry) => serde_json::to_value(entry),
35
+ Either25::W(entry) => serde_json::to_value(entry),
36
+ Either25::X(entry) => serde_json::to_value(entry),
37
+ Either25::Y(entry) => serde_json::to_value(entry),
37
38
  // Decode the error message from the return data
38
- Either24::E(entry @ RevertErrorStackTraceEntry { .. }) => {
39
+ Either25::E(entry @ RevertErrorStackTraceEntry { .. }) => {
39
40
  use serde::de::Error;
40
41
 
41
42
  let decoded_error_msg = ReturnData::new(entry.return_data.clone())
@@ -4,7 +4,7 @@
4
4
  use std::convert::Infallible;
5
5
 
6
6
  use edr_eth::{hex, U256};
7
- use napi::bindgen_prelude::{BigInt, Either24, FromNapiValue, ToNapiValue, Uint8Array, Undefined};
7
+ use napi::bindgen_prelude::{BigInt, Either25, FromNapiValue, ToNapiValue, Uint8Array, Undefined};
8
8
  use napi_derive::napi;
9
9
  use serde::{Serialize, Serializer};
10
10
 
@@ -45,6 +45,7 @@ pub enum StackTraceEntryType {
45
45
  CONTRACT_TOO_LARGE_ERROR,
46
46
  INTERNAL_FUNCTION_CALLSTACK_ENTRY,
47
47
  CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR,
48
+ CHEATCODE_ERROR,
48
49
  }
49
50
 
50
51
  #[napi(catch_unwind)]
@@ -155,7 +156,7 @@ pub struct CallstackEntryStackTraceEntry {
155
156
 
156
157
  impl From<CallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
157
158
  fn from(val: CallstackEntryStackTraceEntry) -> Self {
158
- Either24::A(val)
159
+ Either25::A(val)
159
160
  }
160
161
  }
161
162
 
@@ -174,7 +175,7 @@ pub struct UnrecognizedCreateCallstackEntryStackTraceEntry {
174
175
 
175
176
  impl From<UnrecognizedCreateCallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
176
177
  fn from(val: UnrecognizedCreateCallstackEntryStackTraceEntry) -> Self {
177
- Either24::B(val)
178
+ Either25::B(val)
178
179
  }
179
180
  }
180
181
 
@@ -195,7 +196,7 @@ pub struct UnrecognizedContractCallstackEntryStackTraceEntry {
195
196
 
196
197
  impl From<UnrecognizedContractCallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
197
198
  fn from(val: UnrecognizedContractCallstackEntryStackTraceEntry) -> Self {
198
- Either24::C(val)
199
+ Either25::C(val)
199
200
  }
200
201
  }
201
202
 
@@ -210,7 +211,7 @@ pub struct PrecompileErrorStackTraceEntry {
210
211
 
211
212
  impl From<PrecompileErrorStackTraceEntry> for SolidityStackTraceEntry {
212
213
  fn from(val: PrecompileErrorStackTraceEntry) -> Self {
213
- Either24::D(val)
214
+ Either25::D(val)
214
215
  }
215
216
  }
216
217
 
@@ -227,7 +228,7 @@ pub struct RevertErrorStackTraceEntry {
227
228
 
228
229
  impl From<RevertErrorStackTraceEntry> for SolidityStackTraceEntry {
229
230
  fn from(val: RevertErrorStackTraceEntry) -> Self {
230
- Either24::E(val)
231
+ Either25::E(val)
231
232
  }
232
233
  }
233
234
 
@@ -243,7 +244,7 @@ pub struct PanicErrorStackTraceEntry {
243
244
 
244
245
  impl From<PanicErrorStackTraceEntry> for SolidityStackTraceEntry {
245
246
  fn from(val: PanicErrorStackTraceEntry) -> Self {
246
- Either24::F(val)
247
+ Either25::F(val)
247
248
  }
248
249
  }
249
250
 
@@ -259,7 +260,7 @@ pub struct CustomErrorStackTraceEntry {
259
260
 
260
261
  impl From<CustomErrorStackTraceEntry> for SolidityStackTraceEntry {
261
262
  fn from(val: CustomErrorStackTraceEntry) -> Self {
262
- Either24::G(val)
263
+ Either25::G(val)
263
264
  }
264
265
  }
265
266
 
@@ -278,7 +279,7 @@ pub struct FunctionNotPayableErrorStackTraceEntry {
278
279
 
279
280
  impl From<FunctionNotPayableErrorStackTraceEntry> for SolidityStackTraceEntry {
280
281
  fn from(val: FunctionNotPayableErrorStackTraceEntry) -> Self {
281
- Either24::H(val)
282
+ Either25::H(val)
282
283
  }
283
284
  }
284
285
 
@@ -292,7 +293,7 @@ pub struct InvalidParamsErrorStackTraceEntry {
292
293
 
293
294
  impl From<InvalidParamsErrorStackTraceEntry> for SolidityStackTraceEntry {
294
295
  fn from(val: InvalidParamsErrorStackTraceEntry) -> Self {
295
- Either24::I(val)
296
+ Either25::I(val)
296
297
  }
297
298
  }
298
299
 
@@ -311,7 +312,7 @@ pub struct FallbackNotPayableErrorStackTraceEntry {
311
312
 
312
313
  impl From<FallbackNotPayableErrorStackTraceEntry> for SolidityStackTraceEntry {
313
314
  fn from(val: FallbackNotPayableErrorStackTraceEntry) -> Self {
314
- Either24::J(val)
315
+ Either25::J(val)
315
316
  }
316
317
  }
317
318
 
@@ -332,7 +333,7 @@ pub struct FallbackNotPayableAndNoReceiveErrorStackTraceEntry {
332
333
 
333
334
  impl From<FallbackNotPayableAndNoReceiveErrorStackTraceEntry> for SolidityStackTraceEntry {
334
335
  fn from(val: FallbackNotPayableAndNoReceiveErrorStackTraceEntry) -> Self {
335
- Either24::K(val)
336
+ Either25::K(val)
336
337
  }
337
338
  }
338
339
 
@@ -351,7 +352,7 @@ pub struct UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry {
351
352
 
352
353
  impl From<UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry> for SolidityStackTraceEntry {
353
354
  fn from(val: UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry) -> Self {
354
- Either24::L(val)
355
+ Either25::L(val)
355
356
  }
356
357
  }
357
358
 
@@ -369,7 +370,7 @@ pub struct MissingFallbackOrReceiveErrorStackTraceEntry {
369
370
 
370
371
  impl From<MissingFallbackOrReceiveErrorStackTraceEntry> for SolidityStackTraceEntry {
371
372
  fn from(val: MissingFallbackOrReceiveErrorStackTraceEntry) -> Self {
372
- Either24::M(val)
373
+ Either25::M(val)
373
374
  }
374
375
  }
375
376
 
@@ -386,7 +387,7 @@ pub struct ReturndataSizeErrorStackTraceEntry {
386
387
 
387
388
  impl From<ReturndataSizeErrorStackTraceEntry> for SolidityStackTraceEntry {
388
389
  fn from(val: ReturndataSizeErrorStackTraceEntry) -> Self {
389
- Either24::N(val)
390
+ Either25::N(val)
390
391
  }
391
392
  }
392
393
 
@@ -404,7 +405,7 @@ pub struct NonContractAccountCalledErrorStackTraceEntry {
404
405
 
405
406
  impl From<NonContractAccountCalledErrorStackTraceEntry> for SolidityStackTraceEntry {
406
407
  fn from(val: NonContractAccountCalledErrorStackTraceEntry) -> Self {
407
- Either24::O(val)
408
+ Either25::O(val)
408
409
  }
409
410
  }
410
411
 
@@ -418,7 +419,7 @@ pub struct CallFailedErrorStackTraceEntry {
418
419
 
419
420
  impl From<CallFailedErrorStackTraceEntry> for SolidityStackTraceEntry {
420
421
  fn from(val: CallFailedErrorStackTraceEntry) -> Self {
421
- Either24::P(val)
422
+ Either25::P(val)
422
423
  }
423
424
  }
424
425
 
@@ -435,7 +436,7 @@ pub struct DirectLibraryCallErrorStackTraceEntry {
435
436
 
436
437
  impl From<DirectLibraryCallErrorStackTraceEntry> for SolidityStackTraceEntry {
437
438
  fn from(val: DirectLibraryCallErrorStackTraceEntry) -> Self {
438
- Either24::Q(val)
439
+ Either25::Q(val)
439
440
  }
440
441
  }
441
442
 
@@ -455,7 +456,7 @@ pub struct UnrecognizedCreateErrorStackTraceEntry {
455
456
 
456
457
  impl From<UnrecognizedCreateErrorStackTraceEntry> for SolidityStackTraceEntry {
457
458
  fn from(val: UnrecognizedCreateErrorStackTraceEntry) -> Self {
458
- Either24::R(val)
459
+ Either25::R(val)
459
460
  }
460
461
  }
461
462
 
@@ -477,7 +478,7 @@ pub struct UnrecognizedContractErrorStackTraceEntry {
477
478
 
478
479
  impl From<UnrecognizedContractErrorStackTraceEntry> for SolidityStackTraceEntry {
479
480
  fn from(val: UnrecognizedContractErrorStackTraceEntry) -> Self {
480
- Either24::S(val)
481
+ Either25::S(val)
481
482
  }
482
483
  }
483
484
 
@@ -494,7 +495,7 @@ pub struct OtherExecutionErrorStackTraceEntry {
494
495
 
495
496
  impl From<OtherExecutionErrorStackTraceEntry> for SolidityStackTraceEntry {
496
497
  fn from(val: OtherExecutionErrorStackTraceEntry) -> Self {
497
- Either24::T(val)
498
+ Either25::T(val)
498
499
  }
499
500
  }
500
501
 
@@ -512,7 +513,7 @@ pub struct UnmappedSolc063RevertErrorStackTraceEntry {
512
513
 
513
514
  impl From<UnmappedSolc063RevertErrorStackTraceEntry> for SolidityStackTraceEntry {
514
515
  fn from(val: UnmappedSolc063RevertErrorStackTraceEntry) -> Self {
515
- Either24::U(val)
516
+ Either25::U(val)
516
517
  }
517
518
  }
518
519
 
@@ -529,7 +530,7 @@ pub struct ContractTooLargeErrorStackTraceEntry {
529
530
 
530
531
  impl From<ContractTooLargeErrorStackTraceEntry> for SolidityStackTraceEntry {
531
532
  fn from(val: ContractTooLargeErrorStackTraceEntry) -> Self {
532
- Either24::V(val)
533
+ Either25::V(val)
533
534
  }
534
535
  }
535
536
 
@@ -548,7 +549,7 @@ pub struct InternalFunctionCallStackEntry {
548
549
 
549
550
  impl From<InternalFunctionCallStackEntry> for SolidityStackTraceEntry {
550
551
  fn from(val: InternalFunctionCallStackEntry) -> Self {
551
- Either24::W(val)
552
+ Either25::W(val)
552
553
  }
553
554
  }
554
555
 
@@ -566,7 +567,23 @@ pub struct ContractCallRunOutOfGasError {
566
567
 
567
568
  impl From<ContractCallRunOutOfGasError> for SolidityStackTraceEntry {
568
569
  fn from(val: ContractCallRunOutOfGasError) -> Self {
569
- Either24::X(val)
570
+ Either25::X(val)
571
+ }
572
+ }
573
+
574
+ #[napi(object)]
575
+ #[derive(Clone, Serialize)]
576
+ pub struct CheatcodeErrorStackTraceEntry {
577
+ #[napi(js_name = "type", ts_type = "StackTraceEntryType.CHEATCODE_ERROR")]
578
+ pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::CHEATCODE_ERROR as u8 }>,
579
+ // The parsed cheatcode error message that can be displayed to the user
580
+ pub message: String,
581
+ pub source_reference: SourceReference,
582
+ }
583
+
584
+ impl From<CheatcodeErrorStackTraceEntry> for SolidityStackTraceEntry {
585
+ fn from(val: CheatcodeErrorStackTraceEntry) -> Self {
586
+ Either25::Y(val)
570
587
  }
571
588
  }
572
589
 
@@ -580,7 +597,7 @@ impl From<ContractCallRunOutOfGasError> for SolidityStackTraceEntry {
580
597
  // Rather, we just bite the bullet for now and use the type alias directly
581
598
  // (which falls back to `any` as it's not recognized in the context of the
582
599
  // index.d.ts file) until we finish the porting work.
583
- pub type SolidityStackTraceEntry = Either24<
600
+ pub type SolidityStackTraceEntry = Either25<
584
601
  CallstackEntryStackTraceEntry,
585
602
  UnrecognizedCreateCallstackEntryStackTraceEntry,
586
603
  UnrecognizedContractCallstackEntryStackTraceEntry,
@@ -605,6 +622,7 @@ pub type SolidityStackTraceEntry = Either24<
605
622
  ContractTooLargeErrorStackTraceEntry,
606
623
  InternalFunctionCallStackEntry,
607
624
  ContractCallRunOutOfGasError,
625
+ CheatcodeErrorStackTraceEntry,
608
626
  >;
609
627
 
610
628
  impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::StackTraceEntry {
@@ -663,6 +681,15 @@ impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::St
663
681
  source_reference: source_reference.map(std::convert::Into::into),
664
682
  }
665
683
  .into(),
684
+ StackTraceEntry::CheatCodeError {
685
+ message,
686
+ source_reference,
687
+ } => CheatcodeErrorStackTraceEntry {
688
+ type_: StackTraceEntryTypeConst,
689
+ message,
690
+ source_reference: source_reference.into(),
691
+ }
692
+ .into(),
666
693
  StackTraceEntry::CustomError {
667
694
  message,
668
695
  source_reference,