package evm import ( "context" "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "github.com/rs/zerolog/log" ) type Transaction interface { Wait() error } type transaction struct { *types.Transaction ctx context.Context client Client pendingCheckPeriod time.Duration } func NewTransaction(ctx context.Context, client Client, pendingCheckPeriod time.Duration, tx *types.Transaction) Transaction { return &transaction{ Transaction: tx, ctx: ctx, client: client, pendingCheckPeriod: pendingCheckPeriod, } } func (t *transaction) Wait() error { hash := t.Hash() notfoundmax := 10 notfoundcount := 0 ticker := time.NewTicker(t.pendingCheckPeriod) for { select { case <-t.ctx.Done(): return errors.New("context canceled") case <-ticker.C: _, pending, err := t.client.TransactionByHash(t.ctx, hash) if err != nil { if err == ethereum.NotFound && notfoundcount < notfoundmax { notfoundcount++ log.Debug().Msgf("%d/%d - tx not found %s", notfoundcount, notfoundmax, hash) continue } return errors.Wrapf(err, "retrieving transaction state for hash %s", hash) } if pending { continue } log.Debug().Msg("//TX// tx done") return nil } } }