@nomicfoundation/edr 0.12.0-alpha.0 → 0.12.0-next.0

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.js CHANGED
@@ -310,7 +310,7 @@ if (!nativeBinding) {
310
310
  throw new Error(`Failed to load native binding`)
311
311
  }
312
312
 
313
- const { GENERIC_CHAIN_TYPE, genericChainProviderFactory, L1_CHAIN_TYPE, l1GenesisState, l1ProviderFactory, SpecId, l1HardforkFromString, l1HardforkToString, l1HardforkLatest, FRONTIER, FRONTIER_THAWING, HOMESTEAD, DAO_FORK, TANGERINE, SPURIOUS_DRAGON, BYZANTIUM, CONSTANTINOPLE, PETERSBURG, ISTANBUL, MUIR_GLACIER, BERLIN, LONDON, ARROW_GLACIER, GRAY_GLACIER, MERGE, SHANGHAI, CANCUN, PRAGUE, MineOrdering, EdrContext, ProviderFactory, Response, Provider, SuccessReason, ExceptionalHalt, linkHexStringBytecode, printStackTrace, Exit, ExitCode, BytecodeWrapper, ContractFunctionType, ReturnData, StackTraceEntryType, stackTraceEntryTypeToString, FALLBACK_FUNCTION_NAME, RECEIVE_FUNCTION_NAME, CONSTRUCTOR_FUNCTION_NAME, UNRECOGNIZED_FUNCTION_NAME, UNKNOWN_FUNCTION_NAME, PRECOMPILE_FUNCTION_NAME, UNRECOGNIZED_CONTRACT_NAME, RawTrace, getLatestSupportedSolcVersion } = nativeBinding
313
+ const { GENERIC_CHAIN_TYPE, genericChainProviderFactory, L1_CHAIN_TYPE, l1GenesisState, l1ProviderFactory, SpecId, l1HardforkFromString, l1HardforkToString, l1HardforkLatest, FRONTIER, FRONTIER_THAWING, HOMESTEAD, DAO_FORK, TANGERINE, SPURIOUS_DRAGON, BYZANTIUM, CONSTANTINOPLE, PETERSBURG, ISTANBUL, MUIR_GLACIER, BERLIN, LONDON, ARROW_GLACIER, GRAY_GLACIER, MERGE, SHANGHAI, CANCUN, PRAGUE, OpHardfork, opHardforkFromString, opHardforkToString, opLatestHardfork, OP_CHAIN_TYPE, opGenesisState, opProviderFactory, BEDROCK, REGOLITH, CANYON, ECOTONE, FJORD, GRANITE, HOLOCENE, ISTHMUS, MineOrdering, EdrContext, addStatementCoverageInstrumentation, Precompile, precompileP256Verify, ProviderFactory, Response, Provider, SuccessReason, ExceptionalHalt, CachedChains, CachedEndpoints, FsAccessPermission, IncludeTraces, SolidityTestRunnerFactory, l1SolidityTestRunnerFactory, opSolidityTestRunnerFactory, SuiteResult, TestResult, TestStatus, CallKind, LogKind, linkHexStringBytecode, printStackTrace, Exit, ExitCode, BytecodeWrapper, ContractFunctionType, ReturnData, StackTraceEntryType, stackTraceEntryTypeToString, FALLBACK_FUNCTION_NAME, RECEIVE_FUNCTION_NAME, CONSTRUCTOR_FUNCTION_NAME, UNRECOGNIZED_FUNCTION_NAME, UNKNOWN_FUNCTION_NAME, PRECOMPILE_FUNCTION_NAME, UNRECOGNIZED_CONTRACT_NAME, RawTrace, getLatestSupportedSolcVersion } = nativeBinding
314
314
 
315
315
  module.exports.GENERIC_CHAIN_TYPE = GENERIC_CHAIN_TYPE
316
316
  module.exports.genericChainProviderFactory = genericChainProviderFactory
@@ -340,13 +340,43 @@ module.exports.MERGE = MERGE
340
340
  module.exports.SHANGHAI = SHANGHAI
341
341
  module.exports.CANCUN = CANCUN
342
342
  module.exports.PRAGUE = PRAGUE
