accounts/abi/bind/v2: infer event name from type

This commit is contained in:
Felix Lange 2025-01-28 00:53:34 +01:00
parent c452fb10f0
commit 47784b98b1
4 changed files with 32 additions and 9 deletions

View file

@ -208,6 +208,10 @@ type DBInsert struct {
const DBInsertEventName = "Insert"
func (DBInsert) ContractEventName() string {
return DBInsertEventName
}
func (dB *DB) UnpackInsertEvent(log *types.Log) (*DBInsert, error) {
event := "Insert"
if log.Topics[0] != dB.abi.Events[event].ID {
@ -241,6 +245,10 @@ type DBKeyedInsert struct {
const DBKeyedInsertEventName = "KeyedInsert"
func (DBKeyedInsert) ContractEventName() string {
return DBKeyedInsertEventName
}
func (dB *DB) UnpackKeyedInsertEvent(log *types.Log) (*DBKeyedInsert, error) {
event := "KeyedInsert"
if log.Topics[0] != dB.abi.Events[event].ID {

View file

@ -148,6 +148,10 @@ type CBasic1 struct {
const CBasic1EventName = "basic1"
func (CBasic1) ContractEventName() string {
return CBasic1EventName
}
func (c *C) UnpackBasic1Event(log *types.Log) (*CBasic1, error) {
event := "basic1"
if log.Topics[0] != c.abi.Events[event].ID {
@ -181,6 +185,10 @@ type CBasic2 struct {
const CBasic2EventName = "basic2"
func (CBasic2) ContractEventName() string {
return CBasic2EventName
}
func (c *C) UnpackBasic2Event(log *types.Log) (*CBasic2, error) {
event := "basic2"
if log.Topics[0] != c.abi.Events[event].ID {

View file

@ -31,21 +31,28 @@ func NewContractInstance(backend ContractBackend, addr common.Address, abi abi.A
return NewBoundContract(addr, abi, backend, backend, backend)
}
// ContractEvent is a type constraint for ABI event types.
type ContractEvent interface {
ContractEventName() string
}
// FilterEvents returns an EventIterator instance for filtering historical events based on the event id and a block range.
func FilterEvents[T any](c *BoundContract, opts *FilterOpts, eventName string, unpack func(*types.Log) (*T, error), topics ...[]any) (*EventIterator[T], error) {
logs, sub, err := c.FilterLogs(opts, eventName, topics...)
func FilterEvents[Ev ContractEvent](c *BoundContract, opts *FilterOpts, unpack func(*types.Log) (*Ev, error), topics ...[]any) (*EventIterator[Ev], error) {
var e Ev
logs, sub, err := c.FilterLogs(opts, e.ContractEventName(), topics...)
if err != nil {
return nil, err
}
return &EventIterator[T]{unpack: unpack, logs: logs, sub: sub}, nil
return &EventIterator[Ev]{unpack: unpack, logs: logs, sub: sub}, nil
}
// WatchEvents causes logs emitted with a given event id from a specified
// contract to be intercepted, unpacked, and forwarded to sink. If
// unpack returns an error, the returned subscription is closed with the
// error.
func WatchEvents[T any](c *BoundContract, opts *WatchOpts, eventName string, unpack func(*types.Log) (*T, error), sink chan<- *T, topics ...[]any) (event.Subscription, error) {
logs, sub, err := c.WatchLogs(opts, eventName, topics...)
func WatchEvents[Ev ContractEvent](c *BoundContract, opts *WatchOpts, unpack func(*types.Log) (*Ev, error), sink chan<- *Ev, topics ...[]any) (event.Subscription, error) {
var e Ev
logs, sub, err := c.WatchLogs(opts, e.ContractEventName(), topics...)
if err != nil {
return nil, err
}

View file

@ -233,11 +233,11 @@ func TestEvents(t *testing.T) {
newCBasic1Ch := make(chan *events.CBasic1)
newCBasic2Ch := make(chan *events.CBasic2)
watchOpts := &bind.WatchOpts{}
sub1, err := bind.WatchEvents(instance, watchOpts, events.CBasic1EventName, c.UnpackBasic1Event, newCBasic1Ch)
sub1, err := bind.WatchEvents(instance, watchOpts, c.UnpackBasic1Event, newCBasic1Ch)
if err != nil {
t.Fatalf("WatchEvents returned error: %v", err)
}
sub2, err := bind.WatchEvents(instance, watchOpts, events.CBasic2EventName, c.UnpackBasic2Event, newCBasic2Ch)
sub2, err := bind.WatchEvents(instance, watchOpts, c.UnpackBasic2Event, newCBasic2Ch)
if err != nil {
t.Fatalf("WatchEvents returned error: %v", err)
}
@ -284,11 +284,11 @@ done:
Start: 0,
Context: context.Background(),
}
it, err := bind.FilterEvents(instance, filterOpts, events.CBasic1EventName, c.UnpackBasic1Event)
it, err := bind.FilterEvents(instance, filterOpts, c.UnpackBasic1Event)
if err != nil {
t.Fatalf("error filtering logs %v\n", err)
}
it2, err := bind.FilterEvents(instance, filterOpts, events.CBasic2EventName, c.UnpackBasic2Event)
it2, err := bind.FilterEvents(instance, filterOpts, c.UnpackBasic2Event)
if err != nil {
t.Fatalf("error filtering logs %v\n", err)
}