github.com/NpoolPlatform/chain-middleware@v0.0.0-20240228100535-eb1bcf896eb9/pkg/currency/coinfiat.go (about)

     1  package currency
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/NpoolPlatform/go-service-framework/pkg/logger"
     8  
     9  	"github.com/NpoolPlatform/chain-middleware/pkg/currency/coingecko"
    10  
    11  	coincurrencyfeed1 "github.com/NpoolPlatform/chain-middleware/pkg/mw/coin/currency/feed"
    12  	coinfiat1 "github.com/NpoolPlatform/chain-middleware/pkg/mw/coin/fiat"
    13  	coinfiatcurrency1 "github.com/NpoolPlatform/chain-middleware/pkg/mw/coin/fiat/currency"
    14  	fiatcurrencyfeed1 "github.com/NpoolPlatform/chain-middleware/pkg/mw/fiat/currency/feed"
    15  
    16  	basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1"
    17  	coincurrencyfeedmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency/feed"
    18  	coinfiatmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/fiat"
    19  	fiatcurrencyfeedmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/fiat/currency/feed"
    20  
    21  	"github.com/NpoolPlatform/libent-cruder/pkg/cruder"
    22  	"github.com/shopspring/decimal"
    23  )
    24  
    25  //nolint:funlen,gocyclo
    26  func _refreshCoinFiats(ctx context.Context, feedType basetypes.CurrencyFeedType) error {
    27  	offset := int32(0)
    28  	const limit = int32(100)
    29  
    30  	for {
    31  		h1, err := coinfiat1.NewHandler(
    32  			ctx,
    33  			coinfiat1.WithConds(&coinfiatmwpb.Conds{}),
    34  			coinfiat1.WithOffset(offset),
    35  			coinfiat1.WithLimit(limit),
    36  		)
    37  		if err != nil {
    38  			logger.Sugar().Errorw(
    39  				"_refreshCoinFiats",
    40  				"Error", err,
    41  			)
    42  			return err
    43  		}
    44  
    45  		infos, _, err := h1.GetCoinFiats(ctx)
    46  		if err != nil {
    47  			logger.Sugar().Errorw(
    48  				"_refreshCoinFiats",
    49  				"Error", err,
    50  			)
    51  			return err
    52  		}
    53  		if len(infos) == 0 {
    54  			return nil
    55  		}
    56  
    57  		ids := []string{}
    58  		for _, info := range infos {
    59  			ids = append(ids, info.CoinTypeID)
    60  		}
    61  
    62  		h2, err := coincurrencyfeed1.NewHandler(
    63  			ctx,
    64  			coincurrencyfeed1.WithConds(&coincurrencyfeedmwpb.Conds{
    65  				FeedType:    &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(feedType)},
    66  				Disabled:    &basetypes.BoolVal{Op: cruder.EQ, Value: false},
    67  				CoinTypeIDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: ids},
    68  			}),
    69  			coincurrencyfeed1.WithOffset(0),
    70  			coincurrencyfeed1.WithLimit(int32(len(ids))),
    71  		)
    72  		if err != nil {
    73  			logger.Sugar().Errorw(
    74  				"_refreshCoinFiats",
    75  				"Error", err,
    76  			)
    77  			return err
    78  		}
    79  
    80  		coinFeeds, _, err := h2.GetFeeds(ctx)
    81  		if err != nil {
    82  			logger.Sugar().Errorw(
    83  				"_refreshCoinFiats",
    84  				"Error", err,
    85  			)
    86  			return err
    87  		}
    88  
    89  		coinFeedMap := map[string]*coincurrencyfeedmwpb.Feed{}
    90  		for _, _feed := range coinFeeds {
    91  			coinFeedMap[_feed.CoinTypeID] = _feed
    92  		}
    93  
    94  		ids = []string{}
    95  		for _, info := range infos {
    96  			ids = append(ids, info.FiatID)
    97  		}
    98  
    99  		h3, err := fiatcurrencyfeed1.NewHandler(
   100  			ctx,
   101  			fiatcurrencyfeed1.WithConds(&fiatcurrencyfeedmwpb.Conds{
   102  				FeedType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(feedType)},
   103  				Disabled: &basetypes.BoolVal{Op: cruder.EQ, Value: false},
   104  				FiatIDs:  &basetypes.StringSliceVal{Op: cruder.IN, Value: ids},
   105  			}),
   106  			fiatcurrencyfeed1.WithOffset(0),
   107  			fiatcurrencyfeed1.WithLimit(int32(len(ids))),
   108  		)
   109  		if err != nil {
   110  			logger.Sugar().Errorw(
   111  				"_refreshCoinFiats",
   112  				"Error", err,
   113  			)
   114  			return err
   115  		}
   116  
   117  		fiatFeeds, _, err := h3.GetFeeds(ctx)
   118  		if err != nil {
   119  			logger.Sugar().Errorw(
   120  				"_refreshCoinFiats",
   121  				"Error", err,
   122  			)
   123  			return err
   124  		}
   125  
   126  		fiatFeedMap := map[string]*fiatcurrencyfeedmwpb.Feed{}
   127  		for _, _feed := range fiatFeeds {
   128  			fiatFeedMap[_feed.FiatID] = _feed
   129  		}
   130  
   131  		coinNames := []string{}
   132  		fiatNames := []string{}
   133  
   134  		for _, info := range infos {
   135  			_coinFeed, ok := coinFeedMap[info.CoinTypeID]
   136  			if !ok {
   137  				continue
   138  			}
   139  			_fiatFeed, ok := fiatFeedMap[info.FiatID]
   140  			if !ok {
   141  				continue
   142  			}
   143  
   144  			coinNames = append(coinNames, _coinFeed.FeedCoinName)
   145  			fiatNames = append(fiatNames, _fiatFeed.FeedFiatName)
   146  		}
   147  
   148  		var prices map[string]map[string]decimal.Decimal
   149  		switch feedType {
   150  		case basetypes.CurrencyFeedType_CoinGecko:
   151  			prices, err = coingecko.CoinGeckoPrices(coinNames, fiatNames)
   152  		case basetypes.CurrencyFeedType_CoinBase:
   153  			fallthrough //nolint
   154  		default:
   155  			return fmt.Errorf("invalid feedtype")
   156  		}
   157  		if err != nil {
   158  			logger.Sugar().Errorw(
   159  				"_refreshCoinFiats",
   160  				"Error", err,
   161  			)
   162  			return err
   163  		}
   164  
   165  		_coinFeedMap := map[string][]*coincurrencyfeedmwpb.Feed{}
   166  		for _, _feed := range coinFeeds {
   167  			_coinFeedMap[_feed.FeedCoinName] = append(_coinFeedMap[_feed.FeedCoinName], _feed)
   168  		}
   169  		_fiatFeedMap := map[string][]*fiatcurrencyfeedmwpb.Feed{}
   170  		for _, _feed := range fiatFeeds {
   171  			_fiatFeedMap[_feed.FeedFiatName] = append(_fiatFeedMap[_feed.FeedFiatName], _feed)
   172  		}
   173  
   174  		for _coinName, _val1 := range prices {
   175  			_coinFeeds, ok := _coinFeedMap[_coinName]
   176  			if !ok {
   177  				continue
   178  			}
   179  			for _fiatName, _val2 := range _val1 {
   180  				_fiatFeeds, ok := _fiatFeedMap[_fiatName]
   181  				if !ok {
   182  					continue
   183  				}
   184  
   185  				price := _val2.String()
   186  				for _, _coinFeed := range _coinFeeds {
   187  					for _, _fiatFeed := range _fiatFeeds {
   188  						h4, err := coinfiatcurrency1.NewHandler(
   189  							ctx,
   190  							coinfiatcurrency1.WithCoinTypeID(&_coinFeed.CoinTypeID, true),
   191  							coinfiatcurrency1.WithFiatID(&_fiatFeed.FiatID, true),
   192  							coinfiatcurrency1.WithMarketValueHigh(&price, true),
   193  							coinfiatcurrency1.WithMarketValueLow(&price, true),
   194  						)
   195  						if err != nil {
   196  							logger.Sugar().Errorw(
   197  								"_refreshCoinFiats",
   198  								"Error", err,
   199  							)
   200  							return err
   201  						}
   202  
   203  						_, err = h4.CreateCurrency(ctx)
   204  						if err != nil {
   205  							logger.Sugar().Errorw(
   206  								"_refreshCoinFiats",
   207  								"Error", err,
   208  							)
   209  							return err
   210  						}
   211  					}
   212  				}
   213  			}
   214  		}
   215  
   216  		offset += limit
   217  	}
   218  }
   219  
   220  func refreshCoinFiats(ctx context.Context) {
   221  	if err := _refreshCoinFiats(ctx, basetypes.CurrencyFeedType_CoinGecko); err != nil {
   222  		logger.Sugar().Errorw(
   223  			"refreshCoinFiats",
   224  			"FeedType", basetypes.CurrencyFeedType_CoinGecko,
   225  			"Error", err,
   226  		)
   227  	}
   228  }