343
+ module.exports.OpHardfork = OpHardfork
344
+ module.exports.opHardforkFromString = opHardforkFromString
345
+ module.exports.opHardforkToString = opHardforkToString
346
+ module.exports.opLatestHardfork = opLatestHardfork
347
+ module.exports.OP_CHAIN_TYPE = OP_CHAIN_TYPE
348
+ module.exports.opGenesisState = opGenesisState
349
+ module.exports.opProviderFactory = opProviderFactory
350
+ module.exports.BEDROCK = BEDROCK
351
+ module.exports.REGOLITH = REGOLITH
352
+ module.exports.CANYON = CANYON
353
+ module.exports.ECOTONE = ECOTONE
354
+ module.exports.FJORD = FJORD
355
+ module.exports.GRANITE = GRANITE
356
+ module.exports.HOLOCENE = HOLOCENE
357
+ module.exports.ISTHMUS = ISTHMUS
343
358
  module.exports.MineOrdering = MineOrdering
344
359
  module.exports.EdrContext = EdrContext
360
+ module.exports.addStatementCoverageInstrumentation = addStatementCoverageInstrumentation
361
+ module.exports.Precompile = Precompile
362
+ module.exports.precompileP256Verify = precompileP256Verify
345
363
  module.exports.ProviderFactory = ProviderFactory
346
364
  module.exports.Response = Response
347
365
  module.exports.Provider = Provider
348
366
  module.exports.SuccessReason = SuccessReason
349
367
  module.exports.ExceptionalHalt = ExceptionalHalt
368
+ module.exports.CachedChains = CachedChains
369
+ module.exports.CachedEndpoints = CachedEndpoints
370
+ module.exports.FsAccessPermission = FsAccessPermission
371
+ module.exports.IncludeTraces = IncludeTraces
372
+ module.exports.SolidityTestRunnerFactory = SolidityTestRunnerFactory
373
+ module.exports.l1SolidityTestRunnerFactory = l1SolidityTestRunnerFactory
374
+ module.exports.opSolidityTestRunnerFactory = opSolidityTestRunnerFactory
375
+ module.exports.SuiteResult = SuiteResult
376
+ module.exports.TestResult = TestResult
377
+ module.exports.TestStatus = TestStatus
378
+ module.exports.CallKind = CallKind
379
+ module.exports.LogKind = LogKind
350
380
  module.exports.linkHexStringBytecode = linkHexStringBytecode
351
381
  module.exports.printStackTrace = printStackTrace
352
382
  module.exports.Exit = Exit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomicfoundation/edr",
3
- "version": "0.12.0-alpha.0",
3
+ "version": "0.12.0-next.0",
4
4
  "devDependencies": {
5
5
  "@napi-rs/cli": "^2.18.4",
6
6
  "@nomicfoundation/ethereumjs-util": "^9.0.4",
@@ -17,11 +17,12 @@
17
17
  "eslint-plugin-import": "2.27.5",
18
18
  "eslint-plugin-mocha": "10.4.1",
19
19
  "eslint-plugin-prettier": "5.2.1",
20
+ "ethers": "^6.1.0",
20
21
  "json-stream-stringify": "^3.1.4",
21
22
  "mocha": "^10.0.0",
22
23
  "prettier": "^3.2.5",
23
24
  "ts-node": "^10.8.0",
24
- "typescript": "~5.0.0"
25
+ "typescript": "~5.8.2"
25
26
  },
26
27
  "engines": {
27
28
  "node": ">= 18"
@@ -52,30 +53,32 @@
52
53
  },
53
54
  "repository": "NomicFoundation/edr.git",
54
55
  "types": "index.d.ts",
