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 }