Files
gocryptotrader/engine/withdraw_manager.go
Adrian Gallagher f0d45aa1d2 golangci-lint/CI: Bump versions and introduce new linters (#798)
* golangci-lint/CI: Bump versions

Fix remaining linter issues

* Specifically set AppVeyor version

* Fix the infamous typos 👀

* Add go env cmd to AppVeyor

* Add go version cmd to AppVeyor

* Specify AppVeyor image, adjust linters

* Update go get to go install due to deprecation

* Bump golangci-lint timeout time for AppVeyor

* Change NW contract to NQ

* Address nitters

* GetRandomPair -> Pair{}

* Address nits

* Address time nitterinos plus additional tweaks

* More time inception upgrades!

* Bending time and space
2021-10-14 16:38:53 +11:00

151 lines
4.2 KiB
Go

package engine
import (
"context"
"errors"
"fmt"
"time"
dbwithdraw "github.com/thrasher-corp/gocryptotrader/database/repository/withdraw"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/currencystate"
"github.com/thrasher-corp/gocryptotrader/log"
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
)
// SetupWithdrawManager creates a new withdraw manager
func SetupWithdrawManager(em iExchangeManager, pm iPortfolioManager, isDryRun bool) (*WithdrawManager, error) {
if em == nil {
return nil, errors.New("nil manager")
}
return &WithdrawManager{
exchangeManager: em,
portfolioManager: pm,
isDryRun: isDryRun,
}, nil
}
// SubmitWithdrawal performs validation and submits a new withdraw request to
// exchange
func (m *WithdrawManager) SubmitWithdrawal(ctx context.Context, req *withdraw.Request) (*withdraw.Response, error) {
if m == nil {
return nil, ErrNilSubsystem
}
if req == nil {
return nil, withdraw.ErrRequestCannotBeNil
}
exch, err := m.exchangeManager.GetExchangeByName(req.Exchange)
if err != nil {
return nil, err
}
resp := &withdraw.Response{
Exchange: withdraw.ExchangeResponse{
Name: req.Exchange,
},
RequestDetails: *req,
}
// Determines if the currency can be withdrawn from the exchange
errF := exch.CanWithdraw(req.Currency, asset.Spot)
if errF != nil && !errors.Is(errF, currencystate.ErrCurrencyStateNotFound) { // Suppress not found error
return nil, errF
}
if m.isDryRun {
log.Warnln(log.Global, "Dry run enabled, no withdrawal request will be submitted or have an event created")
resp.ID = withdraw.DryRunID
resp.Exchange.Status = "dryrun"
resp.Exchange.ID = withdraw.DryRunID.String()
} else {
var ret *withdraw.ExchangeResponse
if req.Type == withdraw.Crypto {
if !m.portfolioManager.IsWhiteListed(req.Crypto.Address) {
return nil, withdraw.ErrStrAddressNotWhiteListed
}
if !m.portfolioManager.IsExchangeSupported(req.Exchange, req.Crypto.Address) {
return nil, withdraw.ErrStrExchangeNotSupportedByAddress
}
}
if req.Type == withdraw.Fiat {
ret, err = exch.WithdrawFiatFunds(ctx, req)
if err != nil {
resp.Exchange.Status = err.Error()
} else {
resp.Exchange.Status = ret.Status
resp.Exchange.ID = ret.ID
}
} else if req.Type == withdraw.Crypto {
ret, err = exch.WithdrawCryptocurrencyFunds(ctx, req)
if err != nil {
resp.Exchange.Status = err.Error()
} else {
resp.Exchange.Status = ret.Status
resp.Exchange.ID = ret.ID
}
}
}
if err == nil {
withdraw.Cache.Add(resp.ID, resp)
}
dbwithdraw.Event(resp)
return resp, err
}
// WithdrawalEventByID returns a withdrawal request by ID
func (m *WithdrawManager) WithdrawalEventByID(id string) (*withdraw.Response, error) {
if m == nil {
return nil, ErrNilSubsystem
}
if v := withdraw.Cache.Get(id); v != nil {
return v.(*withdraw.Response), nil
}
l, err := dbwithdraw.GetEventByUUID(id)
if err != nil {
return nil, fmt.Errorf("%w %v", ErrWithdrawRequestNotFound, id)
}
withdraw.Cache.Add(id, l)
return l, nil
}
// WithdrawalEventByExchange returns a withdrawal request by ID
func (m *WithdrawManager) WithdrawalEventByExchange(exchange string, limit int) ([]*withdraw.Response, error) {
if m == nil {
return nil, ErrNilSubsystem
}
_, err := m.exchangeManager.GetExchangeByName(exchange)
if err != nil {
return nil, err
}
return dbwithdraw.GetEventsByExchange(exchange, limit)
}
// WithdrawEventByDate returns a withdrawal request by ID
func (m *WithdrawManager) WithdrawEventByDate(exchange string, start, end time.Time, limit int) ([]*withdraw.Response, error) {
if m == nil {
return nil, ErrNilSubsystem
}
_, err := m.exchangeManager.GetExchangeByName(exchange)
if err != nil {
return nil, err
}
return dbwithdraw.GetEventsByDate(exchange, start, end, limit)
}
// WithdrawalEventByExchangeID returns a withdrawal request by Exchange ID
func (m *WithdrawManager) WithdrawalEventByExchangeID(exchange, id string) (*withdraw.Response, error) {
if m == nil {
return nil, ErrNilSubsystem
}
_, err := m.exchangeManager.GetExchangeByName(exchange)
if err != nil {
return nil, err
}
return dbwithdraw.GetEventByExchangeID(exchange, id)
}