@nomicfoundation/edr 0.11.0 → 0.12.0-alpha.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.
@@ -0,0 +1,51 @@
1
+ use std::sync::Arc;
2
+
3
+ use edr_eth::l1;
4
+ use edr_generic::GenericChainSpec;
5
+ use edr_napi_core::{
6
+ logger::{self, Logger},
7
+ provider::{self, ProviderBuilder, SyncProviderFactory},
8
+ spec::SyncNapiSpec as _,
9
+ subscription,
10
+ };
11
+ use edr_solidity::contract_decoder::ContractDecoder;
12
+ use napi_derive::napi;
13
+
14
+ use crate::provider::ProviderFactory;
15
+
16
+ pub struct GenericChainProviderFactory;
17
+
18
+ impl SyncProviderFactory for GenericChainProviderFactory {
19
+ fn create_provider_builder(
20
+ &self,
21
+ env: &napi::Env,
22
+ provider_config: edr_napi_core::provider::Config,
23
+ logger_config: logger::Config,
24
+ subscription_config: subscription::Config,
25
+ contract_decoder: Arc<ContractDecoder>,
26
+ ) -> napi::Result<Box<dyn provider::Builder>> {
27
+ let logger = Logger::<GenericChainSpec>::new(logger_config, Arc::clone(&contract_decoder))?;
28
+
29
+ let provider_config =
30
+ edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
31
+
32
+ let subscription_callback =
33
+ subscription::Callback::new(env, subscription_config.subscription_callback)?;
34
+
35
+ Ok(Box::new(ProviderBuilder::new(
36
+ contract_decoder,
37
+ Box::new(logger),
38
+ provider_config,
39
+ subscription_callback,
40
+ )))
41
+ }
42
+ }
43
+
44
+ #[napi]
45
+ pub const GENERIC_CHAIN_TYPE: &str = GenericChainSpec::CHAIN_TYPE;
46
+
47
+ #[napi]
48
+ pub fn generic_chain_provider_factory() -> ProviderFactory {
49
+ let factory: Arc<dyn SyncProviderFactory> = Arc::new(GenericChainProviderFactory);
50
+ factory.into()
51
+ }
@@ -0,0 +1,260 @@
1
+ use std::{str::FromStr, sync::Arc};
2
+
3
+ use edr_eth::l1::{self, L1ChainSpec};
4
+ use edr_evm::eips::{
5
+ eip2935::{HISTORY_STORAGE_ADDRESS, HISTORY_STORAGE_UNSUPPORTED_BYTECODE},
6
+ eip4788::{BEACON_ROOTS_ADDRESS, BEACON_ROOTS_BYTECODE},
7
+ };
8
+ use edr_napi_core::{
9
+ logger::Logger,
10
+ provider::{self, ProviderBuilder, SyncProviderFactory},
11
+ spec::SyncNapiSpec as _,
12
+ subscription,
13
+ };
14
+ use edr_solidity::contract_decoder::ContractDecoder;
15
+ use napi::bindgen_prelude::{BigInt, Uint8Array};
16
+ use napi_derive::napi;
17
+
18
+ use crate::{account::Account, provider::ProviderFactory};
19
+
20
+ pub struct L1ProviderFactory;
21
+
22
+ impl SyncProviderFactory for L1ProviderFactory {
23
+ fn create_provider_builder(
24
+ &self,
25
+ env: &napi::Env,
26
+ provider_config: edr_napi_core::provider::Config,
27
+ logger_config: edr_napi_core::logger::Config,
28
+ subscription_config: edr_napi_core::subscription::Config,
29
+ contract_decoder: Arc<ContractDecoder>,
30
+ ) -> napi::Result<Box<dyn provider::Builder>> {
31
+ let logger = Logger::<L1ChainSpec>::new(logger_config, Arc::clone(&contract_decoder))?;
32
+
33
+ let provider_config =
34
+ edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
35
+
36
+ let subscription_callback =
37
+ subscription::Callback::new(env, subscription_config.subscription_callback)?;
38
+
39
+ Ok(Box::new(ProviderBuilder::new(
40
+ contract_decoder,
41
+ Box::new(logger),
42
+ provider_config,
43
+ subscription_callback,
44
+ )))
45
+ }
46
+ }
47
+
48
+ #[napi]
49
+ pub const L1_CHAIN_TYPE: &str = L1ChainSpec::CHAIN_TYPE;
50
+
51
+ #[napi]
52
+ pub fn l1_genesis_state(hardfork: SpecId) -> Vec<Account> {
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(),
60
+ };
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(),
68
+ };
69
+
70
+ if hardfork < SpecId::Cancun {
71
+ Vec::new()
72
+ } else if hardfork < SpecId::Prague {
73
+ vec![beacon_roots_account_constructor()]
74
+ } else {
75
+ vec![
76
+ beacon_roots_account_constructor(),
77
+ history_storage_account_constructor(),
78
+ ]
79
+ }
80
+ }
81
+
82
+ #[napi]
83
+ pub fn l1_provider_factory() -> ProviderFactory {
84
+ let factory: Arc<dyn SyncProviderFactory> = Arc::new(L1ProviderFactory);
85
+ factory.into()
86
+ }
87
+
88
+ /// Identifier for the Ethereum spec.
89
+ #[napi]
90
+ #[derive(PartialEq, Eq, PartialOrd, Ord)]
91
+ pub enum SpecId {
92
+ /// Frontier
93
+ Frontier = 0,
94
+ /// Frontier Thawing
95
+ FrontierThawing = 1,
96
+ /// Homestead
97
+ Homestead = 2,
98
+ /// DAO Fork
99
+ DaoFork = 3,
100
+ /// Tangerine
101
+ Tangerine = 4,
102
+ /// Spurious Dragon
103
+ SpuriousDragon = 5,
104
+ /// Byzantium
105
+ Byzantium = 6,
106
+ /// Constantinople
107
+ Constantinople = 7,
108
+ /// Petersburg
109
+ Petersburg = 8,
110
+ /// Istanbul
111
+ Istanbul = 9,
112
+ /// Muir Glacier
113
+ MuirGlacier = 10,
114
+ /// Berlin
115
+ Berlin = 11,
116
+ /// London
117
+ London = 12,
118
+ /// Arrow Glacier
119
+ ArrowGlacier = 13,
120
+ /// Gray Glacier
121
+ GrayGlacier = 14,
122
+ /// Merge
123
+ Merge = 15,
124
+ /// Shanghai
125
+ Shanghai = 16,
126
+ /// Cancun
127
+ Cancun = 17,
128
+ /// Prague
129
+ Prague = 18,
130
+ }
131
+
132
+ impl FromStr for SpecId {
133
+ type Err = napi::Error;
134
+
135
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
136
+ match s {
137
+ edr_eth::l1::hardfork::name::FRONTIER => Ok(SpecId::Frontier),
138
+ edr_eth::l1::hardfork::name::FRONTIER_THAWING => Ok(SpecId::FrontierThawing),
139
+ edr_eth::l1::hardfork::name::HOMESTEAD => Ok(SpecId::Homestead),
140
+ edr_eth::l1::hardfork::name::DAO_FORK => Ok(SpecId::DaoFork),
141
+ edr_eth::l1::hardfork::name::TANGERINE => Ok(SpecId::Tangerine),
142
+ edr_eth::l1::hardfork::name::SPURIOUS_DRAGON => Ok(SpecId::SpuriousDragon),
143
+ edr_eth::l1::hardfork::name::BYZANTIUM => Ok(SpecId::Byzantium),
144
+ edr_eth::l1::hardfork::name::CONSTANTINOPLE => Ok(SpecId::Constantinople),
145
+ edr_eth::l1::hardfork::name::PETERSBURG => Ok(SpecId::Petersburg),
146
+ edr_eth::l1::hardfork::name::ISTANBUL => Ok(SpecId::Istanbul),
147
+ edr_eth::l1::hardfork::name::MUIR_GLACIER => Ok(SpecId::MuirGlacier),
148
+ edr_eth::l1::hardfork::name::BERLIN => Ok(SpecId::Berlin),
149
+ edr_eth::l1::hardfork::name::LONDON => Ok(SpecId::London),
150
+ edr_eth::l1::hardfork::name::ARROW_GLACIER => Ok(SpecId::ArrowGlacier),
151
+ edr_eth::l1::hardfork::name::GRAY_GLACIER => Ok(SpecId::GrayGlacier),
152
+ edr_eth::l1::hardfork::name::MERGE => Ok(SpecId::Merge),
153
+ edr_eth::l1::hardfork::name::SHANGHAI => Ok(SpecId::Shanghai),
154
+ edr_eth::l1::hardfork::name::CANCUN => Ok(SpecId::Cancun),
155
+ edr_eth::l1::hardfork::name::PRAGUE => Ok(SpecId::Prague),
156
+ _ => Err(napi::Error::new(
157
+ napi::Status::InvalidArg,
158
+ format!("The provided hardfork `{s}` is not supported."),
159
+ )),
160
+ }
161
+ }
162
+ }
163
+
164
+ impl From<SpecId> for edr_eth::l1::SpecId {
165
+ fn from(value: SpecId) -> Self {
166
+ match value {
167
+ SpecId::Frontier => edr_eth::l1::SpecId::FRONTIER,
168
+ SpecId::FrontierThawing => edr_eth::l1::SpecId::FRONTIER_THAWING,
169
+ SpecId::Homestead => edr_eth::l1::SpecId::HOMESTEAD,
170
+ SpecId::DaoFork => edr_eth::l1::SpecId::DAO_FORK,
171
+ SpecId::Tangerine => edr_eth::l1::SpecId::TANGERINE,
172
+ SpecId::SpuriousDragon => edr_eth::l1::SpecId::SPURIOUS_DRAGON,
173
+ SpecId::Byzantium => edr_eth::l1::SpecId::BYZANTIUM,
174
+ SpecId::Constantinople => edr_eth::l1::SpecId::CONSTANTINOPLE,
175
+ SpecId::Petersburg => edr_eth::l1::SpecId::PETERSBURG,
176
+ SpecId::Istanbul => edr_eth::l1::SpecId::ISTANBUL,
177
+ SpecId::MuirGlacier => edr_eth::l1::SpecId::MUIR_GLACIER,
178
+ SpecId::Berlin => edr_eth::l1::SpecId::BERLIN,
179
+ SpecId::London => edr_eth::l1::SpecId::LONDON,
180
+ SpecId::ArrowGlacier => edr_eth::l1::SpecId::ARROW_GLACIER,
181
+ SpecId::GrayGlacier => edr_eth::l1::SpecId::GRAY_GLACIER,
182
+ SpecId::Merge => edr_eth::l1::SpecId::MERGE,
183
+ SpecId::Shanghai => edr_eth::l1::SpecId::SHANGHAI,
184
+ SpecId::Cancun => edr_eth::l1::SpecId::CANCUN,
185
+ SpecId::Prague => edr_eth::l1::SpecId::PRAGUE,
186
+ }
187
+ }
188
+ }
189
+
190
+ /// Tries to parse the provided string to create a [`SpecId`] instance.
191
+ ///
192
+ /// Returns an error if the string does not match any known hardfork.
193
+ #[napi]
194
+ pub fn l1_hardfork_from_string(hardfork: String) -> napi::Result<SpecId> {
195
+ hardfork.parse()
196
+ }
197
+
198
+ #[napi]
199
+ pub fn l1_hardfork_to_string(harfork: SpecId) -> &'static str {
200
+ match harfork {
201
+ SpecId::Frontier => edr_eth::l1::hardfork::name::FRONTIER,
202
+ SpecId::FrontierThawing => edr_eth::l1::hardfork::name::FRONTIER_THAWING,
203
+ SpecId::Homestead => edr_eth::l1::hardfork::name::HOMESTEAD,
204
+ SpecId::DaoFork => edr_eth::l1::hardfork::name::DAO_FORK,
205
+ SpecId::Tangerine => edr_eth::l1::hardfork::name::TANGERINE,
206
+ SpecId::SpuriousDragon => edr_eth::l1::hardfork::name::SPURIOUS_DRAGON,
207
+ SpecId::Byzantium => edr_eth::l1::hardfork::name::BYZANTIUM,
208
+ SpecId::Constantinople => edr_eth::l1::hardfork::name::CONSTANTINOPLE,
209
+ SpecId::Petersburg => edr_eth::l1::hardfork::name::PETERSBURG,
210
+ SpecId::Istanbul => edr_eth::l1::hardfork::name::ISTANBUL,
211
+ SpecId::MuirGlacier => edr_eth::l1::hardfork::name::MUIR_GLACIER,
212
+ SpecId::Berlin => edr_eth::l1::hardfork::name::BERLIN,
213
+ SpecId::London => edr_eth::l1::hardfork::name::LONDON,
214
+ SpecId::ArrowGlacier => edr_eth::l1::hardfork::name::ARROW_GLACIER,
215
+ SpecId::GrayGlacier => edr_eth::l1::hardfork::name::GRAY_GLACIER,
216
+ SpecId::Merge => edr_eth::l1::hardfork::name::MERGE,
217
+ SpecId::Shanghai => edr_eth::l1::hardfork::name::SHANGHAI,
218
+ SpecId::Cancun => edr_eth::l1::hardfork::name::CANCUN,
219
+ SpecId::Prague => edr_eth::l1::hardfork::name::PRAGUE,
220
+ }
221
+ }
222
+
223
+ /// Returns the latest supported OP hardfork.
224
+ ///
225
+ /// The returned value will be updated after each network upgrade.
226
+ #[napi]
227
+ pub fn l1_hardfork_latest() -> SpecId {
228
+ SpecId::Prague
229
+ }
230
+
231
+ macro_rules! export_spec_id {
232
+ ($($variant:ident),*) => {
233
+ $(
234
+ #[napi]
235
+ pub const $variant: &str = edr_eth::l1::hardfork::name::$variant;
236
+ )*
237
+ };
238
+ }
239
+
240
+ export_spec_id!(
241
+ FRONTIER,
242
+ FRONTIER_THAWING,
243
+ HOMESTEAD,
244
+ DAO_FORK,
245
+ TANGERINE,
246
+ SPURIOUS_DRAGON,
247
+ BYZANTIUM,
248
+ CONSTANTINOPLE,
249
+ PETERSBURG,
250
+ ISTANBUL,
251
+ MUIR_GLACIER,
252
+ BERLIN,
253
+ LONDON,
254
+ ARROW_GLACIER,
255
+ GRAY_GLACIER,
256
+ MERGE,
257
+ SHANGHAI,
258
+ CANCUN,
259
+ PRAGUE
260
+ );
@@ -0,0 +1,368 @@
1
+ use std::{str::FromStr, sync::Arc};
2
+
3
+ use edr_eth::hex;
4
+ use edr_napi_core::{
5
+ logger::{self, Logger},
6
+ provider::{self, ProviderBuilder, SyncProviderFactory},
7
+ subscription,
8
+ };
9
+ use edr_op::{OpChainSpec, OpSpecId};
10
+ use edr_solidity::contract_decoder::ContractDecoder;
11
+ use napi::bindgen_prelude::BigInt;
12
+ use napi_derive::napi;
13
+
14
+ use crate::{
15
+ account::{Account, StorageSlot},
16
+ provider::ProviderFactory,
17
+ };
18
+
19
+ pub struct OpProviderFactory;
20
+
21
+ impl SyncProviderFactory for OpProviderFactory {
22
+ fn create_provider_builder(
23
+ &self,
24
+ env: &napi::Env,
25
+ provider_config: provider::Config,
26
+ logger_config: logger::Config,
27
+ subscription_config: subscription::Config,
28
+ contract_decoder: Arc<ContractDecoder>,
29
+ ) -> napi::Result<Box<dyn provider::Builder>> {
30
+ let logger = Logger::<OpChainSpec>::new(logger_config, Arc::clone(&contract_decoder))?;
31
+
32
+ let provider_config = edr_provider::ProviderConfig::<OpSpecId>::try_from(provider_config)?;
33
+
34
+ let subscription_callback =
35
+ subscription::Callback::new(env, subscription_config.subscription_callback)?;
36
+
37
+ Ok(Box::new(ProviderBuilder::new(
38
+ contract_decoder,
39
+ Box::new(logger),
40
+ provider_config,
41
+ subscription_callback,
42
+ )))
43
+ }
44
+ }
45
+
46
+ /// Enumeration of supported OP hardforks.
47
+ #[napi]
48
+ pub enum OpHardfork {
49
+ Bedrock = 100,
50
+ Regolith = 101,
51
+ Canyon = 102,
52
+ Ecotone = 103,
53
+ Fjord = 104,
54
+ Granite = 105,
55
+ Holocene = 106,
56
+ Isthmus = 107,
57
+ }
58
+
59
+ impl From<OpHardfork> for OpSpecId {
60
+ fn from(hardfork: OpHardfork) -> Self {
61
+ match hardfork {
62
+ OpHardfork::Bedrock => OpSpecId::BEDROCK,
63
+ OpHardfork::Regolith => OpSpecId::REGOLITH,
64
+ OpHardfork::Canyon => OpSpecId::CANYON,
65
+ OpHardfork::Ecotone => OpSpecId::ECOTONE,
66
+ OpHardfork::Fjord => OpSpecId::FJORD,
67
+ OpHardfork::Granite => OpSpecId::GRANITE,
68
+ OpHardfork::Holocene => OpSpecId::HOLOCENE,
69
+ OpHardfork::Isthmus => OpSpecId::ISTHMUS,
70
+ }
71
+ }
72
+ }
73
+
74
+ impl FromStr for OpHardfork {
75
+ type Err = napi::Error;
76
+
77
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
78
+ match s {
79
+ edr_op::hardfork::name::BEDROCK => Ok(OpHardfork::Bedrock),
80
+ edr_op::hardfork::name::REGOLITH => Ok(OpHardfork::Regolith),
81
+ edr_op::hardfork::name::CANYON => Ok(OpHardfork::Canyon),
82
+ edr_op::hardfork::name::ECOTONE => Ok(OpHardfork::Ecotone),
83
+ edr_op::hardfork::name::FJORD => Ok(OpHardfork::Fjord),
84
+ edr_op::hardfork::name::GRANITE => Ok(OpHardfork::Granite),
85
+ edr_op::hardfork::name::HOLOCENE => Ok(OpHardfork::Holocene),
86
+ edr_op::hardfork::name::ISTHMUS => Ok(OpHardfork::Isthmus),
87
+ _ => Err(napi::Error::new(
88
+ napi::Status::InvalidArg,
89
+ format!("The provided OP hardfork `{s}` is not supported."),
90
+ )),
91
+ }
92
+ }
93
+ }
94
+
95
+ /// Tries to parse the provided string to create an [`OpHardfork`]
96
+ /// instance.
97
+ ///
98
+ /// Returns an error if the string does not match any known hardfork.
99
+ #[napi]
100
+ pub fn op_hardfork_from_string(hardfork: String) -> napi::Result<OpHardfork> {
101
+ hardfork.parse()
102
+ }
103
+
104
+ /// Returns the string representation of the provided OP hardfork.
105
+ #[napi]
106
+ pub fn op_hardfork_to_string(hardfork: OpHardfork) -> &'static str {
107
+ match hardfork {
108
+ OpHardfork::Bedrock => edr_op::hardfork::name::BEDROCK,
109
+ OpHardfork::Regolith => edr_op::hardfork::name::REGOLITH,
110
+ OpHardfork::Canyon => edr_op::hardfork::name::CANYON,
111
+ OpHardfork::Ecotone => edr_op::hardfork::name::ECOTONE,
112
+ OpHardfork::Fjord => edr_op::hardfork::name::FJORD,
113
+ OpHardfork::Granite => edr_op::hardfork::name::GRANITE,
114
+ OpHardfork::Holocene => edr_op::hardfork::name::HOLOCENE,
115
+ OpHardfork::Isthmus => edr_op::hardfork::name::ISTHMUS,
116
+ }
117
+ }
118
+
119
+ /// Returns the latest supported OP hardfork.
120
+ ///
121
+ /// The returned value will be updated after each network upgrade.
122
+ #[napi]
123
+ pub fn op_latest_hardfork() -> OpHardfork {
124
+ OpHardfork::Holocene
125
+ }
126
+
127
+ #[napi]
128
+ pub const OP_CHAIN_TYPE: &str = edr_op::CHAIN_TYPE;
129
+
130
+ #[napi]
131
+ pub fn op_genesis_state(_hardfork: OpHardfork) -> Vec<Account> {
132
+ let gas_price_oracle_code = hex::decode(include_str!(
133
+ "../../data/op/predeploys/gas_price_oracle.txt"
134
+ ))
135
+ .expect("The bytecode for the GasPriceOracle predeploy should be a valid hex string");
136
+ let gas_price_oracle = Account {
137
+ address: hex!("420000000000000000000000000000000000000F").into(),
138
+ balance: BigInt::from(0u64),
139
+ nonce: BigInt::from(0u64),
140
+ code: Some(gas_price_oracle_code.into()),
141
+ storage: vec![StorageSlot {
142
+ index: BigInt::from(0u64),
143
+ // bool isEcotone = true
144
+ // bool isFjord = true
145
+ value: BigInt::from(
146
+ 0x0000000000000000000000000000000000000000000000000000000000000101u64,
147
+ ),
148
+ }],
149
+ };
150
+
151
+ let l1_block_code = hex::decode(include_str!("../../data/op/predeploys/l1_block.txt"))
152
+ .expect("The bytecode for the L1Block predeploy should be a valid hex string");
153
+ let l1_block = Account {
154
+ address: hex!("4200000000000000000000000000000000000015").into(),
155
+ balance: BigInt::from(0u64),
156
+ nonce: BigInt::from(0u64),
157
+ code: Some(l1_block_code.into()),
158
+ storage: vec![
159
+ StorageSlot {
160
+ index: BigInt::from(0u64),
161
+ // uint64 public number = 1
162
+ // uint64 public timestamp = 1
163
+ value: BigInt {
164
+ words: vec![
165
+ 0x0000000000000001_u64, // least significative
166
+ 0x0000000000000001_u64,
167
+ ],
168
+ sign_bit: false,
169
+ },
170
+ },
171
+ StorageSlot {
172
+ index: BigInt::from(1u64),
173
+ // uint256 baseFee = 10 gwei
174
+ value: BigInt::from(0x00000002540be400_u64),
175
+ },
176
+ StorageSlot {
177
+ index: BigInt::from(2u64),
178
+ // bytes32 hash = 0
179
+ value: BigInt::from(0u64),
180
+ },
181
+ StorageSlot {
182
+ index: BigInt::from(3u64),
183
+ // uint64 sequenceNumber = 0
184
+ // uint32 blobBaseFeeScalar = 1014213
185
+ // uint32 baseFeeScalar = 5227
186
+ value: BigInt {
187
+ words: vec![
188
+ 0x0000000000000000_u64, // least significative
189
+ 0x0000000000000000_u64,
190
+ 0x00000000000f79c5_u64,
191
+ 0x000000000000146b_u64,
192
+ ],
193
+ sign_bit: false,
194
+ },
195
+ },
196
+ StorageSlot {
197
+ index: BigInt::from(4u64),
198
+ // bytes32 batcherHash = 0
199
+ value: BigInt::from(0u64),
200
+ },
201
+ StorageSlot {
202
+ index: BigInt::from(5u64),
203
+ // uint256 l1FeeOverhead = 0
204
+ value: BigInt::from(0u64),
205
+ },
206
+ StorageSlot {
207
+ index: BigInt::from(6u64),
208
+ // uint256 l1FeeScalar = 0
209
+ value: BigInt::from(0u64),
210
+ },
211
+ StorageSlot {
212
+ index: BigInt::from(7u64),
213
+ // uint256 blobBaseFee = 10 gwei
214
+ value: BigInt::from(0x00000002540be400_u64),
215
+ },
216
+ ],
217
+ };
218
+
219
+ /* The rest of the predeploys use a stubbed bytecode that reverts with a
220
+ message indicating that the predeploy is not supported. For each of
221
+ them, the Solidity code that generates the bytecode is:
222
+
223
+ // SPDX-License-Identifier: Unlicense
224
+ pragma solidity ^0.8.0;
225
+
226
+ contract NotSupported {
227
+ fallback() external payable {
228
+ revert("Predeploy <PredeployName> is not supported.");
229
+ }
230
+ }
231
+ */
232
+ let stubbed_predeploys_data = vec![
233
+ (
234
+ "LegacyMessagePasser",
235
+ hex!("4200000000000000000000000000000000000000"),
236
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602f8360bf565b91507f5072656465706c6f79204c65676163794d65737361676550617373657220697360008301527f206e6f7420737570706f727465642e00000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea26469706673582212206ba272e31c33ce6fe2612b534c5aa5ed8905e1bed8a757ff1a74cc06509a17f664736f6c63430008000033",
237
+ ),
238
+ (
239
+ "DeployerWhitelist",
240
+ hex!("4200000000000000000000000000000000000002"),
241
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602d8360bf565b91507f5072656465706c6f79204465706c6f79657257686974656c697374206973206e60008301527f6f7420737570706f727465642e000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea26469706673582212206af5fc0549e5db963a08cb2864cbbf5c4e27efb08219fc0e29bda83f84b121ac64736f6c63430008000033",
242
+ ),
243
+ (
244
+ "LegacyERC20ETH",
245
+ hex!("DeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000"),
246
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602a8360bf565b91507f5072656465706c6f79204c65676163794552433230455448206973206e6f742060008301527f737570706f727465642e000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea264697066735822122054e7f9d6c12400d5b4b67aed39be8c44a8b1461519e96a0e7764c69417239c7964736f6c63430008000033",
247
+ ),
248
+ (
249
+ "WETH9",
250
+ hex!("4200000000000000000000000000000000000006"),
251
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860218360bf565b91507f5072656465706c6f79205745544839206973206e6f7420737570706f7274656460008301527f2e000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220860ec43d585e1b040780713555b6fc492d748c73586bdb8f2b9af441c4452dbf64736f6c63430008000033",
252
+ ),
253
+ (
254
+ "L2CrossDomainMessenger",
255
+ hex!("4200000000000000000000000000000000000007"),
256
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860328360bf565b91507f5072656465706c6f79204c3243726f7373446f6d61696e4d657373656e67657260008301527f206973206e6f7420737570706f727465642e00000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea26469706673582212200fadec69889de49a1a3a14d4e7e477e00921681e12650f510863d0077c16f58864736f6c63430008000033",
257
+ ),
258
+ (
259
+ "L2StandardBridge",
260
+ hex!("4200000000000000000000000000000000000010"),
261
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602c8360bf565b91507f5072656465706c6f79204c325374616e64617264427269646765206973206e6f60008301527f7420737570706f727465642e00000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220ce5c24ee894b04d974b95cd204ab35f85906430ba6f49d1ea70d3d0c9c204cb764736f6c63430008000033",
262
+ ),
263
+ (
264
+ "SequencerFeeVault",
265
+ hex!("4200000000000000000000000000000000000011"),
266
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602d8360bf565b91507f5072656465706c6f792053657175656e6365724665655661756c74206973206e60008301527f6f7420737570706f727465642e000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea26469706673582212203990ed752a94bb02bd5162fef116c1b62079e8207c5164b3ae5a115f5cf0b31164736f6c63430008000033",
267
+ ),
268
+ (
269
+ "OptimismMintableERC20Factory",
270
+ hex!("4200000000000000000000000000000000000012"),
271
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860388360bf565b91507f5072656465706c6f79204f7074696d69736d4d696e7461626c6545524332304660008301527f6163746f7279206973206e6f7420737570706f727465642e00000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220240605543d69b93641a24f1d153969c3969089a04a162fc9f18f95de926b385564736f6c63430008000033",
272
+ ),
273
+ (
274
+ "L1BlockNumber",
275
+ hex!("4200000000000000000000000000000000000013"),
276
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860298360bf565b91507f5072656465706c6f79204c31426c6f636b4e756d626572206973206e6f74207360008301527f7570706f727465642e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea264697066735822122099ba6da366313d162bab19a497fab2200808ddd24935b9f8be496c3622110b1164736f6c63430008000033",
277
+ ),
278
+ (
279
+ "GovernanceToken",
280
+ hex!("4200000000000000000000000000000000000042"),
281
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602b8360bf565b91507f5072656465706c6f7920476f7665726e616e6365546f6b656e206973206e6f7460008301527f20737570706f727465642e0000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea26469706673582212205a22322e97c15d3a28eb86abac215ed31bcf6e0cf562e2679ce5fb3495953cfc64736f6c63430008000033",
282
+ ),
283
+ (
284
+ "L2ToL1MessagePasser",
285
+ hex!("4200000000000000000000000000000000000016"),
286
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602f8360bf565b91507f5072656465706c6f79204c32546f4c314d65737361676550617373657220697360008301527f206e6f7420737570706f727465642e00000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea26469706673582212205b2ed2ecc932d0e4a45e97ae7ac256e58848453ac06733b27890587962871a1864736f6c63430008000033",
287
+ ),
288
+ (
289
+ "L2ERC721Bridge",
290
+ hex!("4200000000000000000000000000000000000014"),
291
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602a8360bf565b91507f5072656465706c6f79204c32455243373231427269646765206973206e6f742060008301527f737570706f727465642e000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea26469706673582212203f9de306b34383b29e9dfb174fd424d7e11d31e8859d0e96a2aa3a46609e826c64736f6c63430008000033",
292
+ ),
293
+ (
294
+ "OptimismMintableERC721Factory",
295
+ hex!("4200000000000000000000000000000000000017"),
296
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860398360bf565b91507f5072656465706c6f79204f7074696d69736d4d696e7461626c6545524337323160008301527f466163746f7279206973206e6f7420737570706f727465642e000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea264697066735822122033131ae0c34f3246f5031971388431bd1dfb1b92d6b08d92a0a905911c1eeeeb64736f6c63430008000033",
297
+ ),
298
+ (
299
+ "ProxyAdmin",
300
+ hex!("4200000000000000000000000000000000000018"),
301
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860268360bf565b91507f5072656465706c6f792050726f787941646d696e206973206e6f74207375707060008301527f6f727465642e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220c7b191ff1b21c73fb6a26fd1e972d6844631a700b7a316ca2d9e04905af44dbb64736f6c63430008000033",
302
+ ),
303
+ (
304
+ "BaseFeeVault",
305
+ hex!("4200000000000000000000000000000000000019"),
306
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860288360bf565b91507f5072656465706c6f7920426173654665655661756c74206973206e6f7420737560008301527f70706f727465642e0000000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220535ae2b8a6393c0be4de1dce095f5e17fc0c7a46b40ac7793db894328f1799e764736f6c63430008000033",
307
+ ),
308
+ (
309
+ "L1FeeVault",
310
+ hex!("420000000000000000000000000000000000001a"),
311
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b6000604860268360bf565b91507f5072656465706c6f79204c314665655661756c74206973206e6f74207375707060008301527f6f727465642e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220dac6ab093c79da782b6e98ec67c48758f6c1cb80cba58e080c114a9b8c93befc64736f6c63430008000033",
312
+ ),
313
+ (
314
+ "SchemaRegistry",
315
+ hex!("4200000000000000000000000000000000000020"),
316
+ "0x60806040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160349060a1565b60405180910390fd5b60006048602a8360bf565b91507f5072656465706c6f7920536368656d615265676973747279206973206e6f742060008301527f737570706f727465642e000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015260b881603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220b3daf5355920b581943cabb92a7cc67123467fdd1b054cb0c5f0e587c08da1be64736f6c63430008000033",
317
+ ),
318
+ (
319
+ "EAS",
320
+ hex!("4200000000000000000000000000000000000021"),
321
+ "0x60806040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603490607b565b60405180910390fd5b60006048601f836099565b91507f5072656465706c6f7920454153206973206e6f7420737570706f727465642e006000830152602082019050919050565b60006020820190508181036000830152609281603d565b9050919050565b60008282526020820190509291505056fea2646970667358221220afa6c1aa54a8b3f4f979e1297db5838a94353f3b77b5ecc164da19db26ea89f564736f6c63430008000033",
322
+ ),
323
+ ];
324
+
325
+ let stubbed_predeploys = stubbed_predeploys_data
326
+ .iter()
327
+ .map(|(name, address, code)| Account {
328
+ address: address.into(),
329
+ balance: BigInt::from(0u64),
330
+ nonce: BigInt::from(0u64),
331
+ code: Some(
332
+ hex::decode(code)
333
+ .unwrap_or_else(|e| panic!("The bytecode for the {name} predeploy should be a valid hex string, got error: {e}"))
334
+ .into(),
335
+ ),
336
+ storage: vec![],
337
+ });
338
+
339
+ let predeploys = vec![gas_price_oracle, l1_block];
340
+
341
+ predeploys.into_iter().chain(stubbed_predeploys).collect()
342
+ }
343
+
344
+ #[napi]
345
+ pub fn op_provider_factory() -> ProviderFactory {
346
+ let factory: Arc<dyn SyncProviderFactory> = Arc::new(OpProviderFactory);
347
+ factory.into()
348
+ }
349
+
350
+ macro_rules! export_spec_id {
351
+ ($($variant:ident,)*) => {
352
+ $(
353
+ #[napi]
354
+ pub const $variant: &str = edr_op::hardfork::name::$variant;
355
+ )*
356
+ };
357
+ }
358
+
359
+ export_spec_id! {
360
+ BEDROCK,
361
+ REGOLITH,
362
+ CANYON,
363
+ ECOTONE,
364
+ FJORD,
365
+ GRANITE,
366
+ HOLOCENE,
367
+ ISTHMUS,
368
+ }