github.com/lmittmann/w3@v0.20.0/module/eth/get_logs.go (about) 1 package eth 2 3 import ( 4 "fmt" 5 6 "github.com/ethereum/go-ethereum" 7 "github.com/ethereum/go-ethereum/core/types" 8 "github.com/ethereum/go-ethereum/rpc" 9 "github.com/lmittmann/w3/internal/module" 10 "github.com/lmittmann/w3/w3types" 11 ) 12 13 // Logs requests the logs of the given ethereum.FilterQuery q. 14 func Logs(q ethereum.FilterQuery) w3types.RPCCallerFactory[[]types.Log] { 15 return &logsFactory{filterQuery: q} 16 } 17 18 type logsFactory struct { 19 // args 20 filterQuery ethereum.FilterQuery 21 22 // returns 23 returns *[]types.Log 24 } 25 26 func (f *logsFactory) Returns(logs *[]types.Log) w3types.RPCCaller { 27 f.returns = logs 28 return f 29 } 30 31 // CreateRequest implements the w3types.RequestCreator interface. 32 func (f *logsFactory) CreateRequest() (rpc.BatchElem, error) { 33 arg, err := toFilterArg(f.filterQuery) 34 if err != nil { 35 return rpc.BatchElem{}, err 36 } 37 38 return rpc.BatchElem{ 39 Method: "eth_getLogs", 40 Args: []any{arg}, 41 Result: f.returns, 42 }, nil 43 } 44 45 // HandleResponse implements the w3types.ResponseHandler interface. 46 func (f *logsFactory) HandleResponse(elem rpc.BatchElem) error { 47 if err := elem.Error; err != nil { 48 return err 49 } 50 return nil 51 } 52 53 func toFilterArg(q ethereum.FilterQuery) (any, error) { 54 arg := map[string]any{ 55 "topics": q.Topics, 56 } 57 if len(q.Addresses) > 0 { 58 arg["address"] = q.Addresses 59 } 60 if q.BlockHash != nil { 61 arg["blockHash"] = *q.BlockHash 62 if q.FromBlock != nil || q.ToBlock != nil { 63 return nil, fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock") 64 } 65 } else { 66 if q.FromBlock == nil { 67 arg["fromBlock"] = "0x0" 68 } else { 69 arg["fromBlock"] = module.BlockNumberArg(q.FromBlock) 70 } 71 arg["toBlock"] = module.BlockNumberArg(q.ToBlock) 72 } 73 return arg, nil 74 }