@@ -584,6 +584,64 @@ defmodule Ethers do
584584 end
585585 end
586586
587+ @ doc """
588+ Fetches event logs for all events in a contract's EventFilters module.
589+
590+ This function is useful when you want to get all events from a contract without
591+ specifying a single event filter. It will automatically decode each log using
592+ the appropriate event selector from the EventFilters module.
593+
594+ ## Parameters
595+ - event_filters_module: The EventFilters module (e.g. `MyContract.EventFilters`)
596+ - address: The contract address to filter events from (nil means all contracts)
597+
598+ ## Overrides and Options
599+
600+ - `:rpc_client`: The RPC Client to use. It should implement ethereum jsonRPC API. default: Ethereumex.HttpClient
601+ - `:rpc_opts`: Extra options to pass to rpc_client. (Like timeout, Server URL, etc.)
602+ - `:fromBlock` | `:from_block`: Minimum block number of logs to filter.
603+ - `:toBlock` | `:to_block`: Maximum block number of logs to filter.
604+
605+ ## Examples
606+
607+ ```elixir
608+ # Get all events from a contract
609+ {:ok, events} = Ethers.get_logs_for_contract(MyContract.EventFilters, "0x1234...")
610+
611+ # Get all events with block range
612+ {:ok, events} = Ethers.get_logs_for_contract(MyContract.EventFilters, "0x1234...",
613+ fromBlock: 1000,
614+ toBlock: 2000
615+ )
616+ ```
617+ """
618+ @ spec get_logs_for_contract ( module ( ) , Types . t_address ( ) | nil , Keyword . t ( ) ) ::
619+ { :ok , [ Event . t ( ) ] } | { :error , atom ( ) }
620+ def get_logs_for_contract ( event_filters_module , address , overrides \\ [ ] ) do
621+ overrides = Keyword . put ( overrides , :address , address )
622+ { opts , overrides } = Keyword . split ( overrides , @ option_keys )
623+
624+ { rpc_client , rpc_opts } = get_rpc_client ( opts )
625+
626+ with { :ok , log_params } <-
627+ pre_process ( event_filters_module , overrides , :get_logs_for_contract , opts ) do
628+ rpc_client . eth_get_logs ( log_params , rpc_opts )
629+ |> post_process ( event_filters_module , :get_logs_for_contract )
630+ end
631+ end
632+
633+ @ doc """
634+ Same as `Ethers.get_logs_for_contract/3` but raises on error.
635+ """
636+ @ spec get_logs_for_contract! ( module ( ) , Types . t_address ( ) | nil , Keyword . t ( ) ) ::
637+ [ Event . t ( ) ] | no_return
638+ def get_logs_for_contract! ( event_filters_module , address , overrides \\ [ ] ) do
639+ case get_logs_for_contract ( event_filters_module , address , overrides ) do
640+ { :ok , events } -> events
641+ { :error , reason } -> raise ExecutionError , reason
642+ end
643+ end
644+
587645 @ doc """
588646 Combines multiple requests and make a batch json RPC request.
589647
@@ -744,6 +802,18 @@ defmodule Ethers do
744802 end
745803 end
746804
805+ defp pre_process ( _event_filters_module , overrides , :get_logs_for_contract , _opts ) do
806+ log_params =
807+ overrides
808+ |> Enum . into ( % { } )
809+ |> ensure_hex_value ( :fromBlock )
810+ |> ensure_hex_value ( :from_block )
811+ |> ensure_hex_value ( :toBlock )
812+ |> ensure_hex_value ( :to_block )
813+
814+ { :ok , log_params }
815+ end
816+
747817 defp pre_process ( event_filter , overrides , :get_logs , _opts ) do
748818 log_params =
749819 event_filter
@@ -806,6 +876,23 @@ defmodule Ethers do
806876 { :ok , resp }
807877 end
808878
879+ defp post_process ( { :ok , resp } , event_filters_module , :get_logs_for_contract )
880+ when is_list ( resp ) do
881+ logs =
882+ Enum . flat_map ( resp , fn log ->
883+ case Event . find_and_decode ( log , event_filters_module ) do
884+ { :ok , decoded_log } -> [ decoded_log ]
885+ { :error , :not_found } -> [ ]
886+ end
887+ end )
888+
889+ { :ok , logs }
890+ end
891+
892+ defp post_process ( { :ok , resp } , _event_filters_module , :get_logs_for_contract ) do
893+ { :ok , resp }
894+ end
895+
809896 defp post_process ( { :ok , % { "contractAddress" => contract_address } } , _tx_hash , :deployed_address )
810897 when not is_nil ( contract_address ) ,
811898 do: { :ok , contract_address }
0 commit comments