55
- "dependencies": {
56
- "@nomicfoundation/edr-darwin-arm64": "0.12.0-alpha.0",
57
- "@nomicfoundation/edr-darwin-x64": "0.12.0-alpha.0",
58
- "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-alpha.0",
59
- "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-alpha.0",
60
- "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-alpha.0",
61
- "@nomicfoundation/edr-linux-x64-musl": "0.12.0-alpha.0",
62
- "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-alpha.0"
56
+ "optionalDependencies": {
57
+ "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.0",
58
+ "@nomicfoundation/edr-darwin-x64": "0.12.0-next.0",
59
+ "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.0",
60
+ "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.0",
61
+ "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.0",
62
+ "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.0",
63
+ "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.0"
63
64
  },
64
65
  "scripts": {
65
66
  "artifacts": "napi artifacts",
66
- "build": "napi build --platform --release --no-const-enum",
67
- "build:debug": "napi build --platform --no-const-enum",
68
- "build:op": "napi build --platform --release --no-const-enum --features op",
69
- "build:scenarios": "napi build --platform --release --no-const-enum --features scenarios",
70
- "build:tracing": "napi build --platform --release --no-const-enum --features tracing",
67
+ "build": "pnpm run build:publish",
68
+ "build:debug": "napi build --platform --no-const-enum --features op",
69
+ "build:dev": "napi build --platform --release --no-const-enum --features op,test-mock",
70
+ "build:publish": "napi build --platform --profile napi-publish --no-const-enum --features op",
71
+ "build:scenarios": "napi build --platform --release --no-const-enum --features op,scenarios",
72
+ "build:tracing": "napi build --platform --release --no-const-enum --features op,tracing",
73
+ "build:typingFile": "napi build --platform --no-const-enum --features op",
71
74
  "clean": "rm -rf @nomicfoundation/edr.node",
72
75
  "eslint": "eslint 'test/**/*.ts'",
73
76
  "lint": "pnpm run prettier && pnpm run eslint",
74
77
  "lint:fix": "pnpm run prettier --write",
75
- "pretest": "pnpm build:op",
78
+ "pretest": "pnpm build:dev",
76
79
  "prettier": "prettier --check \"test/**.ts\"",
77
80
  "test": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/*.ts\"",
78
- "testNoBuild": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(op)}.ts\"",
81
+ "testNoBuild": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(mock)}.ts\"",
79
82
  "universal": "napi universal",
80
83
  "version": "napi version"
81
84
  }
package/src/account.rs CHANGED
@@ -1,76 +1,123 @@
1
- use core::fmt::{Debug, Display};
2
-
3
- use edr_eth::signature::secret_key_from_str;
4
- use napi::{
5
- JsString, Status,
6
- bindgen_prelude::{BigInt, Uint8Array},
7
- };
1
+ use derive_more::Debug;
2
+ use edr_eth::{hex, HashMap, U256};
3
+ use edr_solidity_tests::{backend::Predeploy, revm::state::AccountInfo};
4
+ use napi::bindgen_prelude::{BigInt, Uint8Array};
8
5
  use napi_derive::napi;
9
- use serde::Serialize;
10
6
 
11
- use crate::cast::TryCast as _;
7
+ use crate::{
8
+ cast::TryCast,
9
+ serde::{
10
+ serialize_bigint_as_struct, serialize_optional_bigint_as_struct,
11
+ serialize_optional_uint8array_as_hex, serialize_uint8array_as_hex,
12
+ },
13
+ };
12
14
 
13
- /// A description of an account's state.
15
+ /// Specification of overrides for an account and its storage.
14
16
  #[napi(object)]
15
- pub struct Account {
17
+ #[derive(Clone, Debug, serde::Serialize)]
18
+ pub struct AccountOverride {
16
19
  /// The account's address
20
+ #[debug("{}", hex::encode(address))]
21
+ #[serde(serialize_with = "serialize_uint8array_as_hex")]
17
22
  pub address: Uint8Array,
18
- /// The account's balance
19
- pub balance: BigInt,
20
- /// The account's nonce
21
- pub nonce: BigInt,
22
- /// The account's code
23
+ /// If present, the overwriting balance.
24
+ #[serde(serialize_with = "serialize_optional_bigint_as_struct")]
25
+ pub balance: Option<BigInt>,
26
+ /// If present, the overwriting nonce.
27
+ #[serde(serialize_with = "serialize_optional_bigint_as_struct")]
28
+ pub nonce: Option<BigInt>,
29
+ /// If present, the overwriting code.
30
+ #[debug("{:?}", code.as_ref().map(hex::encode))]
31
+ #[serde(serialize_with = "serialize_optional_uint8array_as_hex")]
23
32
  pub code: Option<Uint8Array>,
24
- /// The account's storage
25
- pub storage: Vec<StorageSlot>,
33
+ /// BEWARE: This field is not supported yet. See <https://github.com/NomicFoundation/edr/issues/911>
34
+ ///
35
+ /// If present, the overwriting storage.
36
+ pub storage: Option<Vec<StorageSlot>>,
26
37
  }
27
38
 
28
- /// A description of a storage slot's state.
29
- #[napi(object)]
30
- pub struct StorageSlot {
31
- /// The storage slot's index
32
- pub index: BigInt,
33
- /// The storage slot's value
34
- pub value: BigInt,
35
- }
39
+ impl TryFrom<AccountOverride> for (edr_eth::Address, edr_provider::AccountOverride) {
40
+ type Error = napi::Error;
36
41
 
37
- /// An owned account, for which the secret key is known, and its desired genesis
38
- /// balance.
39
- #[napi(object)]
40
- pub struct OwnedAccount {
41
- // Using JsString here as it doesn't have `Debug`, `Display` and `Serialize` implementation
42
- // which prevents accidentally leaking the secret keys to error messages and logs.
43
- /// Account secret key
44
- pub secret_key: JsString,
45
- /// Account balance
46
- pub balance: BigInt,
42
+ fn try_from(value: AccountOverride) -> Result<Self, Self::Error> {
43
+ let AccountOverride {
44
+ address,
45
+ balance,
46
+ nonce,
47
+ code,
48
+ storage,
49
+ } = value;
50
+ let storage = storage
51
+ .map(|storage| {
52
+ storage
53
+ .into_iter()
54
+ .map(|StorageSlot { index, value }| {
55
+ let value = value.try_cast()?;
56
+ let slot = edr_evm::state::EvmStorageSlot::new(value);
57
+
58
+ let index: edr_eth::U256 = index.try_cast()?;
59
+ Ok((index, slot))
60
+ })
61
+ .collect::<napi::Result<_>>()
62
+ })
63
+ .transpose()?;
64
+
65
+ let account_override = edr_provider::AccountOverride {
66
+ balance: balance.map(TryCast::try_cast).transpose()?,
67
+ nonce: nonce.map(TryCast::try_cast).transpose()?,
68
+ code: code.map(TryCast::try_cast).transpose()?,
69
+ storage,
70
+ };
71
+
72
+ let address: edr_eth::Address = address.try_cast()?;
73
+
74
+ Ok((address, account_override))
75
+ }
47
76
  }
48
77
 
49
- impl TryFrom<OwnedAccount> for edr_provider::config::OwnedAccount {
78
+ impl TryFrom<AccountOverride> for Predeploy {
50
79
  type Error = napi::Error;
51
80
 
52
- fn try_from(value: OwnedAccount) -> Result<Self, Self::Error> {
53
- // This is the only place in production code where it's allowed to use
54
- // `DangerousSecretKeyStr`.
55
- #[allow(deprecated)]
56
- use edr_eth::signature::DangerousSecretKeyStr;
81
+ fn try_from(value: AccountOverride) -> Result<Self, Self::Error> {
82
+ let (address, account_override) = value.try_into()?;
57
83
 
58
- static_assertions::assert_not_impl_all!(JsString: Debug, Display, Serialize);
59
- // `k256::SecretKey` has `Debug` implementation, but it's opaque (only shows the
60
- // type name)
61
- static_assertions::assert_not_impl_any!(k256::SecretKey: Display, Serialize);
84
+ let storage = account_override.storage.unwrap_or_else(HashMap::new);
85
+ let balance = account_override.balance.unwrap_or(U256::ZERO);
86
+ let nonce = account_override.nonce.unwrap_or(0);
87
+ let code = account_override.code.ok_or_else(|| {
88
+ napi::Error::from_reason(format!("Predeploy with address '{address}' must have code"))
89
+ })?;
62
90
 
63
- let secret_key = value.secret_key.into_utf8()?;
64
- // This is the only place in production code where it's allowed to use
65
- // `DangerousSecretKeyStr`.
66
- #[allow(deprecated)]
67
- let secret_key_str = DangerousSecretKeyStr(secret_key.as_str()?);
68
- let secret_key: k256::SecretKey = secret_key_from_str(secret_key_str)
69
- .map_err(|e| napi::Error::new(Status::InvalidArg, e.to_string()))?;
91
+ if code.is_empty() {
92
+ return Err(napi::Error::from_reason(
93
+ "Predeploy with address '{address}' must have non-empty code",
94
+ ));
95
+ }
96
+ let code_hash = code.hash_slow();
97
+
98
+ let account_info = AccountInfo {
99
+ balance,
100
+ nonce,
101
+ code_hash,
102
+ code: Some(code),
103
+ };
70
104
 
71
105
  Ok(Self {
72
- secret_key,
73
- balance: value.balance.try_cast()?,
106
+ address,
107
+ account_info,
108
+ storage,
74
109
  })
75
110
  }
76
111
  }
112
+
113
+ /// A description of a storage slot's state.
114
+ #[napi(object)]
115
+ #[derive(Clone, Debug, serde::Serialize)]
116
+ pub struct StorageSlot {
117
+ /// The storage slot's index
118
+ #[serde(serialize_with = "serialize_bigint_as_struct")]
119
+ pub index: BigInt,
120
+ /// The storage slot's value
121
+ #[serde(serialize_with = "serialize_bigint_as_struct")]
122
+ pub value: BigInt,
123
+ }
package/src/block.rs CHANGED
@@ -1,108 +1,7 @@
1
- use edr_eth::{Address, B64, B256, Bytes};
2
- use napi::bindgen_prelude::{BigInt, Buffer};
1
+ use napi::bindgen_prelude::BigInt;
3
2
  use napi_derive::napi;
4
3
 
5
- use crate::{cast::TryCast, withdrawal::Withdrawal};
6
-
7
- #[napi(object)]
8
- pub struct BlockOptions {
9
- /// The parent block's hash
10
- pub parent_hash: Option<Buffer>,
11
- /// The block's beneficiary
12
- pub beneficiary: Option<Buffer>,
13
- /// The state's root hash
14
- pub state_root: Option<Buffer>,
15
- /// The block's difficulty
16
- pub difficulty: Option<BigInt>,
17
- /// The block's number
18
- pub number: Option<BigInt>,
19
- /// The block's gas limit
20
- pub gas_limit: Option<BigInt>,
21
- /// The block's timestamp
22
- pub timestamp: Option<BigInt>,
23
- /// The block's extra data
24
- pub extra_data: Option<Buffer>,
25
- /// The block's mix hash (or prevrandao)
26
- pub mix_hash: Option<Buffer>,
27
- /// The block's nonce
28
- pub nonce: Option<Buffer>,
29
- /// The block's base gas fee
30
- pub base_fee: Option<BigInt>,
31
- /// The block's withdrawals
32
- pub withdrawals: Option<Vec<Withdrawal>>,
33
- /// Blob gas was added by EIP-4844 and is ignored in older headers.
34
- pub blob_gas: Option<BlobGas>,
35
- /// The hash tree root of the parent beacon block for the given execution
36
- /// block (EIP-4788).
37
- pub parent_beacon_block_root: Option<Buffer>,
38
- /// The commitment hash calculated for a list of [EIP-7685] data requests.
39
- ///
40
- /// [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685
41
- pub requests_hash: Option<Buffer>,
42
- }
43
-
44
- impl TryFrom<BlockOptions> for edr_eth::block::BlockOptions {
45
- type Error = napi::Error;
46
-
47
- #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
48
- fn try_from(value: BlockOptions) -> Result<Self, Self::Error> {
49
- Ok(Self {
50
- parent_hash: value
51
- .parent_hash
52
- .map(TryCast::<B256>::try_cast)
53
- .transpose()?,
54
- beneficiary: value
55
- .beneficiary
56
- .map(TryCast::<Address>::try_cast)
57
- .transpose()?,
58
- state_root: value
59
- .state_root
60
- .map(TryCast::<B256>::try_cast)
61
- .transpose()?,
62
- difficulty: value
63
- .difficulty
64
- .map_or(Ok(None), |difficulty| difficulty.try_cast().map(Some))?,
65
- number: value
66
- .number
67
- .map_or(Ok(None), |number| number.try_cast().map(Some))?,
68
- gas_limit: value
69
- .gas_limit
70
- .map_or(Ok(None), |gas_limit| gas_limit.try_cast().map(Some))?,
71
- timestamp: value
72
- .timestamp
73
- .map_or(Ok(None), |timestamp| timestamp.try_cast().map(Some))?,
74
- extra_data: value
75
- .extra_data
76
- .map(|extra_data| Bytes::copy_from_slice(&extra_data)),
77
- mix_hash: value.mix_hash.map(TryCast::<B256>::try_cast).transpose()?,
78
- nonce: value.nonce.map(TryCast::<B64>::try_cast).transpose()?,
79
- base_fee: value
80
- .base_fee
81
- .map_or(Ok(None), |basefee| basefee.try_cast().map(Some))?,
82
- withdrawals: value
83
- .withdrawals
84
- .map(|withdrawals| {
85
- withdrawals
86
- .into_iter()
87
- .map(edr_eth::withdrawal::Withdrawal::try_from)
88
- .collect()
89
- })
90
- .transpose()?,
91
- blob_gas: value
92
- .blob_gas
93
- .map(edr_eth::block::BlobGas::try_from)
94
- .transpose()?,
95
- parent_beacon_block_root: value
96
- .parent_beacon_block_root
97
- .map(TryCast::<B256>::try_cast)
98
- .transpose()?,
99
- requests_hash: value
100
- .requests_hash
101
- .map(TryCast::<B256>::try_cast)
102
- .transpose()?,
103
- })
104
- }
105
- }
4
+ use crate::cast::TryCast;
106
5
 
107
6
  /// Information about the blob gas used in a block.
108
7
  #[napi(object)]
@@ -2,12 +2,12 @@ use std::sync::mpsc::channel;
2
2
 
3
3
  use edr_eth::{Address, Bytes};
4
4
  use napi::{
5
- Env, JsFunction, Status,
6
- bindgen_prelude::{Buffer, Promise},
5
+ bindgen_prelude::{Promise, Uint8Array},
7
6
  threadsafe_function::{
8
7
  ErrorStrategy, ThreadSafeCallContext, ThreadsafeFunction, ThreadsafeFunctionCallMode,
9
8
  },
10
9
  tokio::runtime,
10
+ Env, JsFunction, Status,
11
11
  };
12
12
  use napi_derive::napi;
13
13
 
@@ -16,7 +16,7 @@ use crate::cast::TryCast;
16
16
  /// The result of executing a call override.
17
17
  #[napi(object)]
18
18
  pub struct CallOverrideResult {
19
- pub result: Buffer,
19
+ pub result: Uint8Array,
20
20
  pub should_revert: bool,
21
21
  }
22
22
 
@@ -27,7 +27,7 @@ impl TryCast<Option<edr_provider::CallOverrideResult>> for Option<CallOverrideRe
27
27
  match self {
28
28
  None => Ok(None),
29
29
  Some(result) => Ok(Some(edr_provider::CallOverrideResult {
30
- output: result.result.try_cast()?,
30
+ output: Bytes::copy_from_slice(&result.result),
31
31
  should_revert: result.should_revert,
32
32
  })),
33
33
  }
@@ -56,20 +56,20 @@ impl CallOverrideCallback {
56
56
  |ctx: ThreadSafeCallContext<CallOverrideCall>| {
57
57
  let address = ctx
58
58
  .env
59
- .create_buffer_with_data(ctx.value.contract_address.to_vec())?
59
+ .create_arraybuffer_with_data(ctx.value.contract_address.to_vec())?
60
60
  .into_raw();
61
61
 
62
62
  let data = ctx
63
63
  .env
64
- .create_buffer_with_data(ctx.value.data.to_vec())?
64
+ .create_arraybuffer_with_data(ctx.value.data.to_vec())?
65
65
  .into_raw();
66
66
 
67
67
  Ok(vec![address, data])
68
68
  },
69
69
  )?;
70
70
 
71
- // Maintain a weak reference to the function to avoid the event loop from
72
- // exiting.
71
+ // Maintain a weak reference to the function to avoid blocking the event loop
72
+ // from exiting.
73
73
  call_override_callback_fn.unref(env)?;
74
74
 
75
75
  Ok(Self {
package/src/cast.rs CHANGED
@@ -1,7 +1,7 @@
1
- use edr_eth::{Address, B64, B256, Bytecode, Bytes, U256};
1
+ use edr_eth::{Address, Bytecode, Bytes, B256, B64, U256};
2
2
  use napi::{
3
+ bindgen_prelude::{BigInt, Uint8Array},
3
4
  Status,
4
- bindgen_prelude::{BigInt, Buffer, Uint8Array},
5
5
  };
6
6
 
7
7
  /// An attempted conversion that consumes `self`, which may or may not be
@@ -15,20 +15,6 @@ pub trait TryCast<T>: Sized {
15
15
  fn try_cast(self) -> Result<T, Self::Error>;
16
16
  }
17
17
 
18
- impl TryCast<Address> for Buffer {
19
- type Error = napi::Error;
20
-
21
- fn try_cast(self) -> std::result::Result<Address, Self::Error> {
22
- if self.len() != 20 {
23
- return Err(napi::Error::new(
24
- Status::InvalidArg,
25
- "Buffer was expected to be 20 bytes.".to_string(),
26
- ));
27
- }
28
- Ok(Address::from_slice(&self))
29
- }
30
- }
31
-
32
18
  impl TryCast<Address> for Uint8Array {
33
19
  type Error = napi::Error;
34
20
 
@@ -43,28 +29,28 @@ impl TryCast<Address> for Uint8Array {
43
29
  }
44
30
  }
45
31
 
46
- impl TryCast<B64> for Buffer {
32
+ impl TryCast<B64> for Uint8Array {
47
33
  type Error = napi::Error;
48
34
 
49
35
  fn try_cast(self) -> std::result::Result<B64, Self::Error> {
50
36
  if self.len() != 8 {
51
37
  return Err(napi::Error::new(
52
38
  Status::InvalidArg,
53
- "Buffer was expected to be 8 bytes.".to_string(),
39
+ "Uint8Array was expected to be 8 bytes.".to_string(),
54
40
  ));
55
41
  }
56
42
  Ok(B64::from_slice(&self))
57
43
  }
58
44
  }
59
45
 
60
- impl TryCast<B256> for Buffer {
46
+ impl TryCast<B256> for Uint8Array {
61
47
  type Error = napi::Error;
62
48
 
63
49
  fn try_cast(self) -> std::result::Result<B256, Self::Error> {
64
50
  if self.len() != 32 {
65
51
  return Err(napi::Error::new(
66
52
  Status::InvalidArg,
67
- "Buffer was expected to be 32 bytes.".to_string(),
53
+ "Uint8Array was expected to be 32 bytes.".to_string(),
68
54
  ));
69
55
  }
70
56
  Ok(B256::from_slice(&self))
@@ -170,15 +156,7 @@ impl<T> TryCast<T> for T {
170
156
  }
171
157
  }
172
158
 
173
- impl TryCast<Bytes> for Buffer {
174
- type Error = napi::Error;
175
-
176
- fn try_cast(self) -> Result<Bytes, Self::Error> {
177
- Ok(Bytes::copy_from_slice(&self))
178
- }
179
- }
180
-
181
- impl TryCast<Option<Bytes>> for Option<Buffer> {
159
+ impl TryCast<Option<Bytes>> for Option<Uint8Array> {
182
160
  type Error = napi::Error;
183
161
 
184
162
  fn try_cast(self) -> Result<Option<Bytes>, Self::Error> {
@@ -44,7 +44,7 @@ impl SyncProviderFactory for GenericChainProviderFactory {
44
44
  #[napi]
45
45
  pub const GENERIC_CHAIN_TYPE: &str = GenericChainSpec::CHAIN_TYPE;
46
46
 
47
- #[napi]
47
+ #[napi(catch_unwind)]
48
48
  pub fn generic_chain_provider_factory() -> ProviderFactory {
49
49
  let factory: Arc<dyn SyncProviderFactory> = Arc::new(GenericChainProviderFactory);
50
50
  factory.into()
package/src/chains/l1.rs CHANGED
@@ -15,7 +15,7 @@ use edr_solidity::contract_decoder::ContractDecoder;
15
15
  use napi::bindgen_prelude::{BigInt, Uint8Array};
16
16
  use napi_derive::napi;
17
17
 
18
- use crate::{account::Account, provider::ProviderFactory};
18
+ use crate::{account::AccountOverride, provider::ProviderFactory};
19
19
 
20
20
  pub struct L1ProviderFactory;
21
21
 
@@ -48,23 +48,25 @@ impl SyncProviderFactory for L1ProviderFactory {
48
48
  #[napi]
49
49
  pub const L1_CHAIN_TYPE: &str = L1ChainSpec::CHAIN_TYPE;
50
50
 
51
- #[napi]
52
- pub fn l1_genesis_state(hardfork: SpecId) -> Vec<Account> {
51
+ #[napi(catch_unwind)]
52
+ pub fn l1_genesis_state(hardfork: SpecId) -> Vec<AccountOverride> {
53
53
  // Use closures for lazy execution
54
- let beacon_roots_account_constructor = || Account {
55
- address: Uint8Array::from(BEACON_ROOTS_ADDRESS.as_slice()),
56
- balance: BigInt::from(0u64),
57
- nonce: BigInt::from(0u64),
58
- code: Some(Uint8Array::from(BEACON_ROOTS_BYTECODE)),
59
- storage: Vec::new(),
54
+ let beacon_roots_account_constructor = || AccountOverride {
55
+ address: Uint8Array::with_data_copied(BEACON_ROOTS_ADDRESS),
56
+ balance: Some(BigInt::from(0u64)),
57
+ nonce: Some(BigInt::from(0u64)),
58
+ code: Some(Uint8Array::with_data_copied(&BEACON_ROOTS_BYTECODE)),
59
+ storage: Some(Vec::new()),
60
60
  };
61
61
 
62
- let history_storage_account_constructor = || Account {
63
- address: Uint8Array::from(HISTORY_STORAGE_ADDRESS.as_slice()),
64
- balance: BigInt::from(0u64),
65
- nonce: BigInt::from(0u64),
66
- code: Some(Uint8Array::from(HISTORY_STORAGE_UNSUPPORTED_BYTECODE)),
67
- storage: Vec::new(),
62
+ let history_storage_account_constructor = || AccountOverride {
63
+ address: Uint8Array::with_data_copied(HISTORY_STORAGE_ADDRESS),
64
+ balance: Some(BigInt::from(0u64)),
65
+ nonce: Some(BigInt::from(0u64)),
66
+ code: Some(Uint8Array::with_data_copied(
67
+ &HISTORY_STORAGE_UNSUPPORTED_BYTECODE,
68
+ )),
69
+ storage: Some(Vec::new()),
68
70
  };
69
71
 
70
72
  if hardfork < SpecId::Cancun {
@@ -79,7 +81,7 @@ pub fn l1_genesis_state(hardfork: SpecId) -> Vec<Account> {
79
81
  }
80
82
  }
81
83
 
82
- #[napi]
84
+ #[napi(catch_unwind)]
83
85
  pub fn l1_provider_factory() -> ProviderFactory {
84
86
  let factory: Arc<dyn SyncProviderFactory> = Arc::new(L1ProviderFactory);
85
87
  factory.into()
@@ -190,12 +192,12 @@ impl From<SpecId> for edr_eth::l1::SpecId {
190
192
  /// Tries to parse the provided string to create a [`SpecId`] instance.
191
193
  ///
192
194
  /// Returns an error if the string does not match any known hardfork.
193
- #[napi]
195
+ #[napi(catch_unwind)]
194
196
  pub fn l1_hardfork_from_string(hardfork: String) -> napi::Result<SpecId> {
195
197
  hardfork.parse()
196
198
  }
197
199
 
198
- #[napi]
200
+ #[napi(catch_unwind)]
199
201
  pub fn l1_hardfork_to_string(harfork: SpecId) -> &'static str {
200
202
  match harfork {
201
203
  SpecId::Frontier => edr_eth::l1::hardfork::name::FRONTIER,