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(ctx context.Context) error } type transaction struct { *types.Transaction client Client pendingCheckPeriod time.Duration } func NewTransaction(client Client, pendingCheckPeriod time.Duration, tx *types.Transaction) Transaction { return &transaction{ Transaction: tx, client: client, pendingCheckPeriod: pendingCheckPeriod, } } func (t *transaction) Wait(ctx context.Context) error { hash := t.Hash() notfoundmax := 10 notfoundcount := 0 ticker := time.NewTicker(t.pendingCheckPeriod) for { select { case <-ctx.Done(): return errors.New("context canceled") case <-ticker.C: _, pending, err := t.client.TransactionByHash(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 } } }