github.com/status-im/status-go@v1.1.0/services/wallet/walletevent/watcher.go (about) 1 package walletevent 2 3 import ( 4 "context" 5 6 "github.com/ethereum/go-ethereum/event" 7 "github.com/ethereum/go-ethereum/log" 8 "github.com/status-im/status-go/services/wallet/async" 9 ) 10 11 type EventCb func(event Event) 12 13 // Watcher executes a given callback whenever a wallet event gets sent 14 type Watcher struct { 15 feed *event.Feed 16 group *async.Group 17 callback EventCb 18 } 19 20 func NewWatcher(feed *event.Feed, callback EventCb) *Watcher { 21 return &Watcher{ 22 feed: feed, 23 callback: callback, 24 } 25 } 26 27 func (w *Watcher) Start() { 28 if w.group != nil { 29 return 30 } 31 32 w.group = async.NewGroup(context.Background()) 33 w.group.Add(func(ctx context.Context) error { 34 return watch(ctx, w.feed, w.callback) 35 }) 36 } 37 38 func (w *Watcher) Stop() { 39 if w.group != nil { 40 w.group.Stop() 41 w.group.Wait() 42 w.group = nil 43 } 44 } 45 46 func watch(ctx context.Context, feed *event.Feed, callback EventCb) error { 47 ch := make(chan Event, 10) 48 sub := feed.Subscribe(ch) 49 defer sub.Unsubscribe() 50 51 for { 52 select { 53 case <-ctx.Done(): 54 return nil 55 case err := <-sub.Err(): 56 if err != nil { 57 log.Error("wallet event watcher subscription failed", "error", err) 58 } 59 case ev := <-ch: 60 if callback != nil { 61 callback(ev) 62 } 63 } 64 } 65 }