github.com/diadata-org/diadata@v1.4.593/pkg/dia/Messages.go (about)

     1  package dia
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math"
     7  	"math/big"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/ethereum/go-ethereum/common"
    12  )
    13  
    14  const (
    15  	Diadata                                 = "diadata.org"
    16  	PROOF_OF_STAKE    VerificationMechanism = "pos"
    17  	PROOF_OF_WORK     VerificationMechanism = "pow"
    18  	BITCOIN                                 = "Bitcoin"
    19  	ETHEREUM                                = "Ethereum"
    20  	BINANCESMARTCHAIN                       = "BinanceSmartChain"
    21  	POLYGON                                 = "Polygon"
    22  	CELO                                    = "Celo"
    23  	FANTOM                                  = "Fantom"
    24  	NEAR                                    = "NEAR"
    25  	AURORA                                  = "Aurora"
    26  	SOLANA                                  = "Solana"
    27  	FLOW                                    = "Flow"
    28  	MOONRIVER                               = "Moonriver"
    29  	MOONBEAM                                = "Moonbeam"
    30  	AVALANCHE                               = "Avalanche"
    31  	ARBITRUM                                = "Arbitrum"
    32  	ASTAR                                   = "Astar"
    33  	SHIDEN                                  = "Shiden"
    34  	METIS                                   = "Metis"
    35  	KILT                                    = "Kilt"
    36  	FETCH                                   = "Fetch"
    37  	FUSE                                    = "Fuse"
    38  	TELOS                                   = "Telos"
    39  	EVMOS                                   = "Evmos"
    40  	KUSAMA                                  = "Kusama"
    41  	ACALA                                   = "Acala"
    42  	POLKADOT                                = "Polkadot"
    43  	WANCHAIN                                = "Wanchain"
    44  	OSMOSIS                                 = "Osmosis"
    45  	FIAT                                    = "Fiat"
    46  	BIFROST                                 = "Bifrost"
    47  	BIFROST_POLKADOT                        = "Bifrost-polkadot"
    48  	UNREAL_TESTNET                          = "Unreal-Testnet"
    49  	UNREAL                                  = "Unreal"
    50  	LINEA                                   = "Linea"
    51  	OPTIMISM                                = "Optimism"
    52  	ALEPHIUM                                = "Alephium"
    53  	BASE                                    = "Base"
    54  	FILECOIN                                = "Filecoin"
    55  	HYDRATION                               = "Hydration"
    56  	STACKS                                  = "Stacks"
    57  	SWELLCHAIN                              = "Swellchain"
    58  )
    59  
    60  var CRYPTO_ZERO_UNIX_TIME = time.Unix(1230768000, 0)
    61  
    62  type VerificationMechanism string
    63  
    64  // BlockData stores information on a specific block in a given blockchain.
    65  type BlockData struct {
    66  	// Name of the blockchain, as found for instance in dia.ETHEREUM
    67  	BlockchainName string
    68  	// In order to keep it general, BlockNumber is a string
    69  	BlockNumber int64
    70  	Data        map[string]interface{}
    71  }
    72  
    73  type ExchangeVolume struct {
    74  	Exchange string  `json:"Exchange"`
    75  	Volume   float64 `json:"Volume"`
    76  }
    77  
    78  type ExchangeVolumesList struct {
    79  	Volumes   []ExchangeVolume `json:"Volumes"`
    80  	Timestamp time.Time        `json:"Timestamp"`
    81  }
    82  
    83  type AssetVolume struct {
    84  	Asset     Asset   `json:"Asset"`
    85  	Volume    float64 `json:"Volume"`
    86  	VolumeUSD float64 `json:"VolumeUSD"`
    87  	Index     uint8   `json:"Index"`
    88  }
    89  
    90  type AssetLiquidity struct {
    91  	Asset     Asset   `json:"Asset"`
    92  	Volume    float64 `json:"Liquidity"`
    93  	VolumeUSD float64 `json:"LiquidityUSD"`
    94  	Index     uint8   `json:"Index"`
    95  }
    96  
    97  type TopAsset struct {
    98  	Asset          Asset               `json:"Asset"`
    99  	Volume         float64             `json:"Volume"`
   100  	Price          float64             `json:"Price"`
   101  	PriceYesterday float64             `json:"PriceYesterday"`
   102  	Source         map[string][]string `json:"Source"`
   103  }
   104  
   105  type PairVolume struct {
   106  	Pair        Pair    `json:"Pair"`
   107  	PoolAddress string  `json:"Pooladdress"`
   108  	Volume      float64 `json:"Volume"`
   109  	TradesCount int64   `json:"TradesCount"`
   110  }
   111  
   112  type EthereumBlockData struct {
   113  	GasLimit    uint64             `json:"GasLimit"`
   114  	GasUsed     uint64             `json:"GasUsed"`
   115  	Difficulty  *big.Int           `json:"Difficulty"`
   116  	Time        uint64             `json:"Time"`
   117  	Size        common.StorageSize `json:"Size"`
   118  	Number      uint64             `json:"Number"`
   119  	MixDigest   common.Hash        `json:"MixDigest"`
   120  	Nonce       uint64             `json:"Nonce"`
   121  	Coinbase    common.Address     `json:"Coinbase"`
   122  	Root        common.Hash        `json:"Root"`
   123  	ParentHash  common.Hash        `json:"ParentHash"`
   124  	TxHash      common.Hash        `json:"TxHash"`
   125  	ReceiptHash common.Hash        `json:"ReceiptHash"`
   126  	UncleHash   common.Hash        `json:"UncleHash"`
   127  	Extra       []byte             `json:"Extra"`
   128  }
   129  
   130  type Exchange struct {
   131  	Name          string     `json:"Name"`
   132  	Centralized   bool       `json:"Centralized"`
   133  	Bridge        bool       `json:"Bridge"`
   134  	Contract      string     `json:"Contract"`
   135  	BlockChain    BlockChain `json:"BlockChain"`
   136  	RestAPI       string     `json:"RestAPI"`
   137  	WsAPI         string     `json:"WsAPI"`
   138  	PairsAPI      string     `json:"PairsAPI"`
   139  	WatchdogDelay int        `json:"WatchdogDelay"`
   140  	ScraperActive bool       `json:"ScraperActive"`
   141  }
   142  
   143  type Supply struct {
   144  	Asset             Asset     `json:"Asset"`
   145  	Supply            float64   `json:"Supply"`
   146  	CirculatingSupply float64   `json:"CirculatingSupply"`
   147  	Source            string    `json:"Source"`
   148  	Time              time.Time `json:"Time"`
   149  }
   150  
   151  // Asset is the data type for all assets, ranging from fiat to crypto.
   152  type Asset struct {
   153  	Symbol     string `json:"Symbol"`
   154  	Name       string `json:"Name"`
   155  	Address    string `json:"Address"`
   156  	Decimals   uint8  `json:"Decimals"`
   157  	Blockchain string `json:"Blockchain"`
   158  }
   159  
   160  type AssetList struct {
   161  	AssetName   string
   162  	CustomName  string
   163  	Symbol      string
   164  	Methodology string
   165  	ListName    string
   166  
   167  	Exchanges []ExchangeList
   168  }
   169  
   170  func (a AssetList) String() string {
   171  	var exchanges []string
   172  	for _, exchange := range a.Exchanges {
   173  		exchanges = append(exchanges, exchange.String())
   174  	}
   175  
   176  	return fmt.Sprintf(
   177  		" Exchanges: [%s]",
   178  		strings.Join(exchanges, "; "),
   179  	)
   180  }
   181  
   182  type ExchangeList struct {
   183  	Name  string
   184  	Pairs []string
   185  }
   186  
   187  func (e ExchangeList) String() string {
   188  	return fmt.Sprintf("%s: [%s]", e.Name, strings.Join(e.Pairs, ", "))
   189  }
   190  func (asset *Asset) Identifier() string {
   191  	return asset.Blockchain + "-" + asset.Address
   192  }
   193  
   194  // BlockChain is the type for blockchains. Uniquely defined by its @Name.
   195  type BlockChain struct {
   196  	Name string `json:"Name"`
   197  	// Genesis date is a Unix timestamp
   198  	GenesisDate int64 `json:"GenesisDate"`
   199  	NativeToken Asset `json:"NativeToken"`
   200  	// Verificationmechanism is in short notation, such as pos for proof-of-stake
   201  	VerificationMechanism VerificationMechanism `json:"VerificationMechanism"`
   202  	// ChainID refers to EVM based chains and is thereby optional.
   203  	ChainID string `json:"ChainID"`
   204  }
   205  
   206  type ChainConfig struct {
   207  	RestURL string `json:"RestURL"`
   208  	WSURL   string `json:"WSURL"`
   209  	ChainID string `json:"ChainID"`
   210  }
   211  
   212  // Pair substitues the old dia.Pair. It includes the new asset type.
   213  type Pair struct {
   214  	QuoteToken Asset `json:"QuoteToken"`
   215  	BaseToken  Asset `json:"BaseToken"`
   216  }
   217  
   218  func (p *Pair) Identifier() string {
   219  	return p.QuoteToken.Blockchain + "-" + p.QuoteToken.Address + "-" + p.BaseToken.Blockchain + "-" + p.BaseToken.Address
   220  }
   221  
   222  func (p *Pair) PairExchangeIdentifier(exchange string) string {
   223  	return exchange + "-" + p.Identifier()
   224  }
   225  
   226  // ForeignName returns the foreign name of the pair @p, i.e. the string Quotetoken-Basetoken
   227  func (p *Pair) ForeignName() string {
   228  	return p.QuoteToken.Symbol + "-" + p.BaseToken.Symbol
   229  }
   230  
   231  // Pool is the container for liquidity pools on DEXes.
   232  type Pool struct {
   233  	Exchange     Exchange
   234  	Blockchain   BlockChain
   235  	Address      string
   236  	Assetvolumes []AssetVolume
   237  	Time         time.Time
   238  }
   239  
   240  // SufficientNativeBalance returns true if all pool assets have at least @threshold liquidity.
   241  func (p *Pool) SufficientNativeBalance(threshold float64) bool {
   242  	sufficientNativeBalance := true
   243  	for _, av := range p.Assetvolumes {
   244  		if av.Volume < threshold {
   245  			sufficientNativeBalance = false
   246  		}
   247  	}
   248  	return sufficientNativeBalance
   249  }
   250  
   251  // GetPoolLiquidityUSD returns the total USD liquidity if available.
   252  // @lowerBound is true in case USD liquidity is not available for all pool assets.
   253  func (p *Pool) GetPoolLiquidityUSD() (totalLiquidity float64, lowerBound bool) {
   254  	for _, av := range p.Assetvolumes {
   255  		// For some pools, for instance on BalancerV2 type contracts, the pool contains itself as an asset.
   256  		if av.Asset.Address == p.Address {
   257  			continue
   258  		}
   259  		if av.VolumeUSD == 0 {
   260  			lowerBound = true
   261  		}
   262  		totalLiquidity += av.VolumeUSD
   263  	}
   264  	return
   265  }
   266  
   267  // MarshalBinary is a custom marshaller for BlockChain type
   268  func (bc *BlockChain) MarshalBinary() ([]byte, error) {
   269  	return json.Marshal(bc)
   270  }
   271  
   272  // UnmarshalBinary is a custom unmarshaller for BlockChain type
   273  func (bc *BlockChain) UnmarshalBinary(data []byte) error {
   274  	if err := json.Unmarshal(data, &bc); err != nil {
   275  		return err
   276  	}
   277  	return nil
   278  }
   279  
   280  // MarshalBinary is a custom marshaller for Asset type
   281  func (a *Asset) MarshalBinary() ([]byte, error) {
   282  	return json.Marshal(a)
   283  }
   284  
   285  // UnmarshalBinary is a custom unmarshaller for Asset type
   286  func (a *Asset) UnmarshalBinary(data []byte) error {
   287  	if err := json.Unmarshal(data, &a); err != nil {
   288  		return err
   289  	}
   290  	return nil
   291  }
   292  
   293  // ExchangePair is the container for a pair as used by exchanges.
   294  // Across exchanges, these pairs cannot be uniquely mapped on asset pairs.
   295  type ExchangePair struct {
   296  	Symbol         string `json:"Symbol"`
   297  	ForeignName    string `json:"ForeignName"`
   298  	Exchange       string `json:"EXchange"`
   299  	Verified       bool   `json:"Verified"`
   300  	UnderlyingPair Pair   `json:"UnderlyingPair"`
   301  }
   302  
   303  // MarshalBinary is a custom marshaller for ExchangePair type
   304  func (ep *ExchangePair) MarshalBinary() ([]byte, error) {
   305  	return json.Marshal(ep)
   306  }
   307  
   308  // UnmarshalBinary is a custom unmarshaller for ExchangePair type
   309  func (ep *ExchangePair) UnmarshalBinary(data []byte) error {
   310  	if err := json.Unmarshal(data, &ep); err != nil {
   311  		return err
   312  	}
   313  	return nil
   314  }
   315  
   316  type Pairs []ExchangePair
   317  
   318  type FeedSelection struct {
   319  	Asset              Asset
   320  	Exchangepairs      []ExchangepairSelection
   321  	LiquidityThreshold float64
   322  }
   323  
   324  type FeedSelectionAggregated struct {
   325  	Exchange         string
   326  	Quotetoken       Asset
   327  	Basetoken        Asset
   328  	Pooladdress      string
   329  	PoolLiquidityUSD float64
   330  	TradesCount      int32
   331  	Volume           float64
   332  	LastPrice        float64
   333  	Starttime        time.Time
   334  	Endtime          time.Time
   335  	StatusMessage    string
   336  	StatusCode       int32
   337  }
   338  
   339  type ExchangepairSelection struct {
   340  	Exchange           Exchange
   341  	Pairs              []Pair
   342  	Pools              []Pool
   343  	LiquidityThreshold float64
   344  }
   345  
   346  // Trade remark: In a pair A-B, we call A the Quote token and B the Base token
   347  type Trade struct {
   348  	// TO DO: Deprecated fields. Delete as soon as token-to-type branch is deployed.
   349  	Symbol string `json:"Symbol"`
   350  	Pair   string `json:"Pair"`
   351  	// Final fields for trade
   352  	QuoteToken        Asset     `json:"QuoteToken"`
   353  	BaseToken         Asset     `json:"BaseToken"`
   354  	Price             float64   `json:"Price"`
   355  	Volume            float64   `json:"Volume"` // Quantity of bought/sold units of Quote token. Negative if result of Market order Sell
   356  	Time              time.Time `json:"Time"`
   357  	PoolAddress       string    `json:"PoolAddress"`
   358  	ForeignTradeID    string    `json:"ForeignTradeID"`
   359  	EstimatedUSDPrice float64   `json:"EstimatedUSDPrice"` // will be filled by the TradesBlockService
   360  	Source            string    `json:"Source"`
   361  	VerifiedPair      bool      `json:"VerifiedPair"` // will be filled by the pairDiscoveryService
   362  }
   363  
   364  func (t *Trade) VolumeUSD() float64 {
   365  	return t.EstimatedUSDPrice * math.Abs(t.Volume)
   366  }
   367  
   368  // NormalizeSymbols normalizes @t.Symbol and @t.Pair in a trade struct to
   369  // upper case letters like so A@pairSplitterB. For instance, btcusdt will be BTC-USDT.
   370  func (t *Trade) NormalizeSymbols(upperCase bool, pairSplitter string) error {
   371  	symbols, err := GetPairSymbols(ExchangePair{Exchange: t.Source, ForeignName: t.Pair, Symbol: t.Symbol})
   372  	if err != nil {
   373  		return err
   374  	}
   375  	if len(symbols) == 2 {
   376  		if upperCase {
   377  			t.Pair = strings.ToUpper(symbols[0] + pairSplitter + symbols[1])
   378  			t.Symbol = strings.ToUpper(symbols[0])
   379  		} else {
   380  			t.Pair = strings.ToLower(symbols[0] + pairSplitter + symbols[1])
   381  			t.Symbol = strings.ToLower(symbols[0])
   382  		}
   383  	}
   384  	return nil
   385  }
   386  
   387  type TradesBlockData struct {
   388  	BeginTime    time.Time
   389  	EndTime      time.Time
   390  	TradesNumber int
   391  	Trades       []Trade
   392  }
   393  
   394  type TradesBlock struct {
   395  	BlockHash       string
   396  	TradesBlockData TradesBlockData
   397  }
   398  
   399  type FiltersBlock struct {
   400  	BlockHash        string
   401  	FiltersBlockData FiltersBlockData
   402  }
   403  
   404  type FiltersBlockData struct {
   405  	TradesBlockHash string
   406  	BeginTime       time.Time
   407  	EndTime         time.Time
   408  	FilterPoints    []FilterPoint
   409  	FiltersNumber   int
   410  }
   411  
   412  // FilterPoint contains the resulting value of a filter applied to an asset.
   413  type FilterPoint struct {
   414  	Asset      Asset
   415  	Value      float64
   416  	Name       string
   417  	Time       time.Time
   418  	Max        float64
   419  	Min        float64
   420  	FirstTrade Trade
   421  	LastTrade  Trade
   422  }
   423  
   424  type FilterPointExtended struct {
   425  	FilterPoint FilterPoint
   426  	// Pools and pairs of the filter point's underlying trades.
   427  	Pools         []Pool
   428  	Pairs         []ExchangePair
   429  	TradesCount   int32
   430  	StatusMessage string
   431  	StatusCode    int32
   432  }
   433  
   434  type IndexBlock struct {
   435  	BlockHash      string         `json:"BlockHash"`
   436  	IndexBlockData IndexBlockData `json:"IndexBlockData"`
   437  }
   438  
   439  type IndexBlockData struct {
   440  	FiltersBlockHash    string         `json:"FiltersBlockHash"`
   441  	SuppliesBlockHash   string         `json:"SuppliesBlockHash"`
   442  	VolatilityBlockHash string         `json:"VolatilityBlockHash"`
   443  	IndexElements       []IndexElement `json:"IndexElements"`
   444  	IndexElementsNumber int            `json:"IndexElementsNumber"`
   445  	Time                time.Time      `json:"Time"`
   446  	IndexValue          float64        `json:"IndexValue"`
   447  	ValueTokenette      float64        `json:"ValueTokenette"`
   448  	ValueToken          float64        `json:"ValueToken"`
   449  	USDPerPointsOfIndex float64        `json:"USDPerPointsOfIndex"`
   450  }
   451  
   452  type IndexElement struct {
   453  	Name            string
   454  	Symbol          string
   455  	Percentage      float64
   456  	FilteredPoint   FilterPoint
   457  	Supply          Supply
   458  	VolatilityRatio VolatilityRatio
   459  }
   460  
   461  type VolatilityRatio struct {
   462  	Symbol    string
   463  	Threehold float64
   464  	DaysAbove int64
   465  	DaysBelow int64
   466  	Time      time.Time
   467  	Selected  bool
   468  }
   469  
   470  type SuppliesBlock struct {
   471  	BlockHash string            `json:"BlockHash"`
   472  	BlockData SuppliesBlockData `json:"BlockData"`
   473  }
   474  
   475  type SuppliesBlockData struct {
   476  	Time     time.Time `json:"Time"`
   477  	Supplies []Supply  `json:"Supplies"`
   478  }
   479  
   480  type FilterPointMetadata struct {
   481  	Max float64
   482  	Min float64
   483  }
   484  
   485  func NewFilterPointMetadata() *FilterPointMetadata {
   486  	return &FilterPointMetadata{Max: 0, Min: -1}
   487  }
   488  
   489  func (fp *FilterPointMetadata) AddPoint(value float64) {
   490  	if fp.Max < value {
   491  		fp.Max = value
   492  	}
   493  	if fp.Min > value || fp.Min == -1 {
   494  		fp.Min = value
   495  	}
   496  }
   497  
   498  // MarshalBinary -
   499  func (e *FiltersBlock) MarshalBinary() ([]byte, error) {
   500  	return json.Marshal(e)
   501  }
   502  
   503  // UnmarshalBinary -
   504  func (e *FiltersBlock) UnmarshalBinary(data []byte) error {
   505  	if err := json.Unmarshal(data, &e); err != nil {
   506  		return err
   507  	}
   508  	return nil
   509  }
   510  
   511  // MarshalBinary -
   512  func (e *Trade) MarshalBinary() ([]byte, error) {
   513  	return json.Marshal(e)
   514  }
   515  
   516  // UnmarshalBinary -
   517  func (e *Trade) UnmarshalBinary(data []byte) error {
   518  	if err := json.Unmarshal(data, &e); err != nil {
   519  		return err
   520  	}
   521  	return nil
   522  }
   523  
   524  // MarshalBinary -
   525  func (e *TradesBlock) MarshalBinary() ([]byte, error) {
   526  	return json.Marshal(e)
   527  }
   528  
   529  // UnmarshalBinary -
   530  func (e *TradesBlock) UnmarshalBinary(data []byte) error {
   531  	if err := json.Unmarshal(data, &e); err != nil {
   532  		return err
   533  	}
   534  	return nil
   535  }
   536  
   537  // MarshalBinary -
   538  func (e *Supply) MarshalBinary() ([]byte, error) {
   539  	return json.Marshal(e)
   540  }
   541  
   542  // UnmarshalBinary -
   543  func (e *Supply) UnmarshalBinary(data []byte) error {
   544  	if err := json.Unmarshal(data, &e); err != nil {
   545  		return err
   546  	}
   547  	return nil
   548  }
   549  
   550  // MarshalBinary -
   551  func (e *Pairs) MarshalBinary() ([]byte, error) {
   552  	return json.Marshal(e)
   553  }
   554  
   555  // UnmarshalBinary -
   556  func (e *Pairs) UnmarshalBinary(data []byte) error {
   557  	if err := json.Unmarshal(data, &e); err != nil {
   558  		return err
   559  	}
   560  	return nil
   561  }
   562  
   563  func (ib IndexBlock) Hash() string {
   564  	return ib.BlockHash
   565  }
   566  
   567  // MarshalBinary -
   568  func (e *IndexBlock) MarshalBinary() ([]byte, error) {
   569  	return json.Marshal(e)
   570  }
   571  
   572  // UnmarshalBinary -
   573  func (e *IndexBlock) UnmarshalBinary(data []byte) error {
   574  	if err := json.Unmarshal(data, &e); err != nil {
   575  		return err
   576  	}
   577  	return nil
   578  }
   579  
   580  // MarshalBinary -
   581  func (e *SuppliesBlock) MarshalBinary() ([]byte, error) {
   582  	return json.Marshal(e)
   583  }
   584  
   585  // UnmarshalBinary -
   586  func (e *SuppliesBlock) UnmarshalBinary(data []byte) error {
   587  	if err := json.Unmarshal(data, &e); err != nil {
   588  		return err
   589  	}
   590  	return nil
   591  }
   592  
   593  type OracleConfig struct {
   594  	Symbols            []string
   595  	FeederID           string
   596  	Address            string
   597  	FeederAddress      string
   598  	Owner              string
   599  	ChainID            string
   600  	Active             bool
   601  	Frequency          string
   602  	SleepSeconds       string
   603  	DeviationPermille  string
   604  	BlockchainNode     string
   605  	MandatoryFrequency string
   606  	CreatedDate        time.Time
   607  	LastUpdate         time.Time
   608  	Deleted            bool
   609  	Draft              bool
   610  	FeederSelection    string
   611  	Expired            bool
   612  	ExpiredDate        time.Time
   613  	ExpiringDate       time.Time
   614  	LastOracleUpdate   time.Time
   615  	CustomerID         string
   616  	Billable           bool
   617  	Name               string
   618  	Ecosystem          bool
   619  }
   620  
   621  func (e *OracleConfig) MarshalBinary() ([]byte, error) {
   622  	return json.Marshal(e)
   623  }
   624  
   625  // UnmarshalBinary -
   626  func (e *OracleConfig) UnmarshalBinary(data []byte) error {
   627  	if err := json.Unmarshal(data, &e); err != nil {
   628  		return err
   629  	}
   630  	return nil
   631  }
   632  
   633  type OracleUpdate struct {
   634  	OracleAddress     string
   635  	TransactionHash   string
   636  	TransactionCost   string
   637  	AssetKey          string
   638  	AssetPrice        string
   639  	UpdateBlock       uint64
   640  	UpdateFrom        string
   641  	FromBalance       string
   642  	GasCost           string
   643  	GasUsed           float64
   644  	ChainID           string
   645  	UpdateTime        time.Time
   646  	CreationBlock     uint64
   647  	CreationBlockTime time.Time
   648  }
   649  
   650  type FeedUpdates struct {
   651  	Day         time.Time `json:"Day"`
   652  	UpdateCount int32     `json:"UpdateCount"`
   653  	GasUsed     float64   `json:"GasUsed"`
   654  }