web3 7.5.0__py3-none-any.whl → 7.6.1__py3-none-any.whl

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.
web3/contract/contract.py CHANGED
@@ -1,4 +1,3 @@
1
- import copy
2
1
  from typing import (
3
2
  TYPE_CHECKING,
4
3
  Any,
@@ -14,13 +13,14 @@ from typing import (
14
13
 
15
14
  from eth_typing import (
16
15
  ABI,
17
- ABIEvent,
16
+ ABIFunction,
18
17
  ChecksumAddress,
19
18
  )
20
19
  from eth_utils import (
20
+ abi_to_signature,
21
21
  combomethod,
22
+ filter_abi_by_type,
22
23
  get_abi_input_names,
23
- get_all_function_abis,
24
24
  )
25
25
  from eth_utils.toolz import (
26
26
  partial,
@@ -31,6 +31,7 @@ from hexbytes import (
31
31
 
32
32
  from web3._utils.abi import (
33
33
  fallback_func_abi_exists,
34
+ get_name_from_abi_element_identifier,
34
35
  receive_func_abi_exists,
35
36
  )
36
37
  from web3._utils.abi_element_identifiers import (
@@ -41,6 +42,8 @@ from web3._utils.compat import (
41
42
  Self,
42
43
  )
43
44
  from web3._utils.contracts import (
45
+ copy_contract_event,
46
+ copy_contract_function,
44
47
  parse_block_identifier,
45
48
  )
46
49
  from web3._utils.datatypes import (
@@ -83,7 +86,10 @@ from web3.contract.utils import (
83
86
  transact_with_contract_function,
84
87
  )
85
88
  from web3.exceptions import (
89
+ ABIEventNotFound,
86
90
  ABIFunctionNotFound,
91
+ MismatchedABI,
92
+ NoABIEventsFound,
87
93
  NoABIFound,
88
94
  NoABIFunctionsFound,
89
95
  Web3AttributeError,
@@ -98,6 +104,9 @@ from web3.types import (
98
104
  TxParams,
99
105
  )
100
106
  from web3.utils.abi import (
107
+ _filter_by_argument_count,
108
+ _get_any_abi_signature_with_name,
109
+ _mismatched_abi_error_diagnosis,
101
110
  get_abi_element,
102
111
  )
103
112
 
@@ -110,16 +119,8 @@ class ContractEvent(BaseContractEvent):
110
119
  # mypy types
111
120
  w3: "Web3"
112
121
 
113
- def __call__(self) -> "ContractEvent":
114
- clone = copy.copy(self)
115
-
116
- if not self.abi:
117
- self.abi = cast(
118
- ABIEvent,
119
- get_abi_element(self.contract_abi, self.event_name),
120
- )
121
-
122
- return clone
122
+ def __call__(self, *args: Any, **kwargs: Any) -> "ContractEvent":
123
+ return copy_contract_event(self, *args, **kwargs)
123
124
 
124
125
  @combomethod
125
126
  def get_logs(
@@ -186,7 +187,6 @@ class ContractEvent(BaseContractEvent):
186
187
  :yield: Tuple of :class:`AttributeDict` instances
187
188
  """
188
189
  event_abi = self._get_event_abi()
189
-
190
190
  # validate ``argument_filters`` if present
191
191
  if argument_filters is not None:
192
192
  event_arg_names = get_abi_input_names(event_abi)
@@ -228,7 +228,8 @@ class ContractEvent(BaseContractEvent):
228
228
  """
229
229
  Create filter object that tracks logs emitted by this contract event.
230
230
  """
231
- filter_builder = EventFilterBuilder(self._get_event_abi(), self.w3.codec)
231
+ abi = self._get_event_abi()
232
+ filter_builder = EventFilterBuilder(abi, self.w3.codec)
232
233
  self._set_up_filter_builder(
233
234
  argument_filters,
234
235
  from_block,
@@ -238,28 +239,25 @@ class ContractEvent(BaseContractEvent):
238
239
  filter_builder,
239
240
  )
240
241
  log_filter = filter_builder.deploy(self.w3)
241
- log_filter.log_entry_formatter = get_event_data(
242
- self.w3.codec, self._get_event_abi()
243
- )
242
+ log_filter.log_entry_formatter = get_event_data(self.w3.codec, abi)
244
243
  log_filter.builder = filter_builder
245
244
 
246
245
  return log_filter
247
246
 
248
247
  @combomethod
249
248
  def build_filter(self) -> EventFilterBuilder:
249
+ abi = self._get_event_abi()
250
250
  builder = EventFilterBuilder(
251
- self._get_event_abi(),
251
+ abi,
252
252
  self.w3.codec,
253
- formatter=get_event_data(self.w3.codec, self._get_event_abi()),
253
+ formatter=get_event_data(self.w3.codec, abi),
254
254
  )
255
255
  builder.address = self.address
256
256
  return builder
257
257
 
258
258
  @classmethod
259
259
  def factory(cls, class_name: str, **kwargs: Any) -> Self:
260
- return PropertyCheckingFactory(class_name, (cls,), kwargs)(
261
- abi=kwargs.get("abi")
262
- )
260
+ return PropertyCheckingFactory(class_name, (cls,), kwargs)()
263
261
 
264
262
 
265
263
  class ContractEvents(BaseContractEvents):
@@ -268,33 +266,155 @@ class ContractEvents(BaseContractEvents):
268
266
  ) -> None:
269
267
  super().__init__(abi, w3, ContractEvent, address)
270
268
 
269
+ def __getattr__(self, event_name: str) -> "ContractEvent":
270
+ if super().__getattribute__("abi") is None:
271
+ raise NoABIFound(
272
+ "There is no ABI found for this contract.",
273
+ )
274
+ elif "_events" not in self.__dict__ or len(self._events) == 0:
275
+ raise NoABIEventsFound(
276
+ "The abi for this contract contains no event definitions. ",
277
+ "Are you sure you provided the correct contract abi?",
278
+ )
279
+ elif get_name_from_abi_element_identifier(event_name) not in [
280
+ get_name_from_abi_element_identifier(event["name"])
281
+ for event in self._events
282
+ ]:
283
+ raise ABIEventNotFound(
284
+ f"The event '{event_name}' was not found in this contract's abi. ",
285
+ "Are you sure you provided the correct contract abi?",
286
+ )
287
+
288
+ if "(" not in event_name:
289
+ event_name = _get_any_abi_signature_with_name(event_name, self._events)
290
+ else:
291
+ event_name = f"_{event_name}"
292
+
293
+ return super().__getattribute__(event_name)
294
+
295
+ def __getitem__(self, event_name: str) -> "ContractEvent":
296
+ return getattr(self, event_name)
297
+
298
+ def __iter__(self) -> Iterable["ContractEvent"]:
299
+ if not hasattr(self, "_events") or not self._events:
300
+ return
301
+
302
+ for event in self._events:
303
+ yield self[abi_to_signature(event)]
304
+
271
305
 
272
306
  class ContractFunction(BaseContractFunction):
273
307
  # mypy types
274
308
  w3: "Web3"
275
309
 
276
310
  def __call__(self, *args: Any, **kwargs: Any) -> "ContractFunction":
277
- clone = copy.copy(self)
278
- if args is None:
279
- clone.args = tuple()
280
- else:
281
- clone.args = args
311
+ # When a function is called, check arguments to obtain the correct function
312
+ # in the contract. self will be used if all args and kwargs are
313
+ # encodable to self.abi, otherwise the correct function is obtained from
314
+ # the contract.
315
+ if (
316
+ self.abi_element_identifier in [FallbackFn, ReceiveFn]
317
+ or self.abi_element_identifier == "constructor"
318
+ ):
319
+ return copy_contract_function(self, *args, **kwargs)
320
+
321
+ all_functions = cast(
322
+ List[ABIFunction],
323
+ filter_abi_by_type(
324
+ "function",
325
+ self.contract_abi,
326
+ ),
327
+ )
328
+ # Filter functions by name to obtain function signatures
329
+ function_name = get_name_from_abi_element_identifier(
330
+ self.abi_element_identifier
331
+ )
332
+ function_abis = [
333
+ function for function in all_functions if function["name"] == function_name
334
+ ]
335
+ num_args = len(args) + len(kwargs)
336
+ function_abis_with_arg_count = cast(
337
+ List[ABIFunction],
338
+ _filter_by_argument_count(
339
+ num_args,
340
+ function_abis,
341
+ ),
342
+ )
282
343
 
283
- if kwargs is None:
284
- clone.kwargs = {}
344
+ if not len(function_abis_with_arg_count):
345
+ # Build an ABI without arguments to determine if one exists
346
+ function_abis_with_arg_count = [
347
+ ABIFunction({"type": "function", "name": function_name})
348
+ ]
349
+
350
+ # Check that arguments in call match a function ABI
351
+ num_attempts = 0
352
+ function_abi_matches = []
353
+ contract_function = None
354
+ for abi in function_abis_with_arg_count:
355
+ try:
356
+ num_attempts += 1
357
+
358
+ # Search for a function ABI that matches the arguments used
359
+ function_abi_matches.append(
360
+ cast(
361
+ ABIFunction,
362
+ get_abi_element(
363
+ function_abis,
364
+ abi_to_signature(abi),
365
+ *args,
366
+ abi_codec=self.w3.codec,
367
+ **kwargs,
368
+ ),
369
+ )
370
+ )
371
+ except MismatchedABI:
372
+ # ignore exceptions
373
+ continue
374
+
375
+ if len(function_abi_matches) == 1:
376
+ function_abi = function_abi_matches[0]
377
+ if abi_to_signature(self.abi) == abi_to_signature(function_abi):
378
+ contract_function = self
379
+ else:
380
+ # Found a match that is not self
381
+ contract_function = ContractFunction.factory(
382
+ abi_to_signature(function_abi),
383
+ w3=self.w3,
384
+ contract_abi=self.contract_abi,
385
+ address=self.address,
386
+ abi_element_identifier=abi_to_signature(function_abi),
387
+ abi=function_abi,
388
+ )
285
389
  else:
286
- clone.kwargs = kwargs
287
- clone._set_function_info()
288
- return clone
390
+ for abi in function_abi_matches:
391
+ if abi_to_signature(self.abi) == abi_to_signature(abi):
392
+ contract_function = self
393
+ break
394
+ else:
395
+ # Raise exception if multiple found
396
+ raise MismatchedABI(
397
+ _mismatched_abi_error_diagnosis(
398
+ function_name,
399
+ self.contract_abi,
400
+ len(function_abi_matches),
401
+ num_args,
402
+ *args,
403
+ abi_codec=self.w3.codec,
404
+ **kwargs,
405
+ )
406
+ )
407
+
408
+ return copy_contract_function(contract_function, *args, **kwargs)
289
409
 
290
410
  @classmethod
291
411
  def factory(cls, class_name: str, **kwargs: Any) -> Self:
292
- return PropertyCheckingFactory(class_name, (cls,), kwargs)(kwargs.get("abi"))
412
+ return PropertyCheckingFactory(class_name, (cls,), kwargs)()
293
413
 
294
414
  def call(
295
415
  self,
296
416
  transaction: Optional[TxParams] = None,
297
- block_identifier: BlockIdentifier = None,
417
+ block_identifier: Optional[BlockIdentifier] = None,
298
418
  state_override: Optional[StateOverride] = None,
299
419
  ccip_read_enabled: Optional[bool] = None,
300
420
  ) -> Any:
@@ -319,9 +439,9 @@ class ContractFunction(BaseContractFunction):
319
439
  addr = contract.functions.owner().call()
320
440
 
321
441
  :param transaction: Dictionary of transaction info for web3 interface
322
- :param block_identifier: TODO
323
- :param state_override TODO
324
- :param ccip_read_enabled TODO
442
+ :param block_identifier: Block number or string "latest", "pending", "earliest"
443
+ :param state_override: Dictionary of state override values
444
+ :param ccip_read_enabled: Enable CCIP read operations for the call
325
445
  :return: ``Caller`` object that has contract public functions
326
446
  and variables exposed as Python methods
327
447
  """
@@ -329,11 +449,13 @@ class ContractFunction(BaseContractFunction):
329
449
 
330
450
  block_id = parse_block_identifier(self.w3, block_identifier)
331
451
 
452
+ abi_element_identifier = abi_to_signature(self.abi)
453
+
332
454
  return call_contract_function(
333
455
  self.w3,
334
456
  self.address,
335
457
  self._return_data_normalizers,
336
- self.abi_element_identifier,
458
+ abi_element_identifier,
337
459
  call_transaction,
338
460
  block_id,
339
461
  self.contract_abi,
@@ -347,11 +469,12 @@ class ContractFunction(BaseContractFunction):
347
469
 
348
470
  def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
349
471
  setup_transaction = self._transact(transaction)
472
+ abi_element_identifier = abi_to_signature(self.abi)
350
473
 
351
474
  return transact_with_contract_function(
352
475
  self.address,
353
476
  self.w3,
354
- self.abi_element_identifier,
477
+ abi_element_identifier,
355
478
  setup_transaction,
356
479
  self.contract_abi,
357
480
  self.abi,
@@ -366,10 +489,11 @@ class ContractFunction(BaseContractFunction):
366
489
  state_override: Optional[StateOverride] = None,
367
490
  ) -> int:
368
491
  setup_transaction = self._estimate_gas(transaction)
492
+ abi_element_identifier = abi_to_signature(self.abi)
369
493
  return estimate_gas_for_function(
370
494
  self.address,
371
495
  self.w3,
372
- self.abi_element_identifier,
496
+ abi_element_identifier,
373
497
  setup_transaction,
374
498
  self.contract_abi,
375
499
  self.abi,
@@ -381,11 +505,12 @@ class ContractFunction(BaseContractFunction):
381
505
 
382
506
  def build_transaction(self, transaction: Optional[TxParams] = None) -> TxParams:
383
507
  built_transaction = self._build_transaction(transaction)
508
+ abi_element_identifier = abi_to_signature(self.abi)
384
509
 
385
510
  return build_transaction_for_function(
386
511
  self.address,
387
512
  self.w3,
388
- self.abi_element_identifier,
513
+ abi_element_identifier,
389
514
  built_transaction,
390
515
  self.contract_abi,
391
516
  self.abi,
@@ -400,12 +525,14 @@ class ContractFunction(BaseContractFunction):
400
525
  address: Optional[ChecksumAddress] = None,
401
526
  ) -> "ContractFunction":
402
527
  if abi and fallback_func_abi_exists(abi):
528
+ fallback_abi = filter_abi_by_type("fallback", abi)[0]
403
529
  return ContractFunction.factory(
404
530
  "fallback",
405
531
  w3=w3,
406
532
  contract_abi=abi,
407
533
  address=address,
408
534
  abi_element_identifier=FallbackFn,
535
+ abi=fallback_abi,
409
536
  )()
410
537
  return cast(ContractFunction, NonExistentFallbackFunction())
411
538
 
@@ -416,12 +543,14 @@ class ContractFunction(BaseContractFunction):
416
543
  address: Optional[ChecksumAddress] = None,
417
544
  ) -> "ContractFunction":
418
545
  if abi and receive_func_abi_exists(abi):
546
+ receive_abi = filter_abi_by_type("receive", abi)[0]
419
547
  return ContractFunction.factory(
420
548
  "receive",
421
549
  w3=w3,
422
550
  contract_abi=abi,
423
551
  address=address,
424
552
  abi_element_identifier=ReceiveFn,
553
+ abi=receive_abi,
425
554
  )()
426
555
  return cast(ContractFunction, NonExistentReceiveFunction())
427
556
 
@@ -436,23 +565,45 @@ class ContractFunctions(BaseContractFunctions):
436
565
  ) -> None:
437
566
  super().__init__(abi, w3, ContractFunction, address, decode_tuples)
438
567
 
568
+ def __iter__(self) -> Iterable["ContractFunction"]:
569
+ if not hasattr(self, "_functions") or not self._functions:
570
+ return
571
+
572
+ for func in self._functions:
573
+ yield self[abi_to_signature(func)]
574
+
439
575
  def __getattr__(self, function_name: str) -> "ContractFunction":
440
- if self.abi is None:
576
+ if super().__getattribute__("abi") is None:
441
577
  raise NoABIFound(
442
578
  "There is no ABI found for this contract.",
443
579
  )
444
- if "_functions" not in self.__dict__:
580
+ elif "_functions" not in self.__dict__ or len(self._functions) == 0:
445
581
  raise NoABIFunctionsFound(
446
582
  "The abi for this contract contains no function definitions. ",
447
583
  "Are you sure you provided the correct contract abi?",
448
584
  )
449
- elif function_name not in self.__dict__["_functions"]:
585
+ elif get_name_from_abi_element_identifier(function_name) not in [
586
+ get_name_from_abi_element_identifier(function["name"])
587
+ for function in self._functions
588
+ ]:
450
589
  raise ABIFunctionNotFound(
451
- f"The function '{function_name}' was not found in this contract's abi.",
452
- " Are you sure you provided the correct contract abi?",
590
+ f"The function '{function_name}' was not found in this ",
591
+ "contract's abi.",
592
+ )
593
+
594
+ if "(" not in function_name:
595
+ function_name = _get_any_abi_signature_with_name(
596
+ function_name, self._functions
453
597
  )
454
598
  else:
455
- return super().__getattribute__(function_name)
599
+ function_name = f"_{function_name}"
600
+
601
+ return super().__getattribute__(
602
+ function_name,
603
+ )
604
+
605
+ def __getitem__(self, function_name: str) -> "ContractFunction":
606
+ return getattr(self, function_name)
456
607
 
457
608
 
458
609
  class Contract(BaseContract):
@@ -477,7 +628,8 @@ class Contract(BaseContract):
477
628
  )
478
629
 
479
630
  if address:
480
- self.address = normalize_address(cast("ENS", _w3.ens), address)
631
+ # invoke ``w3._ens`` over ``w3.ens`` to avoid premature instantiation
632
+ self.address = normalize_address(cast("ENS", _w3._ens), address)
481
633
 
482
634
  if not self.address:
483
635
  raise Web3TypeError(
@@ -488,7 +640,11 @@ class Contract(BaseContract):
488
640
  self.abi, _w3, self.address, decode_tuples=self.decode_tuples
489
641
  )
490
642
  self.caller = ContractCaller(
491
- self.abi, _w3, self.address, decode_tuples=self.decode_tuples
643
+ self.abi,
644
+ _w3,
645
+ self.address,
646
+ decode_tuples=self.decode_tuples,
647
+ contract_functions=self.functions,
492
648
  )
493
649
  self.events = ContractEvents(self.abi, _w3, self.address)
494
650
  self.fallback = Contract.get_fallback_function(
@@ -512,7 +668,8 @@ class Contract(BaseContract):
512
668
 
513
669
  normalizers = {
514
670
  "abi": normalize_abi,
515
- "address": partial(normalize_address, w3.ens),
671
+ # invoke ``w3._ens`` over ``w3.ens`` to avoid premature instantiation
672
+ "address": partial(normalize_address, w3._ens),
516
673
  "bytecode": normalize_bytecode,
517
674
  "bytecode_runtime": normalize_bytecode,
518
675
  }
@@ -526,6 +683,16 @@ class Contract(BaseContract):
526
683
  normalizers=normalizers,
527
684
  ),
528
685
  )
686
+
687
+ if contract.abi:
688
+ for abi in contract.abi:
689
+ abi_name = abi.get("name")
690
+ if abi_name in ["abi", "address"]:
691
+ raise Web3AttributeError(
692
+ f"Contract contains a reserved word `{abi_name}` "
693
+ f"and could not be instantiated."
694
+ )
695
+
529
696
  contract.functions = ContractFunctions(
530
697
  contract.abi, contract.w3, decode_tuples=contract.decode_tuples
531
698
  )
@@ -534,6 +701,7 @@ class Contract(BaseContract):
534
701
  contract.w3,
535
702
  contract.address,
536
703
  decode_tuples=contract.decode_tuples,
704
+ contract_functions=contract.functions,
537
705
  )
538
706
  contract.events = ContractEvents(contract.abi, contract.w3)
539
707
  contract.fallback = Contract.get_fallback_function(
@@ -599,7 +767,7 @@ class Contract(BaseContract):
599
767
 
600
768
  @combomethod
601
769
  def get_event_by_identifier(
602
- cls, events: Sequence["ContractEvent"], identifier: str
770
+ self, events: Sequence["ContractEvent"], identifier: str
603
771
  ) -> "ContractEvent":
604
772
  return get_event_by_identifier(events, identifier)
605
773
 
@@ -617,6 +785,7 @@ class ContractCaller(BaseContractCaller):
617
785
  block_identifier: BlockIdentifier = None,
618
786
  ccip_read_enabled: Optional[bool] = None,
619
787
  decode_tuples: Optional[bool] = False,
788
+ contract_functions: Optional[ContractFunctions] = None,
620
789
  ) -> None:
621
790
  super().__init__(abi, w3, address, decode_tuples=decode_tuples)
622
791
 
@@ -624,18 +793,13 @@ class ContractCaller(BaseContractCaller):
624
793
  if transaction is None:
625
794
  transaction = {}
626
795
 
627
- self._functions = get_all_function_abis(self.abi)
628
-
629
- for func in self._functions:
630
- fn = ContractFunction.factory(
631
- func["name"],
632
- w3=w3,
633
- contract_abi=self.abi,
634
- address=self.address,
635
- abi_element_identifier=func["name"],
636
- decode_tuples=decode_tuples,
796
+ if contract_functions is None:
797
+ contract_functions = ContractFunctions(
798
+ abi, w3, address=address, decode_tuples=decode_tuples
637
799
  )
638
800
 
801
+ self._functions = contract_functions._functions
802
+ for fn in contract_functions.__iter__():
639
803
  caller_method = partial(
640
804
  self.call_function,
641
805
  fn,
@@ -643,8 +807,7 @@ class ContractCaller(BaseContractCaller):
643
807
  block_identifier=block_identifier,
644
808
  ccip_read_enabled=ccip_read_enabled,
645
809
  )
646
-
647
- setattr(self, func["name"], caller_method)
810
+ setattr(self, str(fn.abi_element_identifier), caller_method)
648
811
 
649
812
  def __call__(
650
813
  self,
web3/contract/utils.py CHANGED
@@ -23,6 +23,7 @@ from eth_typing import (
23
23
  TypeStr,
24
24
  )
25
25
  from eth_utils.abi import (
26
+ abi_to_signature,
26
27
  filter_abi_by_type,
27
28
  get_abi_output_types,
28
29
  )
@@ -342,14 +343,17 @@ def find_functions_by_identifier(
342
343
  """
343
344
  Given a contract ABI, return a list of TContractFunction instances.
344
345
  """
345
- fns_abi = filter_abi_by_type("function", contract_abi)
346
+ fns_abi = sorted(
347
+ filter_abi_by_type("function", contract_abi),
348
+ key=lambda fn: (fn["name"], len(fn.get("inputs", []))),
349
+ )
346
350
  return [
347
351
  function_type.factory(
348
- fn_abi["name"],
352
+ abi_to_signature(fn_abi),
349
353
  w3=w3,
350
354
  contract_abi=contract_abi,
351
355
  address=address,
352
- abi_element_identifier=fn_abi["name"],
356
+ abi_element_identifier=abi_to_signature(fn_abi),
353
357
  abi=fn_abi,
354
358
  )
355
359
  for fn_abi in fns_abi
web3/eth/async_eth.py CHANGED
@@ -127,6 +127,17 @@ class AsyncEth(BaseEth):
127
127
  async def accounts(self) -> Tuple[ChecksumAddress]:
128
128
  return await self._accounts()
129
129
 
130
+ # eth_blobBaseFee
131
+
132
+ _eth_blobBaseFee: Method[Callable[[], Awaitable[Wei]]] = Method(
133
+ RPC.eth_blobBaseFee,
134
+ is_property=True,
135
+ )
136
+
137
+ @property
138
+ async def blob_base_fee(self) -> Wei:
139
+ return await self._eth_blobBaseFee()
140
+
130
141
  # eth_blockNumber
131
142
 
132
143
  get_block_number: Method[Callable[[], Awaitable[BlockNumber]]] = Method(
web3/eth/eth.py CHANGED
@@ -119,6 +119,17 @@ class Eth(BaseEth):
119
119
  def accounts(self) -> Tuple[ChecksumAddress]:
120
120
  return self._accounts()
121
121
 
122
+ # eth_blobBaseFee
123
+
124
+ _eth_blobBaseFee: Method[Callable[[], Wei]] = Method(
125
+ RPC.eth_blobBaseFee,
126
+ is_property=True,
127
+ )
128
+
129
+ @property
130
+ def blob_base_fee(self) -> Wei:
131
+ return self._eth_blobBaseFee()
132
+
122
133
  # eth_blockNumber
123
134
 
124
135
  get_block_number: Method[Callable[[], BlockNumber]] = Method(
@@ -246,6 +246,7 @@ API_ENDPOINTS = {
246
246
  "chainId": static_return(131277322940537), # from fixture generation file
247
247
  "feeHistory": call_eth_tester("get_fee_history"),
248
248
  "maxPriorityFeePerGas": static_return(10**9),
249
+ "blobBaseFee": static_return(10**9),
249
250
  "gasPrice": static_return(10**9), # must be >= base fee post-London
250
251
  "accounts": call_eth_tester("get_accounts"),
251
252
  "blockNumber": compose(
web3/providers/ipc.py CHANGED
@@ -164,7 +164,7 @@ class IPCProvider(JSONBaseProvider):
164
164
  def _make_request(self, request: bytes) -> RPCResponse:
165
165
  with self._lock, self._socket as sock:
166
166
  try:
167
- sock.sendall(request)
167
+ sock.sendall(request + b"\n")
168
168
  except BrokenPipeError:
169
169
  # one extra attempt, then give up
170
170
  sock = self._socket.reset()
@@ -116,7 +116,7 @@ class AsyncIPCProvider(PersistentConnectionProvider):
116
116
 
117
117
  async def _socket_send(self, request_data: bytes) -> None:
118
118
  try:
119
- self._writer.write(request_data)
119
+ self._writer.write(request_data + b"\n")
120
120
  await self._writer.drain()
121
121
  except OSError as e:
122
122
  # Broken pipe