lemdaddy commited on
Commit
6a7abb7
·
1 Parent(s): 383415a

Major knowledgebase update

Browse files
chatxbt-assistant.py CHANGED
@@ -11,7 +11,7 @@ from phi.tools.yfinance import YFinanceTools
11
  from src.databases.postgres import sqlalchemy_engine
12
  from src.tools.coin_data_toolkit import CryptoDataTools
13
  from phi.storage.assistant.postgres import PgAssistantStorage
14
- from src.knowledge_bases.knowledge_base import knowledge_base
15
 
16
  storage = PgAssistantStorage(
17
  # store runs in the ai.assistant_runs table
 
11
  from src.databases.postgres import sqlalchemy_engine
12
  from src.tools.coin_data_toolkit import CryptoDataTools
13
  from phi.storage.assistant.postgres import PgAssistantStorage
14
+ from src.knowledge_bases.combined import knowledge_base
15
 
16
  storage = PgAssistantStorage(
17
  # store runs in the ai.assistant_runs table
requirements.txt CHANGED
@@ -1,9 +1,12 @@
 
1
  aiofiles==23.2.1
2
  aiohttp==3.9.5
 
3
  aiosignal==1.3.1
4
  annotated-types==0.7.0
5
  anthropic==0.28.0
6
  anyio==3.7.1
 
7
  appnope==0.1.4
8
  asgiref==3.8.1
9
  asttokens==2.4.1
@@ -14,6 +17,8 @@ backcall==0.2.0
14
  beautifulsoup4==4.12.3
15
  bidict==0.23.1
16
  bleach==6.1.0
 
 
17
  certifi==2024.6.2
18
  chainlit==1.1.300
19
  charset-normalizer==3.3.2
@@ -35,6 +40,8 @@ filelock==3.15.1
35
  filetype==1.2.0
36
  frozendict==2.4.4
37
  frozenlist==1.4.1
 
 
38
  fsspec==2024.6.0
39
  gitdb==4.0.11
40
  GitPython==3.1.43
@@ -53,6 +60,7 @@ ipython==8.12.3
53
  jedi==0.19.1
54
  Jinja2==3.1.4
55
  jiter==0.4.2
 
56
  jsonpatch==1.33
57
  jsonpointer==3.0.0
58
  jsonschema==4.22.0
@@ -147,7 +155,8 @@ regex==2024.5.15
147
  requests==2.32.3
148
  rich==13.7.1
149
  rpds-py==0.18.1
150
- setuptools==70.0.0
 
151
  shellingham==1.5.4
152
  simple-websocket==1.0.0
153
  six==1.16.0
 
1
+ aiobotocore==2.13.0
2
  aiofiles==23.2.1
3
  aiohttp==3.9.5
4
+ aioitertools==0.11.0
5
  aiosignal==1.3.1
6
  annotated-types==0.7.0
7
  anthropic==0.28.0
8
  anyio==3.7.1
9
+ appdirs==1.4.4
10
  appnope==0.1.4
11
  asgiref==3.8.1
12
  asttokens==2.4.1
 
17
  beautifulsoup4==4.12.3
18
  bidict==0.23.1
19
  bleach==6.1.0
20
+ boto3==1.34.131
21
+ botocore==1.34.131
22
  certifi==2024.6.2
23
  chainlit==1.1.300
24
  charset-normalizer==3.3.2
 
40
  filetype==1.2.0
41
  frozendict==2.4.4
42
  frozenlist==1.4.1
43
+ fs==2.4.16
44
+ fs-s3fs==1.1.1
45
  fsspec==2024.6.0
46
  gitdb==4.0.11
47
  GitPython==3.1.43
 
60
  jedi==0.19.1
61
  Jinja2==3.1.4
62
  jiter==0.4.2
63
+ jmespath==1.0.1
64
  jsonpatch==1.33
65
  jsonpointer==3.0.0
66
  jsonschema==4.22.0
 
155
  requests==2.32.3
156
  rich==13.7.1
157
  rpds-py==0.18.1
158
+ s3fs==2024.6.0
159
+ s3transfer==0.10.1
160
  shellingham==1.5.4
161
  simple-websocket==1.0.0
162
  six==1.16.0
run.py CHANGED
@@ -1,51 +1,7 @@
1
  import json
2
  import pprint
3
- from src.libs.logger import logger
4
 
5
- # from src.data_sources.coingecko import CoinGecko
6
- # from src.data_sources.cryptocompare import CryptoCompare
7
 
8
- # cgc = CoinGecko()
9
-
10
- # result = cgc.get_coin_price(ids=["bitcoin", "ethereum"], vs_currencies=["usd"])
11
- # logger.info(f"Got token price: {result}")
12
-
13
- # result = cgc.get_coin_data(id="tron")
14
- # logger.info(f"Got token data: {result}")
15
-
16
- # pprint.pprint(result)
17
-
18
- # coingecko_instance = get_coingecko_instance()
19
- # print(coingecko_instance)
20
-
21
- # result = coingecko_instance.exchanges.get_list()
22
- # logger.info(f"Got exchange data: {result}")
23
-
24
- # pprint.pprint(result)
25
-
26
-
27
- # result = cgc.get_coin_price(ids=["pepe"], vs_currencies=["usd"])
28
- # # logger.info(f"Got token data: {result}")
29
- # pprint.pprint(result)
30
-
31
- # result1 = ccp.get_coin_price(ids=["portal"], vs_currencies=["usd"])
32
- # # logger.info(f"Got token data: {result1}")
33
- # pprint.pprint(result1)
34
-
35
- # from src.data_sources.cryptocompare import CryptoCompare
36
- # ccp = CryptoCompare()
37
-
38
- # result = ccp.get_overall_coin_data(symbol="bnb")
39
- # pprint.pprint(result)
40
-
41
- from src.data_sources.cryptocompare import CryptoCompare
42
- from src.data_sources.dexscreener import DexScreener
43
-
44
- crypto_compare = CryptoCompare()
45
- dex_screener = DexScreener()
46
-
47
- dexscreener_coin_data = dex_screener.search(query='PANDORA')
48
- cryptocompare_coin_data = crypto_compare.get_overall_coin_data(symbol='PANDORA')
49
-
50
- pprint.pprint(dexscreener_coin_data)
51
- pprint.pprint(cryptocompare_coin_data)
 
1
  import json
2
  import pprint
3
+ import asyncio
4
 
5
+ import src.knowledge_bases.pipeline as Pipeline
 
6
 
7
+ asyncio.run(Pipeline.main())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/data_sources/coin_gecko.py CHANGED
@@ -11,6 +11,24 @@ redis_cache = REDIS_CACHED
11
 
12
  class CoinGecko:
13
  def __init__(self, pro_api: bool = False) -> None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  if pro_api:
15
  self.cgc = CoinGeckoProClient(api_key=os.getenv('COINGECKO_PRO_API_KEY'))
16
  else:
@@ -19,18 +37,54 @@ class CoinGecko:
19
  @redis_cache(ttl=ONE_MINUTE_IN_SECONDS)
20
  @logger.instrument()
21
  def get_coin_price(self, ids: list[str], vs_currencies: list[str], cache_ttl: int = None) -> dict:
22
- # logger.debug(f"ids: {ids}")
23
- # logger.debug(f"vs_currencies: {vs_currencies}")
 
 
 
 
 
 
 
 
24
 
 
 
 
 
 
 
 
 
 
 
25
  result = self.cgc.simple.get_price(ids=ids, vs_currencies=vs_currencies)
26
- # logger.debug(f"Result: {result}")
27
 
28
  return result
29
 
30
  @redis_cache(ttl=ONE_HOUR_IN_SECONDS)
31
  @logger.instrument()
32
  def get_coin_data(self, id: str, cache_ttl: int = None) -> dict:
 
 
 
 
 
 
 
 
 
33
 
 
 
 
 
 
 
 
 
 
 
34
  result = self.cgc.coins.get_id(id=id, localization=False, market_data=False, tickers=False, sparkline=False)
35
  logger.debug(f"Result: {result}")
36
 
@@ -39,7 +93,26 @@ class CoinGecko:
39
  @redis_cache(ttl=ONE_MONTH_IN_SECONDS)
40
  @logger.instrument()
41
  def get_coin_category_data(self, params: dict = None, cache_ttl: int = None) -> dict:
 
 
 
 
 
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  params = params or {
44
  "order": "market_cap_desc",
45
  }
@@ -52,9 +125,25 @@ class CoinGecko:
52
  @redis_cache(ttl=ONE_MONTH_IN_SECONDS)
53
  @logger.instrument()
54
  def get_exchanges_list(self, cache_ttl: int = None) -> dict:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
- # result = self.cgc.exchanges.get(per_page=10)
57
- # result = self.cgc.exchanges.get_id(id=id)
 
58
  result = self.cgc.exchanges.get_list()
59
  logger.debug(f"Result: {result}")
60
 
@@ -63,6 +152,31 @@ class CoinGecko:
63
  @redis_cache(ttl=ONE_HOUR_IN_SECONDS)
64
  @logger.instrument()
65
  def get_exchange_data(self, id: str = None, cache_ttl: int = None) -> dict:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  result = self.cgc.exchanges.get_id(id=id)
68
  logger.debug(f"Result: {result}")
 
11
 
12
  class CoinGecko:
13
  def __init__(self, pro_api: bool = False) -> None:
14
+ """
15
+ Initializes the CoinGecko object.
16
+
17
+ Args:
18
+ pro_api (bool, optional): A boolean value indicating whether to use the Pro API. Defaults to False.
19
+
20
+ Returns:
21
+ None
22
+
23
+ Raises:
24
+ ValueError: If the `pro_api` argument is not a boolean value.
25
+
26
+ Note:
27
+ This method initializes the CoinGecko object by creating an instance of either CoinGeckoProClient or CoinGeckoDemoClient based on the `pro_api` argument. If `pro_api` is `True`, it uses the Pro API with the provided API key; otherwise, it uses the Demo API.
28
+ """
29
+ if not isinstance(pro_api, bool):
30
+ raise ValueError("The `pro_api` argument must be a boolean value.")
31
+
32
  if pro_api:
33
  self.cgc = CoinGeckoProClient(api_key=os.getenv('COINGECKO_PRO_API_KEY'))
34
  else:
 
37
  @redis_cache(ttl=ONE_MINUTE_IN_SECONDS)
38
  @logger.instrument()
39
  def get_coin_price(self, ids: list[str], vs_currencies: list[str], cache_ttl: int = None) -> dict:
40
+ """
41
+ Retrieves the current price of a list of coins in a specified currency.
42
+
43
+ Args:
44
+ ids (list[str]): A list of unique identifiers for the coins to retrieve prices for.
45
+ vs_currencies (list[str]): A list of currency codes to convert the coin prices to.
46
+ cache_ttl (int, optional): The time-to-live (in seconds) for the cached data. Defaults to None.
47
+
48
+ Returns:
49
+ dict: A dictionary containing the current prices of the specified coins in the specified currencies.
50
 
51
+ Example:
52
+ To get the current prices of a list of coins in USD, you can call:
53
+
54
+ ```python
55
+ coin_prices = coin_gecko.get_coin_price(ids=['bitcoin', 'ethereum'], vs_currencies=['usd'])
56
+ ```
57
+
58
+ Note:
59
+ The `get_coin_price` method uses the `redis_cache` decorator to cache the result for a specified time (`ONE_MINUTE_IN_SECONDS`). This means that if the same request is made within the cache time, the cached result will be returned instead of making a new API call.
60
+ """
61
  result = self.cgc.simple.get_price(ids=ids, vs_currencies=vs_currencies)
 
62
 
63
  return result
64
 
65
  @redis_cache(ttl=ONE_HOUR_IN_SECONDS)
66
  @logger.instrument()
67
  def get_coin_data(self, id: str, cache_ttl: int = None) -> dict:
68
+ """
69
+ Retrieves detailed information about a specific coin.
70
+
71
+ Args:
72
+ id (str): The unique identifier of the coin.
73
+ cache_ttl (int, optional): The time-to-live (in seconds) for the cached data. Defaults to None.
74
+
75
+ Returns:
76
+ dict: A dictionary containing the detailed information about the specified coin.
77
 
78
+ Example:
79
+ To get data for the coin with id 'bitcoin', you can call:
80
+
81
+ ```python
82
+ coin_data = coin_gecko.get_coin_data(id='bitcoin')
83
+ ```
84
+
85
+ Note:
86
+ The `get_coin_data` method uses the `redis_cache` decorator to cache the result for a specified time (`ONE_HOUR_IN_SECONDS`). This means that if the same request is made within the cache time, the cached result will be returned instead of making a new API call.
87
+ """
88
  result = self.cgc.coins.get_id(id=id, localization=False, market_data=False, tickers=False, sparkline=False)
89
  logger.debug(f"Result: {result}")
90
 
 
93
  @redis_cache(ttl=ONE_MONTH_IN_SECONDS)
94
  @logger.instrument()
95
  def get_coin_category_data(self, params: dict = None, cache_ttl: int = None) -> dict:
96
+ """
97
+ Retrieves data for all available coin categories.
98
+
99
+ Args:
100
+ params (dict, optional): A dictionary containing optional parameters for the request. Defaults to None.
101
+ cache_ttl (int, optional): The time-to-live (in seconds) for the cached data. Defaults to None.
102
 
103
+ Returns:
104
+ dict: A dictionary containing the data for all available coin categories.
105
+
106
+ Example:
107
+ To get data for all available coin categories, you can call:
108
+
109
+ ```python
110
+ category_data = coin_gecko.get_coin_category_data()
111
+ ```
112
+
113
+ Note:
114
+ The `get_coin_category_data` method uses the `redis_cache` decorator to cache the result for a specified time (`ONE_MONTH_IN_SECONDS`). This means that if the same request is made within the cache time, the cached result will be returned instead of making a new API call.
115
+ """
116
  params = params or {
117
  "order": "market_cap_desc",
118
  }
 
125
  @redis_cache(ttl=ONE_MONTH_IN_SECONDS)
126
  @logger.instrument()
127
  def get_exchanges_list(self, cache_ttl: int = None) -> dict:
128
+ """
129
+ Retrieves a list of all available exchanges.
130
+
131
+ Args:
132
+ cache_ttl (int, optional): The time-to-live (in seconds) for the cached data. Defaults to None.
133
+
134
+ Returns:
135
+ dict: A dictionary containing a list of all available exchanges.
136
+
137
+ Example:
138
+ To get a list of all available exchanges, you can call:
139
+
140
+ ```python
141
+ exchange_list = coin_gecko.get_exchanges_list()
142
+ ```
143
 
144
+ Note:
145
+ The `get_exchanges_list` method uses the `redis_cache` decorator to cache the result for a specified time (`ONE_MONTH_IN_SECONDS`). This means that if the same request is made within the cache time, the cached result will be returned instead of making a new API call.
146
+ """
147
  result = self.cgc.exchanges.get_list()
148
  logger.debug(f"Result: {result}")
149
 
 
152
  @redis_cache(ttl=ONE_HOUR_IN_SECONDS)
153
  @logger.instrument()
154
  def get_exchange_data(self, id: str = None, cache_ttl: int = None) -> dict:
155
+ """
156
+ Retrieves detailed information about a specific exchange.
157
+
158
+ Args:
159
+ id (str, optional): The unique identifier of the exchange. Defaults to None.
160
+ cache_ttl (int, optional): The time-to-live (in seconds) for the cached data. Defaults to None.
161
+
162
+ Returns:
163
+ dict: A dictionary containing the detailed information about the specified exchange.
164
+
165
+ Raises:
166
+ ValueError: If the `id` is not provided and `None` is passed as the argument.
167
+
168
+ Example:
169
+ To get data for the exchange with id 'binance', you can call:
170
+
171
+ ```python
172
+ exchange_data = coin_gecko.get_exchange_data(id='binance')
173
+ ```
174
+
175
+ Note:
176
+ The `get_exchange_data` method uses the `redis_cache` decorator to cache the result for a specified time (`ONE_HOUR_IN_SECONDS`). This means that if the same request is made within the cache time, the cached result will be returned instead of making a new API call.
177
+ """
178
+ if id is None:
179
+ raise ValueError("Exchange ID must be provided.")
180
 
181
  result = self.cgc.exchanges.get_id(id=id)
182
  logger.debug(f"Result: {result}")
src/data_sources/cryptocompare.py CHANGED
@@ -3,10 +3,13 @@ from dotenv import load_dotenv
3
  load_dotenv()
4
 
5
  import httpx
 
6
  from src.libs.logger import logger
7
  from src.databases.redis import REDIS_CACHED
8
  from src.libs.helper_functions import convert_to_snakecase
9
  from src.libs.constants import (
 
 
10
  ONE_MINUTE_IN_SECONDS,
11
  ONE_QUARTER_IN_SECONDS,
12
  CRYPTO_COMPARE_API_BASE_URL,
@@ -15,13 +18,29 @@ from src.libs.constants import (
15
 
16
  redis_cache = REDIS_CACHED
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  class CryptoCompare:
20
  def __init__(self, base_url: str = None, asset_data_base_url: str = None) -> None:
21
  self.CRYPTO_COMPARE_API_BASE_URL = base_url or CRYPTO_COMPARE_API_BASE_URL
22
  self.CRYPTO_COMPARE_ASSET_DATA_API_BASE_URL = asset_data_base_url or CRYPTO_COMPARE_ASSET_DATA_API_BASE_URL
23
 
24
- @redis_cache(ttl=ONE_MINUTE_IN_SECONDS)
25
  @logger.instrument()
26
  def get_all_coins(self) -> dict:
27
  url = f"{self.CRYPTO_COMPARE_API_BASE_URL}data/all/coinlist"
@@ -91,4 +110,216 @@ class CryptoCompare:
91
  except httpx.HTTPError as e:
92
  logger.debug(f"An error occurred while making the request: {e}")
93
  # print(f"An error occurred while making the request: {e}")
94
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  load_dotenv()
4
 
5
  import httpx
6
+ from enum import Enum
7
  from src.libs.logger import logger
8
  from src.databases.redis import REDIS_CACHED
9
  from src.libs.helper_functions import convert_to_snakecase
10
  from src.libs.constants import (
11
+ ONE_HOUR_IN_SECONDS,
12
+ ONE_MONTH_IN_SECONDS,
13
  ONE_MINUTE_IN_SECONDS,
14
  ONE_QUARTER_IN_SECONDS,
15
  CRYPTO_COMPARE_API_BASE_URL,
 
18
 
19
  redis_cache = REDIS_CACHED
20
 
21
+ class CryptoCompareNewsSortOrder(Enum):
22
+ LATEST = "latest"
23
+ POPULAR = "popular"
24
+
25
+ def __str__(self):
26
+ return self.value
27
+
28
+ class CryptoCompareLanguages(Enum):
29
+ English = "EN"
30
+ French = "FR"
31
+ Espanol = "ES"
32
+ Turkish = "TR"
33
+ Portuguese = "PT"
34
+
35
+ def __str__(self):
36
+ return self.value
37
 
38
  class CryptoCompare:
39
  def __init__(self, base_url: str = None, asset_data_base_url: str = None) -> None:
40
  self.CRYPTO_COMPARE_API_BASE_URL = base_url or CRYPTO_COMPARE_API_BASE_URL
41
  self.CRYPTO_COMPARE_ASSET_DATA_API_BASE_URL = asset_data_base_url or CRYPTO_COMPARE_ASSET_DATA_API_BASE_URL
42
 
43
+ # @redis_cache(ttl=ONE_MINUTE_IN_SECONDS)
44
  @logger.instrument()
45
  def get_all_coins(self) -> dict:
46
  url = f"{self.CRYPTO_COMPARE_API_BASE_URL}data/all/coinlist"
 
110
  except httpx.HTTPError as e:
111
  logger.debug(f"An error occurred while making the request: {e}")
112
  # print(f"An error occurred while making the request: {e}")
113
+ return None
114
+
115
+ @redis_cache(ttl=ONE_QUARTER_IN_SECONDS)
116
+ @logger.instrument()
117
+ def get_news_categories(self, cache_ttl: int = None) -> dict:
118
+ """
119
+ Retrieves the news categories from the CryptoCompare API.
120
+
121
+ Args:
122
+ cache_ttl (int, optional): The time-to-live (TTL) for the cached response. Defaults to None.
123
+
124
+ Returns:
125
+ dict: A dictionary containing the news categories from the CryptoCompare API.
126
+
127
+ Raises:
128
+ httpx.HTTPError: If an error occurs while making the request to the CryptoCompare API.
129
+ """
130
+ url = f"{self.CRYPTO_COMPARE_API_BASE_URL}data/news/categories"
131
+ logger.debug(f"Query URL: {url}")
132
+
133
+ params = {
134
+ "api_key": os.getenv("CRYPTOCOMPARE_API_KEY"),
135
+ }
136
+ logger.debug(f"Query params: {params}")
137
+
138
+ headers = {"Content-type":"application/json; charset=UTF-8"}
139
+ logger.debug(f"Query headers {headers}")
140
+
141
+ try:
142
+ with httpx.Client(timeout=30.0) as client:
143
+ response = client.get(url, params=params, headers=headers)
144
+ response.raise_for_status() # Raise an exception if the request was unsuccessful
145
+ return response.json()
146
+ except httpx.HTTPError as e:
147
+ logger.debug(f"An error occurred while making the request: {e}")
148
+ # print(f"An error occurred while making the request: {e}")
149
+ return None
150
+
151
+ @redis_cache(ttl=ONE_HOUR_IN_SECONDS)
152
+ @logger.instrument()
153
+ def get_latest_news_articles(
154
+ self,
155
+ language: CryptoCompareLanguages = CryptoCompareLanguages.English,
156
+ sort_order: CryptoCompareNewsSortOrder = CryptoCompareNewsSortOrder.LATEST,
157
+ cache_ttl: int = None
158
+ ) -> dict:
159
+ """
160
+ Retrieves the latest news articles from the CryptoCompare API.
161
+
162
+ Args:
163
+ language (CryptoCompareLanguages, optional): The language of the news articles. Defaults to English.
164
+ sort_order (CryptoCompareNewsSortOrder, optional): The sort order of the news articles. Defaults to 'latest'.
165
+ cache_ttl (int, optional): The time-to-live (TTL) for the cached response. Defaults to None.
166
+
167
+ Returns:
168
+ dict: A dictionary containing the latest news articles from the CryptoCompare API.
169
+
170
+ Raises:
171
+ httpx.HTTPError: If an error occurs while making the request to the CryptoCompare API.
172
+
173
+ Example:
174
+ # Get the latest news articles in English, sorted by popularity
175
+ latest_news = crypto_compare_instance.get_latest_news_articles(language=CryptoCompareLanguages.English, sort_order=CryptoCompareNewsSortOrder.POPULAR)
176
+ """
177
+ url = f"{self.CRYPTO_COMPARE_API_BASE_URL}data/v2/news/"
178
+ logger.debug(f"Query URL: {url}")
179
+
180
+ params = {
181
+ "api_key": os.getenv("CRYPTOCOMPARE_API_KEY"),
182
+ "lang": language,
183
+ "sortOrder": sort_order,
184
+ }
185
+ logger.debug(f"Query params: {params}")
186
+
187
+ headers = {"Content-type":"application/json; charset=UTF-8"}
188
+ logger.debug(f"Query headers {headers}")
189
+
190
+ try:
191
+ with httpx.Client(timeout=30.0) as client:
192
+ response = client.get(url, params=params, headers=headers)
193
+ response.raise_for_status() # Raise an exception if the request was unsuccessful
194
+ return response.json()
195
+ except httpx.HTTPError as e:
196
+ logger.debug(f"An error occurred while making the request: {e}")
197
+ # print(f"An error occurred while making the request: {e}")
198
+ return None
199
+
200
+ @redis_cache(ttl=ONE_MONTH_IN_SECONDS)
201
+ @logger.instrument()
202
+ def get_all_exchanges_general_info(self, cache_ttl: int = None) -> dict:
203
+ """
204
+ Retrieves general information about all supported exchanges from the CryptoCompare API.
205
+
206
+ Args:
207
+ cache_ttl (int, optional): The time-to-live (TTL) for the cached response. Defaults to None.
208
+
209
+ Returns:
210
+ dict: A dictionary containing general information about all supported exchanges from the CryptoCompare API.
211
+
212
+ Raises:
213
+ httpx.HTTPError: If an error occurs while making the request to the CryptoCompare API.
214
+
215
+ Example:
216
+ # Get general information about all supported exchanges
217
+ all_exchanges_info = crypto_compare_instance.get_all_exchanges_general_info()
218
+ """
219
+ url = f"{self.CRYPTO_COMPARE_API_BASE_URL}data/exchanges/general"
220
+ logger.debug(f"Query URL: {url}")
221
+
222
+ params = {
223
+ "api_key": os.getenv("CRYPTOCOMPARE_API_KEY"),
224
+ }
225
+ logger.debug(f"Query params: {params}")
226
+
227
+ headers = {"Content-type":"application/json; charset=UTF-8"}
228
+ logger.debug(f"Query headers {headers}")
229
+
230
+ try:
231
+ with httpx.Client(timeout=30.0) as client:
232
+ response = client.get(url, params=params, headers=headers)
233
+ response.raise_for_status() # Raise an exception if the request was unsuccessful
234
+ return response.json()
235
+ except httpx.HTTPError as e:
236
+ logger.debug(f"An error occurred while making the request: {e}")
237
+ # print(f"An error occurred while making the request: {e}")
238
+ return None
239
+
240
+ @redis_cache(ttl=ONE_MONTH_IN_SECONDS)
241
+ @logger.instrument()
242
+ def get_all_wallets_general_info(self, cache_ttl: int = None) -> dict:
243
+ """
244
+ Retrieves general information about all supported wallets from the CryptoCompare API.
245
+
246
+ Args:
247
+ cache_ttl (int, optional): The time-to-live (TTL) for the cached response. Defaults to None.
248
+
249
+ Returns:
250
+ dict: A dictionary containing general information about all supported wallets from the CryptoCompare API.
251
+
252
+ Raises:
253
+ httpx.HTTPError: If an error occurs while making the request to the CryptoCompare API.
254
+
255
+ Example:
256
+ # Get general information about all supported wallets
257
+ all_wallets_info = crypto_compare_instance.get_all_wallets_general_info()
258
+ """
259
+ url = f"{self.CRYPTO_COMPARE_API_BASE_URL}data/wallets/general"
260
+ logger.debug(f"Query URL: {url}")
261
+
262
+ params = {
263
+ "api_key": os.getenv("CRYPTOCOMPARE_API_KEY"),
264
+ }
265
+ logger.debug(f"Query params: {params}")
266
+
267
+ headers = {"Content-type":"application/json; charset=UTF-8"}
268
+ logger.debug(f"Query headers {headers}")
269
+
270
+ try:
271
+ with httpx.Client(timeout=30.0) as client:
272
+ response = client.get(url, params=params, headers=headers)
273
+ response.raise_for_status() # Raise an exception if the request was unsuccessful
274
+ return response.json()
275
+ except httpx.HTTPError as e:
276
+ logger.debug(f"An error occurred while making the request: {e}")
277
+ # print(f"An error occurred while making the request: {e}")
278
+ return None
279
+
280
+ # @redis_cache(ttl=ONE_MONTH_IN_SECONDS)
281
+ @logger.instrument()
282
+ def get_top_tier_exchanges_list(
283
+ self,
284
+ top_tier: bool = False,
285
+ cache_ttl: int = None
286
+ ) -> dict:
287
+ """
288
+ Retrieves a list of top-tier exchanges from the CryptoCompare API.
289
+
290
+ Args:
291
+ top_tier (bool, optional): A boolean flag indicating whether to retrieve top-tier exchanges. Defaults to False.
292
+ cache_ttl (int, optional): The time-to-live (TTL) for the cached response. Defaults to None.
293
+
294
+ Returns:
295
+ dict: A dictionary containing a list of top-tier exchanges from the CryptoCompare API.
296
+
297
+ Raises:
298
+ httpx.HTTPError: If an error occurs while making the request to the CryptoCompare API.
299
+
300
+ Example:
301
+ # Get a list of top-tier exchanges
302
+ top_tier_exchanges = crypto_compare_instance.get_top_tier_exchanges_list(top_tier=True)
303
+ """
304
+ url = f"{self.CRYPTO_COMPARE_API_BASE_URL}data/v4/all/exchanges"
305
+ logger.debug(f"Query URL: {url}")
306
+
307
+ params = {
308
+ "api_key": os.getenv("CRYPTOCOMPARE_API_KEY"),
309
+ "topTier": 'true' if top_tier else 'false',
310
+ }
311
+ logger.debug(f"Query params: {params}")
312
+
313
+ headers = {"Content-type":"application/json; charset=UTF-8"}
314
+ logger.debug(f"Query headers {headers}")
315
+
316
+ try:
317
+ with httpx.Client(timeout=30.0) as client:
318
+ response = client.get(url, params=params, headers=headers)
319
+ response.raise_for_status() # Raise an exception if the request was unsuccessful
320
+ return response.json()
321
+ except httpx.HTTPError as e:
322
+ logger.debug(f"An error occurred while making the request: {e}")
323
+ # print(f"An error occurred while making the request: {e}")
324
+ return None
325
+
src/data_sources/dexscreener.py CHANGED
@@ -10,7 +10,6 @@ load_dotenv()
10
 
11
  redis_cache = REDIS_CACHED
12
 
13
-
14
  class DexScreener:
15
  """
16
  A class for interacting with the Dex Screener API.
 
10
 
11
  redis_cache = REDIS_CACHED
12
 
 
13
  class DexScreener:
14
  """
15
  A class for interacting with the Dex Screener API.
src/knowledge_bases/{knowledge_base.py → combined.py} RENAMED
@@ -1,6 +1,6 @@
1
  from phi.knowledge.combined import CombinedKnowledgeBase
2
  from phi.vectordb.pgvector import PgVector2
3
- from src.knowledge_bases.json_knowledge_base import json_knowledge_base
4
  from src.databases.postgres import sqlalchemy_engine
5
 
6
  knowledge_base = CombinedKnowledgeBase(
 
1
  from phi.knowledge.combined import CombinedKnowledgeBase
2
  from phi.vectordb.pgvector import PgVector2
3
+ from src.knowledge_bases.json import json_knowledge_base
4
  from src.databases.postgres import sqlalchemy_engine
5
 
6
  knowledge_base = CombinedKnowledgeBase(
src/knowledge_bases/data/coin_data/bnb.json DELETED
@@ -1,713 +0,0 @@
1
- {
2
- "Data": {
3
- "ID": 8,
4
- "TYPE": "162",
5
- "ID_LEGACY": 204788,
6
- "ID_PARENT_ASSET": null,
7
- "SYMBOL": "BNB",
8
- "URI": "bnb",
9
- "ASSET_TYPE": "BLOCKCHAIN",
10
- "PARENT_ASSET_SYMBOL": null,
11
- "CREATED_ON": 1661250250,
12
- "UPDATED_ON": 1717070963,
13
- "PUBLIC_NOTICE": "2024-05-30: The BNB Chain is currently in the final phase of the BNB Smart Chain Feynman Hardfork. This stage involves migrating assets from the BNB Beacon Chain to the BNB Smart Chain (BSC). Previous steps, including enabling native BSC validators, staking, cross-chain stake migration, and governance, have been completed. Stakeholders must take necessary actions before June 2024 to avoid risks associated with this migration process. For more details, visit the [BNB Chain Fusion page](https://www.bnbchain.org/en/bnb-chain-fusion).",
14
- "NAME": "Binance Coin",
15
- "LOGO_URL": "https://resources.cryptocompare.com/asset-management/8/1661250459982.png",
16
- "LAUNCH_DATE": 1555545600,
17
- "PREVIOUS_ASSET_SYMBOLS": null,
18
- "ASSET_ALTERNATIVE_IDS": [
19
- {
20
- "NAME": "CMC",
21
- "ID": 1839
22
- },
23
- {
24
- "NAME": "CG",
25
- "ID": "binancecoin"
26
- },
27
- {
28
- "NAME": "ISIN",
29
- "ID": "XT8N2VXJKB15"
30
- },
31
- {
32
- "NAME": "VALOR",
33
- "ID": "114384091"
34
- },
35
- {
36
- "NAME": "DTI",
37
- "ID": "8N2VXJKB1"
38
- }
39
- ],
40
- "ASSET_DESCRIPTION_SNIPPET": "BNB, created by Changpeng Zhao, is integral to the Binance ecosystem, serving as a versatile utility token within and outside of the Binance platform.",
41
- "ASSET_DECIMAL_POINTS": 8,
42
- "SUPPORTED_PLATFORMS": [
43
- {
44
- "BLOCKCHAIN": "MATIC",
45
- "TOKEN_STANDARD": "ERC20",
46
- "BRIDGE_OPERATOR": "PORTAL_TOKEN_BRIDGE",
47
- "IS_ASSET_ISSUER": true,
48
- "EXPLORER_URL": "https://polygonscan.com/token/0xecdcb5b88f8e3c15f95c720c51c71c9e2080525d",
49
- "SMART_CONTRACT_ADDRESS": "0xecdcb5b88f8e3c15f95c720c51c71c9e2080525d",
50
- "LAUNCH_DATE": 1636416000,
51
- "TRADING_AS": "WBNB",
52
- "DECIMALS": 18
53
- },
54
- {
55
- "BLOCKCHAIN": "SOL",
56
- "TOKEN_STANDARD": "SPL",
57
- "BRIDGE_OPERATOR": "PORTAL_TOKEN_BRIDGE",
58
- "IS_ASSET_ISSUER": true,
59
- "EXPLORER_URL": "https://solscan.io/token/9gP2kCy3wA1ctvYWQk75guqXuHfrEomqydHLtcTCqiLa",
60
- "SMART_CONTRACT_ADDRESS": "9gP2kCy3wA1ctvYWQk75guqXuHfrEomqydHLtcTCqiLa",
61
- "LAUNCH_DATE": 1633910400,
62
- "TRADING_AS": "WBNB",
63
- "DECIMALS": 8
64
- },
65
- {
66
- "BLOCKCHAIN": "ETH",
67
- "TOKEN_STANDARD": "ERC20",
68
- "BRIDGE_OPERATOR": "NATIVE_ASSET",
69
- "IS_ASSET_ISSUER": true,
70
- "EXPLORER_URL": "https://etherscan.io/token/0xB8c77482e45F1F44dE1745F52C74426C631bDD52",
71
- "SMART_CONTRACT_ADDRESS": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52",
72
- "LAUNCH_DATE": 1499212800,
73
- "TRADING_AS": "BNB",
74
- "DECIMALS": 18
75
- },
76
- {
77
- "BLOCKCHAIN": "BNB",
78
- "TOKEN_STANDARD": "BEP20",
79
- "BRIDGE_OPERATOR": "BINANCE_BRIDGE",
80
- "IS_ASSET_ISSUER": true,
81
- "EXPLORER_URL": "https://bscscan.com/token/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
82
- "SMART_CONTRACT_ADDRESS": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
83
- "LAUNCH_DATE": 1599091200,
84
- "TRADING_AS": "WBNB",
85
- "DECIMALS": 18
86
- },
87
- {
88
- "BLOCKCHAIN": "AVAX",
89
- "TOKEN_STANDARD": "ERC20",
90
- "BRIDGE_OPERATOR": "MULTICHAIN",
91
- "IS_ASSET_ISSUER": true,
92
- "EXPLORER_URL": "https://snowtrace.io/token/0x264c1383ea520f73dd837f915ef3a732e204a493",
93
- "SMART_CONTRACT_ADDRESS": "0x264c1383ea520f73dd837f915ef3a732e204a493",
94
- "LAUNCH_DATE": 1623974400,
95
- "RETIRE_DATE": 1684627200,
96
- "TRADING_AS": "BNB",
97
- "DECIMALS": 18
98
- },
99
- {
100
- "BLOCKCHAIN": "WEMIX",
101
- "TOKEN_STANDARD": "ERC20",
102
- "BRIDGE_OPERATOR": "MULTICHAIN",
103
- "IS_ASSET_ISSUER": true,
104
- "EXPLORER_URL": "https://explorer.wemix.com/token/0xC1Be9a4D5D45BeeACAE296a7BD5fADBfc14602C4",
105
- "SMART_CONTRACT_ADDRESS": "0xC1Be9a4D5D45BeeACAE296a7BD5fADBfc14602C4",
106
- "LAUNCH_DATE": 1667433600,
107
- "RETIRE_DATE": 1684627200,
108
- "TRADING_AS": "BNB",
109
- "DECIMALS": 18
110
- },
111
- {
112
- "BLOCKCHAIN": "MOVR",
113
- "TOKEN_STANDARD": "ERC20",
114
- "BRIDGE_OPERATOR": "MULTICHAIN",
115
- "IS_ASSET_ISSUER": true,
116
- "EXPLORER_URL": "https://moonriver.moonscan.io/token/0x2bf9b864cdc97b08b6d79ad4663e71b8ab65c45c",
117
- "SMART_CONTRACT_ADDRESS": "0x2bf9b864cdc97b08b6d79ad4663e71b8ab65c45c",
118
- "LAUNCH_DATE": 1630627200,
119
- "RETIRE_DATE": 1684627200,
120
- "TRADING_AS": "BNB",
121
- "DECIMALS": 18
122
- },
123
- {
124
- "BLOCKCHAIN": "GLMR",
125
- "TOKEN_STANDARD": "ERC20",
126
- "BRIDGE_OPERATOR": "MULTICHAIN",
127
- "IS_ASSET_ISSUER": true,
128
- "EXPLORER_URL": "https://moonscan.io/token/0xc9baa8cfdde8e328787e29b4b078abf2dadc2055",
129
- "SMART_CONTRACT_ADDRESS": "0xc9baa8cfdde8e328787e29b4b078abf2dadc2055",
130
- "LAUNCH_DATE": 1641945600,
131
- "RETIRE_DATE": 1684627200,
132
- "TRADING_AS": "BNB",
133
- "DECIMALS": 18
134
- },
135
- {
136
- "BLOCKCHAIN": "ETC",
137
- "TOKEN_STANDARD": "ERC20",
138
- "BRIDGE_OPERATOR": "MULTICHAIN",
139
- "IS_ASSET_ISSUER": true,
140
- "EXPLORER_URL": "https://blockscout.com/etc/mainnet/token/0x0dCb0CB0120d355CdE1ce56040be57Add0185BAa",
141
- "SMART_CONTRACT_ADDRESS": "0x0dCb0CB0120d355CdE1ce56040be57Add0185BAa",
142
- "LAUNCH_DATE": 1654819200,
143
- "RETIRE_DATE": 1684627200,
144
- "TRADING_AS": "BNB",
145
- "DECIMALS": 18
146
- },
147
- {
148
- "BLOCKCHAIN": "DOGE",
149
- "TOKEN_STANDARD": "ERC20",
150
- "BRIDGE_OPERATOR": "MULTICHAIN",
151
- "IS_ASSET_ISSUER": true,
152
- "EXPLORER_URL": "https://explorer.dogechain.dog/token/0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F",
153
- "SMART_CONTRACT_ADDRESS": "0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F",
154
- "LAUNCH_DATE": 1660780800,
155
- "RETIRE_DATE": 1684627200,
156
- "TRADING_AS": "BNB",
157
- "DECIMALS": 18
158
- },
159
- {
160
- "BLOCKCHAIN": "KAI",
161
- "TOKEN_STANDARD": "ERC20",
162
- "BRIDGE_OPERATOR": "MULTICHAIN",
163
- "IS_ASSET_ISSUER": true,
164
- "EXPLORER_URL": "https://explorer.kardiachain.io/token/0xB44a9B6905aF7c801311e8F4E76932ee959c663C",
165
- "SMART_CONTRACT_ADDRESS": "0xB44a9B6905aF7c801311e8F4E76932ee959c663C",
166
- "LAUNCH_DATE": 1656547200,
167
- "RETIRE_DATE": 1684627200,
168
- "TRADING_AS": "BNB",
169
- "DECIMALS": 18
170
- },
171
- {
172
- "BLOCKCHAIN": "FTM",
173
- "TOKEN_STANDARD": "ERC20",
174
- "BRIDGE_OPERATOR": "SPOOKYSWAP_BRIDGE",
175
- "IS_ASSET_ISSUER": true,
176
- "EXPLORER_URL": "https://ftmscan.com/token/0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454",
177
- "SMART_CONTRACT_ADDRESS": "0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454",
178
- "LAUNCH_DATE": 1620691200,
179
- "TRADING_AS": "BNB",
180
- "DECIMALS": 18
181
- },
182
- {
183
- "BLOCKCHAIN": "ETH",
184
- "TOKEN_STANDARD": "ERC20",
185
- "BRIDGE_OPERATOR": "REN_BRIDGE",
186
- "IS_ASSET_ISSUER": true,
187
- "EXPLORER_URL": "https://etherscan.io/token/0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
188
- "SMART_CONTRACT_ADDRESS": "0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
189
- "LAUNCH_DATE": 1646092800,
190
- "TRADING_AS": "RENBNB",
191
- "DECIMALS": 18,
192
- "IS_INHERITED": true
193
- },
194
- {
195
- "BLOCKCHAIN": "FTM",
196
- "TOKEN_STANDARD": "ERC20",
197
- "BRIDGE_OPERATOR": "REN_BRIDGE",
198
- "IS_ASSET_ISSUER": true,
199
- "EXPLORER_URL": "https://ftmscan.com/token/0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
200
- "SMART_CONTRACT_ADDRESS": "0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
201
- "LAUNCH_DATE": 1656979200,
202
- "TRADING_AS": "RENBNB",
203
- "DECIMALS": 18,
204
- "IS_INHERITED": true
205
- },
206
- {
207
- "BLOCKCHAIN": "MATIC",
208
- "TOKEN_STANDARD": "ERC20",
209
- "BRIDGE_OPERATOR": "REN_BRIDGE",
210
- "IS_ASSET_ISSUER": true,
211
- "EXPLORER_URL": "https://polygonscan.com/token/0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
212
- "SMART_CONTRACT_ADDRESS": "0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
213
- "LAUNCH_DATE": 1638144000,
214
- "TRADING_AS": "RENBNB",
215
- "DECIMALS": 18,
216
- "IS_INHERITED": true
217
- },
218
- {
219
- "BLOCKCHAIN": "AVAX",
220
- "TOKEN_STANDARD": "ERC20",
221
- "BRIDGE_OPERATOR": "REN_BRIDGE",
222
- "IS_ASSET_ISSUER": true,
223
- "EXPLORER_URL": "https://snowtrace.io/token/0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
224
- "SMART_CONTRACT_ADDRESS": "0xb8f7762192C840A5E4A6661D5Fa2D4d103E1d16a",
225
- "LAUNCH_DATE": 1638230400,
226
- "TRADING_AS": "RENBNB",
227
- "DECIMALS": 18,
228
- "IS_INHERITED": true
229
- }
230
- ],
231
- "ASSET_CUSTODIANS": [
232
- {
233
- "NAME": "FIREBLOCKS"
234
- },
235
- {
236
- "NAME": "BITGO"
237
- },
238
- {
239
- "NAME": "MATRIXPORT"
240
- },
241
- {
242
- "NAME": "CACTUS_CUSTODY"
243
- },
244
- {
245
- "NAME": "COBO"
246
- },
247
- {
248
- "NAME": "CYBAVO"
249
- },
250
- {
251
- "NAME": "LEDGER_ENTERPRISE"
252
- },
253
- {
254
- "NAME": "ETANA_CUSTODY"
255
- },
256
- {
257
- "NAME": "BITCOIN_SUISSE"
258
- },
259
- {
260
- "NAME": "COPPER"
261
- }
262
- ],
263
- "CONTROLLED_ADDRESSES": null,
264
- "ASSET_SECURITY_METRICS": [
265
- {
266
- "NAME": "CERTIK",
267
- "OVERALL_SCORE": 92.11,
268
- "OVERALL_RANK": 35,
269
- "UPDATED_AT": 1718236800
270
- }
271
- ],
272
- "SUPPLY_MAX": 100000000,
273
- "SUPPLY_ISSUED": 202000000,
274
- "SUPPLY_TOTAL": 147584208.501559,
275
- "SUPPLY_CIRCULATING": 147584208.50155932,
276
- "SUPPLY_FUTURE": 0,
277
- "SUPPLY_LOCKED": 0,
278
- "SUPPLY_BURNT": 54415791.498441,
279
- "SUPPLY_STAKED": null,
280
- "LAST_BLOCK_MINT": null,
281
- "LAST_BLOCK_BURN": null,
282
- "BURN_ADDRESSES": null,
283
- "LOCKED_ADDRESSES": null,
284
- "HAS_SMART_CONTRACT_CAPABILITIES": true,
285
- "SMART_CONTRACT_SUPPORT_TYPE": "ADVANCED_EXECUTION_RIGHTS",
286
- "TARGET_BLOCK_MINT": null,
287
- "TARGET_BLOCK_TIME": null,
288
- "LAST_BLOCK_NUMBER": 376559131,
289
- "LAST_BLOCK_TIMESTAMP": null,
290
- "LAST_BLOCK_TIME": null,
291
- "LAST_BLOCK_SIZE": null,
292
- "LAST_BLOCK_ISSUER": null,
293
- "LAST_BLOCK_TRANSACTION_FEE_TOTAL": null,
294
- "LAST_BLOCK_TRANSACTION_COUNT": null,
295
- "LAST_BLOCK_HASHES_PER_SECOND": null,
296
- "LAST_BLOCK_DIFFICULTY": null,
297
- "SUPPORTED_STANDARDS": [
298
- {
299
- "NAME": "BEP2"
300
- },
301
- {
302
- "NAME": "BEP20"
303
- }
304
- ],
305
- "LAYER_TWO_SOLUTIONS": [
306
- {
307
- "NAME": "opBNB",
308
- "WEBSITE_URL": "https://opbnb.bnbchain.org/en",
309
- "DESCRIPTION": "Developing on opBNB, an optimistic rollup Layer 2 scaling solution for the BNB Smart Chain, is similar to building directly on the BNB Smart Chain itself. opBNB employs an Ethereum Virtual Machine (EVM) execution engine, which allows for easy migration of decentralized applications from Ethereum, BNB Smart Chain, Polygon, and other EVM-compatible chains with minimal code changes.\n\nThe platform scales the BNB Smart Chain by bundling transactions off-chain and using fraud proofs to ensure their validity, leading to significantly higher throughput compared to the underlying chain. This compatibility with the EVM means that any decentralized application (dApp), smart contract, or other application designed for the EVM can operate on opBNB with little to no modifications required.\n\nDevelopers can deploy the same applications on opBNB to benefit from Layer 2 scaling while maintaining the security features of the BNB Smart Chain. This offers the scalability and low costs associated with a rollup solution, combined with the robust security of a Layer 1 platform, providing an efficient environment for dApps to operate effectively.",
310
- "CATEGORY": "ROLLUP"
311
- },
312
- {
313
- "NAME": "Boba Network",
314
- "WEBSITE_URL": "https://boba.network/",
315
- "DESCRIPTION": "The Boba Network, functioning as a multichain Layer 2 optimistic rollup, seeks to harness the capabilities of rollup technology while facilitating interoperability between various blockchains and real-world applications. As a hybrid blockchain, it offers off-chain data and computational resources, making it suitable for the development of sophisticated applications geared towards widespread use. Fully compatible with EVM-based tools, the Boba Network has implemented multichain support for Ethereum, Avalanche, and BNB, providing a platform for rapid transactions and reduced fees.",
316
- "CATEGORY": "ROLLUP"
317
- }
318
- ],
319
- "PRIVACY_SOLUTIONS": null,
320
- "CODE_REPOSITORIES": [
321
- {
322
- "URL": "https://github.com/binance-exchange"
323
- },
324
- {
325
- "URL": "https://github.com/binance-exchange/binance-official-api-docs",
326
- "OPEN_ISSUES": 2,
327
- "CLOSED_ISSUES": 126,
328
- "OPEN_PULL_REQUESTS": 0,
329
- "CLOSED_PULL_REQUESTS": 126,
330
- "CONTRIBUTORS": 0,
331
- "FORKS": 2136,
332
- "STARS": 3832,
333
- "SUBSCRIBERS": 499,
334
- "LAST_UPDATED_TS": 1690372964,
335
- "LAST_PUSH_TS": 1682283934,
336
- "CODE_SIZE_IN_BYTES": 1,
337
- "IS_FORK": false,
338
- "LANGUAGE": null,
339
- "FORKED_ASSET_DATA": null
340
- },
341
- {
342
- "URL": "https://github.com/binance-exchange/binance-api-node",
343
- "OPEN_ISSUES": 1,
344
- "CLOSED_ISSUES": 25,
345
- "OPEN_PULL_REQUESTS": 0,
346
- "CLOSED_PULL_REQUESTS": 25,
347
- "CONTRIBUTORS": 102,
348
- "FORKS": 176,
349
- "STARS": 568,
350
- "SUBSCRIBERS": 44,
351
- "LAST_UPDATED_TS": 1690375176,
352
- "LAST_PUSH_TS": 1686157630,
353
- "CODE_SIZE_IN_BYTES": 739,
354
- "IS_FORK": true,
355
- "LANGUAGE": "JavaScript",
356
- "FORKED_ASSET_DATA": null
357
- },
358
- {
359
- "URL": "https://github.com/binance-exchange/go-binance",
360
- "OPEN_ISSUES": 9,
361
- "CLOSED_ISSUES": 10,
362
- "OPEN_PULL_REQUESTS": 9,
363
- "CLOSED_PULL_REQUESTS": 10,
364
- "CONTRIBUTORS": 3,
365
- "FORKS": 102,
366
- "STARS": 214,
367
- "SUBSCRIBERS": 22,
368
- "LAST_UPDATED_TS": 1690375177,
369
- "LAST_PUSH_TS": 1595796163,
370
- "CODE_SIZE_IN_BYTES": 1599,
371
- "IS_FORK": true,
372
- "LANGUAGE": "Go",
373
- "FORKED_ASSET_DATA": null
374
- },
375
- {
376
- "URL": "https://github.com/binance-exchange/node-binance-api",
377
- "OPEN_ISSUES": 18,
378
- "CLOSED_ISSUES": 214,
379
- "OPEN_PULL_REQUESTS": 0,
380
- "CLOSED_PULL_REQUESTS": 109,
381
- "CONTRIBUTORS": 82,
382
- "FORKS": 150,
383
- "STARS": 521,
384
- "SUBSCRIBERS": 42,
385
- "LAST_UPDATED_TS": 1690372966,
386
- "LAST_PUSH_TS": 1682296247,
387
- "CODE_SIZE_IN_BYTES": 1217,
388
- "IS_FORK": true,
389
- "LANGUAGE": "JavaScript",
390
- "FORKED_ASSET_DATA": null
391
- },
392
- {
393
- "URL": "https://github.com/binance-exchange/python-binance",
394
- "OPEN_ISSUES": 4,
395
- "CLOSED_ISSUES": 0,
396
- "OPEN_PULL_REQUESTS": 4,
397
- "CLOSED_PULL_REQUESTS": 0,
398
- "CONTRIBUTORS": 21,
399
- "FORKS": 182,
400
- "STARS": 452,
401
- "SUBSCRIBERS": 68,
402
- "LAST_UPDATED_TS": 1690372967,
403
- "LAST_PUSH_TS": 1531807102,
404
- "CODE_SIZE_IN_BYTES": 347,
405
- "IS_FORK": true,
406
- "LANGUAGE": "Python",
407
- "FORKED_ASSET_DATA": null
408
- },
409
- {
410
- "URL": "https://github.com/binance-exchange/binance-java-api",
411
- "OPEN_ISSUES": 154,
412
- "CLOSED_ISSUES": 281,
413
- "OPEN_PULL_REQUESTS": 41,
414
- "CLOSED_PULL_REQUESTS": 97,
415
- "CONTRIBUTORS": 43,
416
- "FORKS": 640,
417
- "STARS": 826,
418
- "SUBSCRIBERS": 97,
419
- "LAST_UPDATED_TS": 1690375177,
420
- "LAST_PUSH_TS": 1686147366,
421
- "CODE_SIZE_IN_BYTES": 440,
422
- "IS_FORK": true,
423
- "LANGUAGE": "Java",
424
- "FORKED_ASSET_DATA": null
425
- }
426
- ],
427
- "SUBREDDITS": [
428
- {
429
- "URL": "https://reddit.com/r/binance",
430
- "MAKE_3RD_PARTY_REQUEST": true,
431
- "NAME": "binance",
432
- "CURRENT_ACTIVE_USERS": 43,
433
- "AVERAGE_POSTS_PER_DAY": 0.22,
434
- "AVERAGE_POSTS_PER_HOUR": 0.01,
435
- "AVERAGE_COMMENTS_PER_DAY": 18.05,
436
- "AVERAGE_COMMENTS_PER_HOUR": 0.75,
437
- "SUBSCRIBERS": 904498,
438
- "COMMUNITY_CREATED_AT": 1498873536,
439
- "LAST_UPDATED_TS": 1718367530
440
- }
441
- ],
442
- "TWITTER_ACCOUNTS": [
443
- {
444
- "URL": "https://twitter.com/binance",
445
- "MAKE_3RD_PARTY_REQUEST": true,
446
- "NAME": "Binance",
447
- "USERNAME": "binance",
448
- "VERIFIED": true,
449
- "VERIFIED_TYPE": "business",
450
- "FOLLOWING": 0,
451
- "FOLLOWERS": 10858205,
452
- "FAVOURITES": 0,
453
- "LISTS": 29826,
454
- "STATUSES": 29219,
455
- "ACCOUNT_CREATED_AT": 1498120695,
456
- "LAST_UPDATED_TS": 1698775503
457
- }
458
- ],
459
- "DISCORD_SERVERS": [
460
- {
461
- "URL": "https://discord.com/invite/jE4wt8g2H2",
462
- "MAKE_3RD_PARTY_REQUEST": false,
463
- "NAME": "Binance",
464
- "TOTAL_MEMBERS": 91925,
465
- "CURRENT_ACTIVE_USERS": 7886,
466
- "PREMIUM_SUBSCRIBERS": 25,
467
- "LAST_UPDATED_TS": 1691075162
468
- }
469
- ],
470
- "TELEGRAM_GROUPS": [
471
- {
472
- "URL": "https://t.me/BNBchaincommunity",
473
- "MAKE_3RD_PARTY_REQUEST": false,
474
- "NAME": "BNB Chain Community",
475
- "USERNAME": "BNBchaincommunity",
476
- "MEMBERS": 118577,
477
- "LAST_UPDATED_TS": 1695279793
478
- }
479
- ],
480
- "OTHER_SOCIAL_NETWORKS": [
481
- {
482
- "NAME": "FACEBOOK",
483
- "URL": "https://www.facebook.com/binance"
484
- },
485
- {
486
- "NAME": "INSTAGRAM",
487
- "URL": "https://www.instagram.com/Binance/"
488
- },
489
- {
490
- "NAME": "YOUTUBE",
491
- "URL": "https://www.youtube.com/binanceyoutube"
492
- },
493
- {
494
- "NAME": "LINKEDIN",
495
- "URL": "https://www.linkedin.com/company/binance"
496
- }
497
- ],
498
- "HELD_TOKEN_SALE": true,
499
- "TOKEN_SALES": [
500
- {
501
- "TOKEN_SALE_TYPE": "ICO",
502
- "TOKEN_SALE_DATE_START": 1498435200,
503
- "TOKEN_SALE_DATE_END": 1499040000,
504
- "TOKEN_SALE_DESCRIPTION": "Binance held its ICO on the 26th of June, with the ICO supply representing half of the total 200M token supply, thus selling 100,000,000 BNB tokens and raising $15,000,000. The ICO ended on the 3rd of July. The issue price was 1 ETH for 2,700 BNB or 1 BTC for 20,000 BNB (around 0.11 USD back then).",
505
- "TOKEN_SALE_TEAM_MEMBERS": [
506
- {
507
- "TYPE": "EMPLOYEE",
508
- "FULL_NAME": "Changpeng Zhao"
509
- },
510
- {
511
- "TYPE": "EMPLOYEE",
512
- "FULL_NAME": "Roger Wang"
513
- },
514
- {
515
- "TYPE": "EMPLOYEE",
516
- "FULL_NAME": "James Hofbauer"
517
- },
518
- {
519
- "TYPE": "EMPLOYEE",
520
- "FULL_NAME": "Paul Jankunas"
521
- }
522
- ],
523
- "TOKEN_SALE_WEBSITE_URL": "https://www.binance.com/",
524
- "TOKEN_SALE_SUPPLY": 100000000,
525
- "TOKEN_SUPPLY_POST_SALE": "DECREASES",
526
- "TOKEN_SALE_PAYMENT_METHOD_TYPE": "CRYPTO",
527
- "TOKEN_SALE_START_PRICE": 0.15,
528
- "TOKEN_SALE_START_PRICE_CURRENCY": "USD",
529
- "TOKEN_SALE_FUNDS_RAISED": [
530
- {
531
- "CURRENCY": "BNB",
532
- "TOTAL_VALUE": 100000000,
533
- "DESCRIPTION": "Out of the total 200 million BNB token supply, 100 million BNB coins were sold during the ICO at a Binance ICO price of 2,700 BNB for 1 ETH"
534
- }
535
- ],
536
- "TOKEN_SALE_FUNDS_RAISED_USD": 15000000,
537
- "TOKEN_SALE_INVESTORS_SPLIT": [
538
- {
539
- "CATEGORY": "PUBLIC",
540
- "TOTAL_TOKENS": 50000000
541
- }
542
- ],
543
- "TOKEN_SALE_RESERVE_SPLIT": [
544
- {
545
- "CATEGORY": "TEAM",
546
- "TOTAL_TOKENS": 80000000
547
- },
548
- {
549
- "CATEGORY": "TEAM",
550
- "TOTAL_TOKENS": 20000000
551
- }
552
- ],
553
- "TOKEN_SALE_JURISDICTIONS": [
554
- {
555
- "NAME": "KY"
556
- }
557
- ],
558
- "TOKEN_SALE_LEGAL_FORMS": [
559
- {
560
- "NAME": "CORPORATION"
561
- }
562
- ]
563
- }
564
- ],
565
- "HELD_EQUITY_SALE": false,
566
- "WEBSITE_URL": "https://www.binance.com/",
567
- "BLOG_URL": "https://www.binance.com/en/blog",
568
- "WHITE_PAPER_URL": "https://resources.cryptocompare.com/asset-management/8/1661250302524.pdf",
569
- "OTHER_DOCUMENT_URLS": [
570
- {
571
- "TYPE": "TOKEN_ECONOMICS",
572
- "VERSION": 1,
573
- "URL": "https://resources.cryptocompare.com/asset-management/8/1664528054778.pdf",
574
- "COMMENT": "\"Tokenomics Deep Dive\""
575
- },
576
- {
577
- "TYPE": "AUDIT",
578
- "URL": "https://resources.cryptocompare.com/asset-management/8/1702984453160.pdf",
579
- "COMMENT": "Certik audit"
580
- },
581
- {
582
- "TYPE": "AUDIT",
583
- "URL": "https://resources.cryptocompare.com/asset-management/8/1702984652594.pdf",
584
- "COMMENT": "Hacken audit"
585
- },
586
- {
587
- "TYPE": "ROADMAP",
588
- "URL": "https://resources.cryptocompare.com/asset-management/8/1703172228924.pdf",
589
- "COMMENT": "Uploaded 21/12/2023"
590
- },
591
- {
592
- "TYPE": "ROADMAP",
593
- "URL": "https://resources.cryptocompare.com/asset-management/8/1703172721792.pdf",
594
- "COMMENT": "BNB Chain Fusion Roadmap"
595
- },
596
- {
597
- "TYPE": "ESG_REPORT",
598
- "URL": "https://resources.cryptocompare.com/asset-management/8/1703174584333.pdf",
599
- "COMMENT": "Governance of BSC"
600
- },
601
- {
602
- "TYPE": "ESG_REPORT",
603
- "URL": "https://resources.cryptocompare.com/asset-management/8/1703174851909.pdf",
604
- "COMMENT": "Governance of BNB Beacon Chain"
605
- }
606
- ],
607
- "EXPLORER_ADDRESSES": [
608
- {
609
- "URL": "https://explorer.bnbchain.org/"
610
- },
611
- {
612
- "URL": "https://bscscan.com/"
613
- },
614
- {
615
- "URL": "https://binance.mintscan.io/"
616
- },
617
- {
618
- "URL": "https://explorer.bitquery.io/bsc"
619
- },
620
- {
621
- "URL": "https://bsctrace.com/"
622
- },
623
- {
624
- "URL": "https://www.oklink.com/bsc"
625
- },
626
- {
627
- "URL": "https://getblock.io/explorers/bsc/"
628
- },
629
- {
630
- "URL": "https://blockchair.com/bnb"
631
- },
632
- {
633
- "URL": "https://bsc.tokenview.io/"
634
- },
635
- {
636
- "URL": "https://bnb.dex.guru/"
637
- }
638
- ],
639
- "ASSET_INDUSTRIES": [
640
- {
641
- "ASSET_INDUSTRY": "PLATFORM"
642
- },
643
- {
644
- "ASSET_INDUSTRY": "BRIDGE_OPERATOR"
645
- },
646
- {
647
- "ASSET_INDUSTRY": "PAYMENTS"
648
- }
649
- ],
650
- "CONSENSUS_MECHANISMS": [
651
- {
652
- "NAME": "POS"
653
- },
654
- {
655
- "NAME": "POA"
656
- }
657
- ],
658
- "CONSENSUS_ALGORITHM_TYPES": [
659
- {
660
- "NAME": "Tendermint BFT",
661
- "DESCRIPTION": "Binance Chain relies on the Tendermint BFT consensus and Delegated Proof of Stake (DPoS) with a dedicated application layer that runs upon it. As of today, the vote delegation feature is not open for users.\n\nBinance Chain is built on forks of Tendermint and Cosmos SDK. Specifically, Binance Chain is made on a revised edition of the Tendermint consensus while leveraging its P2P networking logic.\n\nAt any given state, the following information is being recorded:\n\n- Account and balances: the balance (i.e., the number of tokens) of each asset is composed of 3 different parts: locked, frozen, and available. It is recorded on all accounts.\n- Fees: it represents how much fees were paid in the previous block.\n- Token information: what are the tokens, along with their respective information (frozen supply, etc.)\n- Trading pairs: the list of all the trading pairs on Binance DEX.\n- Tick size and lot size: various information related to the trading engine of Binance DEX.\n- Governance information: information about the validators, and governance mechanism of the Binance Chain."
662
- },
663
- {
664
- "NAME": "Proof-of-Staked Authority (PoSA)",
665
- "DESCRIPTION": "The Binance Smart Chain combines several features from Delegated Proof-of-Stake (DPoS) and Proof-of-Authority (PoA) for consensus finding.\n\nAt its core, this consensus algorithm called Parlia is built on a network of 21 validators and delegators, who vote for validators.\n\nIn Binance Smart Chain, any party can attempt to become a validator, assuming they meet (1) the hardware requirement to run the network, (2) manage their own keys, (3) guarantee a high uptime and (4) own and stake at least 20,000 BNB. Similar to other DPoS blockchains, BSC validators receive network fees for validating blocks.\n\nAs of writing, the top 21 validators with the largest number of BNBs staked are selected every day and eligible to validate and produce blocks on the Binance Smart Chain. \n\nDelegators can vote for validators, allocating BNB to increase the validator\u2019s capacity to produce blocks, while receiving some of the rewards from network fees. This election is repeated every 24 hours. At the end of the period, the staking status decides what the top 21 highest nodes with votes to become the validator set for the next period are.\n\nIn addition, Binance Smart Chain introduces a slashing mechanism to prevent bad behaviour and other issues: e.g., prevent double signatures, penalties for being offline, etc.\n\nFor instance, BSC\u2019s slashing mechanism allows any individual to submit a \u201cslashing request\u201d on Binance Chain, assuming they are able to bring the proof that the malicious validator produced two block headers with the same height and parent block."
666
- }
667
- ],
668
- "HASHING_ALGORITHM_TYPES": [
669
- {
670
- "NAME": "SHA_256"
671
- }
672
- ],
673
- "PRICE_USD": 605.351392574596,
674
- "PRICE_USD_SOURCE": "cadli",
675
- "PRICE_USD_LAST_UPDATE_TS": 1718377245,
676
- "MKT_CAP_PENALTY": 0,
677
- "CIRCULATING_MKT_CAP_USD": 89340306138.43848,
678
- "TOTAL_MKT_CAP_USD": 89340306138.43828,
679
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_DIRECT_USD": 5717.5208552127,
680
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_DIRECT_USD": 681557.540655213,
681
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_USD": 337790572.034656,
682
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD": 507742353.298955,
683
- "SPOT_MOVING_24_HOUR_CHANGE_USD": 8.158248751072,
684
- "SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD": 1.3660988635667999,
685
- "TOPLIST_BASE_RANK": {
686
- "LAUNCH_DATE": 4601,
687
- "CIRCULATING_MKT_CAP_USD": 4,
688
- "TOTAL_MKT_CAP_USD": 4,
689
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD": 8,
690
- "SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD": 1037
691
- },
692
- "ASSET_DESCRIPTION": "## What is Binance Coin (BNB)?\nBinance Coin, known as BNB, is the cryptocurrency token that powers the BNB Chain ecosystem. Initially referred to as Binance Coin, it plays a central role in the functionalities of the Binance ecosystem, which includes the world's largest cryptocurrency exchange by volume. BNB operates as a utility token, allowing users to trade it like any other cryptocurrency. Furthermore, BNB is used in a variety of applications and use cases, extending its utility beyond mere trading. The Binance Chain, supporting BNB, uses a Byzantine Fault Tolerance (BFT) consensus mechanism for fast and efficient transaction processing.\n\nBinance is a cryptocurrency exchange platform. It offers a variety of services including cryptocurrency trading, digital asset management, and various blockchain-based offerings. Binance is known for supporting a wide array of cryptocurrencies for trading. The platform also provides features like crypto-to-crypto trading, staking, and an option for users to participate in initial coin offerings (ICOs) and token sales. The exchange is designed to cater to both beginner and experienced traders, offering a range of tools and functionalities tailored to different levels of expertise in the cryptocurrency market.\n\n## What is Binance Coin (BNB) used for?\nBNB was initially used mainly to pay for trading and transaction fees on the Binance cryptocurrency exchange. Over time, its utility has expanded significantly. Today, BNB is used in various applications within and outside the Binance ecosystem, showcasing its versatility as a utility token. The token's role in facilitating various transactions and activities within the Binance ecosystem has been a key factor in its widespread adoption and use. Additionally, the introduction of the Binance Smart Chain, a parallel blockchain, has enabled smart contract functionality and interoperability, further expanding BNB's use cases.\n\n## Who created Binance Coin (BNB)?\nBinance Coin (BNB) was founded in 2017 by Changpeng Zhao, a tech entrepreneur commonly referred to as CZ. He established BNB as the native utility token of the Binance exchange. The BNB Chain employs a unique combination of Proof of Stake (PoS) and Proof of Authority (PoA) consensus mechanisms to validate network transactions, contributing to the security and efficiency of the ecosystem.",
693
- "ASSET_DESCRIPTION_SUMMARY": "Binance Coin (BNB) is a cryptocurrency token central to the Binance ecosystem, including the world's largest cryptocurrency exchange. Created by Changpeng Zhao in 2017, BNB has evolved from a tool for paying transaction fees on the Binance exchange to a widely used utility token in various applications. Its importance in the Binance ecosystem is underscored by its role in facilitating transactions and activities across the platform.",
694
- "PROJECT_LEADERS": [
695
- {
696
- "LEADER_TYPE": "FOUNDER",
697
- "FULL_NAME": "Changpeng Zhao"
698
- },
699
- {
700
- "LEADER_TYPE": "FOUNDER",
701
- "FULL_NAME": "Yi He"
702
- }
703
- ],
704
- "ASSOCIATED_CONTACT_DETAILS": [
705
- {
706
- "CONTACT_MEDIUM": "EMAIL_ADDRESS"
707
- }
708
- ],
709
- "SEO_TITLE": "Binance Coin (BNB)",
710
- "SEO_DESCRIPTION": "Live Binance Coin price movements from all markets and BNB market cap, use our charts and see when there is an opportunity to buy or sell."
711
- },
712
- "Err": {}
713
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/knowledge_bases/data/coin_data/pepe.json DELETED
@@ -1,158 +0,0 @@
1
- {
2
- "Data": {
3
- "ID": 3010,
4
- "TYPE": "162",
5
- "ID_LEGACY": 953245,
6
- "ID_PARENT_ASSET": null,
7
- "SYMBOL": "PEPE",
8
- "URI": "pepe",
9
- "ASSET_TYPE": "TOKEN",
10
- "PARENT_ASSET_SYMBOL": null,
11
- "CREATED_ON": 1683799924,
12
- "UPDATED_ON": 1709050507,
13
- "PUBLIC_NOTICE": null,
14
- "NAME": "Pepe",
15
- "LOGO_URL": "https://resources.cryptocompare.com/asset-management/3010/1709049889749.png",
16
- "LAUNCH_DATE": 1681430400,
17
- "PREVIOUS_ASSET_SYMBOLS": null,
18
- "ASSET_ALTERNATIVE_IDS": [
19
- {
20
- "NAME": "CG",
21
- "ID": "pepe"
22
- },
23
- {
24
- "NAME": "CMC",
25
- "ID": 24478
26
- }
27
- ],
28
- "ASSET_DESCRIPTION_SNIPPET": "$PEPE is an ERC-20 token, known as the most memeable memecoin, embracing the internet meme Pepe's popularity. Unlike other meme-based cryptocurrencies, it launched stealthily without presale or taxes, aiming to be a coin for the people.",
29
- "SUPPORTED_PLATFORMS": [
30
- {
31
- "BLOCKCHAIN": "ETH",
32
- "TOKEN_STANDARD": "ERC20",
33
- "BRIDGE_OPERATOR": "NATIVE_ASSET",
34
- "IS_ASSET_ISSUER": true,
35
- "EXPLORER_URL": "https://etherscan.io/token/0x6982508145454Ce325dDbE47a25d4ec3d2311933",
36
- "SMART_CONTRACT_ADDRESS": "0x6982508145454Ce325dDbE47a25d4ec3d2311933",
37
- "LAUNCH_DATE": 1681430400,
38
- "TRADING_AS": "PEPE",
39
- "DECIMALS": 18
40
- }
41
- ],
42
- "ASSET_CUSTODIANS": null,
43
- "CONTROLLED_ADDRESSES": null,
44
- "ASSET_SECURITY_METRICS": [
45
- {
46
- "NAME": "CERTIK",
47
- "OVERALL_SCORE": 86.87,
48
- "OVERALL_RANK": 211,
49
- "UPDATED_AT": 1718409600
50
- }
51
- ],
52
- "SUPPLY_MAX": -1,
53
- "SUPPLY_ISSUED": 420689899999995,
54
- "SUPPLY_TOTAL": 420689899999995,
55
- "SUPPLY_CIRCULATING": 420689899999995,
56
- "SUPPLY_FUTURE": -1,
57
- "SUPPLY_LOCKED": 0,
58
- "SUPPLY_BURNT": 0,
59
- "SUPPLY_STAKED": null,
60
- "BURN_ADDRESSES": null,
61
- "LOCKED_ADDRESSES": null,
62
- "CODE_REPOSITORIES": null,
63
- "SUBREDDITS": null,
64
- "TWITTER_ACCOUNTS": [
65
- {
66
- "URL": "https://twitter.com/pepecoineth",
67
- "NAME": "Pepe",
68
- "USERNAME": "pepecoineth",
69
- "FOLLOWING": 1,
70
- "FOLLOWERS": 413507,
71
- "FAVOURITES": 254,
72
- "LISTS": 458,
73
- "STATUSES": 407,
74
- "ACCOUNT_CREATED_AT": 1680625027,
75
- "LAST_UPDATED_TS": 1689344201
76
- }
77
- ],
78
- "DISCORD_SERVERS": [
79
- {
80
- "URL": "https://discord.com/invite/pepe-palace",
81
- "MAKE_3RD_PARTY_REQUEST": false,
82
- "NAME": "\ud83d\udc38Pepe Palace\ud83d\udc38",
83
- "TOTAL_MEMBERS": 16821,
84
- "CURRENT_ACTIVE_USERS": 1262,
85
- "PREMIUM_SUBSCRIBERS": 14,
86
- "LAST_UPDATED_TS": 1688912388
87
- }
88
- ],
89
- "TELEGRAM_GROUPS": [
90
- {
91
- "URL": "https://t.me/pepecoineth"
92
- }
93
- ],
94
- "OTHER_SOCIAL_NETWORKS": null,
95
- "HELD_TOKEN_SALE": false,
96
- "HELD_EQUITY_SALE": false,
97
- "WEBSITE_URL": "https://www.pepe.vip/",
98
- "BLOG_URL": null,
99
- "WHITE_PAPER_URL": null,
100
- "OTHER_DOCUMENT_URLS": [
101
- {
102
- "TYPE": "ROADMAP",
103
- "URL": "https://resources.cryptocompare.com/asset-management/3010/1683800472809.png"
104
- },
105
- {
106
- "TYPE": "TOKEN_ECONOMICS",
107
- "URL": "https://resources.cryptocompare.com/asset-management/3010/1683800517243.png"
108
- },
109
- {
110
- "TYPE": "AUDIT",
111
- "URL": "https://resources.cryptocompare.com/asset-management/3010/1699438872469.pdf",
112
- "COMMENT": "Pepe-Token-Audit-Report 2023-08-21"
113
- },
114
- {
115
- "TYPE": "AUDIT",
116
- "URL": "https://resources.cryptocompare.com/asset-management/3010/1709050208378.pdf",
117
- "COMMENT": "Certik audit"
118
- }
119
- ],
120
- "ASSET_INDUSTRIES": [
121
- {
122
- "ASSET_INDUSTRY": "PLATFORM"
123
- },
124
- {
125
- "ASSET_INDUSTRY": "PAYMENT"
126
- },
127
- {
128
- "ASSET_INDUSTRY": "BRIDGE_OPERATOR"
129
- }
130
- ],
131
- "PRICE_USD": 1.23046108057731e-05,
132
- "PRICE_USD_SOURCE": "cadli",
133
- "PRICE_USD_LAST_UPDATE_TS": 1718570876,
134
- "MKT_CAP_PENALTY": null,
135
- "CIRCULATING_MKT_CAP_USD": 5176425489.419543,
136
- "TOTAL_MKT_CAP_USD": 5176425489.419543,
137
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_DIRECT_USD": 4732463.87575718,
138
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_DIRECT_USD": 15781091.0909223,
139
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_USD": 335538908.468033,
140
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD": 425993603.001758,
141
- "SPOT_MOVING_24_HOUR_CHANGE_USD": 4.714449013124e-07,
142
- "SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD": 3.9840977902175903,
143
- "TOPLIST_BASE_RANK": {
144
- "LAUNCH_DATE": 10706,
145
- "CIRCULATING_MKT_CAP_USD": 23,
146
- "TOTAL_MKT_CAP_USD": 38,
147
- "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD": 7,
148
- "SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD": 614
149
- },
150
- "ASSET_DESCRIPTION": "## What is Pepe (PEPE)?\n\nPepe (PEPE) is a digital currency positioned as the next step in the evolution of meme coins, leveraging the memetic power of Pepe, a recognizable internet meme. Launched without any presale or taxes, PEPE aims to be a coin for the people, with its liquidity provider tokens burned and contract renounced.\n\n## Who created Pepe?\n\nThe specific creator of Pepe (PEPE) is not mentioned, but it is clarified that it is not associated with Matt Furie or his creation Pepe the Frog. Instead, it pays homage to the meme character.\n\n## What is $PEPE used for?\n\nThe PEPE token serves as a meme coin with no intrinsic value or financial return expectation. It follows a roadmap with phases like getting listed on popular crypto platforms, community partnerships, launching Pepe Times newsletter, token-gated Discord group, and plans for Pepe merchandise and academy. PEPE is intended to be entirely useless and solely for entertainment purposes.",
151
- "ASSET_DESCRIPTION_SUMMARY": "Pepe (PEPE) is a digital currency that positions itself as the next step in meme coin evolution, leveraging the memetic power of the internet meme Pepe. Launched without presale or taxes, it aims to be a coin for the people, with liquidity provider tokens burned and contract renounced. The token has a roadmap with different phases, including community partnerships, launching a digital newsletter, and getting listed on exchanges. However, it's important to note that PEPE is not associated with Pepe the Frog and is intended to be entirely useless and for entertainment purposes only.",
152
- "PROJECT_LEADERS": null,
153
- "ASSOCIATED_CONTACT_DETAILS": null,
154
- "SEO_TITLE": "Pepe (PEPE)",
155
- "SEO_DESCRIPTION": "Live Pepe price movements from all markets and PEPE market cap, use our charts and see when there is an opportunity to buy or sell."
156
- },
157
- "Err": {}
158
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/knowledge_bases/json.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from fs_s3fs import S3FS
3
+ from src.libs.logger import logger
4
+ from src.libs.s3fs import get_s3_credentials
5
+ from phi.vectordb.pgvector import PgVector2
6
+ from phi.knowledge.json import JSONKnowledgeBase
7
+ from src.databases.postgres import sqlalchemy_engine
8
+
9
+ class JSONKnowledgeBaseExtended(JSONKnowledgeBase):
10
+ s3fs: S3FS = None # Explicitly declare the s3fs attribute
11
+
12
+ def __init__(
13
+ self,
14
+ s3_bucket_name,
15
+ vector_db,
16
+ s3_access_key_id,
17
+ s3_secret_access_key,
18
+ s3_endpoint_url,
19
+ s3_region,
20
+ ):
21
+ super().__init__(path=s3_bucket_name, vector_db=vector_db, bucket_name = s3_bucket_name)
22
+
23
+ # Initialize the S3 filesystem
24
+ self.s3fs = S3FS(
25
+ bucket_name=s3_bucket_name,
26
+ aws_access_key_id=s3_access_key_id,
27
+ aws_secret_access_key=s3_secret_access_key,
28
+ endpoint_url = s3_endpoint_url,
29
+ region = s3_region,
30
+ )
31
+
32
+ def load_knowledge_base(self, recreate: bool = False):
33
+ json_knowledge_base.load(recreate=recreate)
34
+
35
+ def store_json_data_in_s3(self, json_data, file_path):
36
+ if file_path[0] == '/':
37
+ file_path = f"/json-data/{file_path[1:]}"
38
+ else:
39
+ file_path = f"/json-data/{file_path}"
40
+
41
+ logger.info(f"Storing JSON data in S3 bucket: {self.s3fs._bucket_name} at path: {file_path}")
42
+
43
+ # Open the file in write mode and write the JSON data
44
+ self.s3fs.open(path = f"/{file_path}", mode = 'w').write(json.dumps(json_data, indent=2))
45
+ return True
46
+
47
+
48
+ # S3 credentials
49
+ _s3_credendtials = get_s3_credentials()
50
+ _json_knowledge_base_arguments = {
51
+ "vector_db": PgVector2(
52
+ collection="json_documents",
53
+ db_engine=sqlalchemy_engine
54
+ ),
55
+ **_s3_credendtials
56
+ }
57
+
58
+ # Initialize the extended JSONKnowledgeBase with the S3 bucket name and S3 credentials
59
+ json_knowledge_base = JSONKnowledgeBaseExtended(
60
+ **_json_knowledge_base_arguments
61
+ )
src/knowledge_bases/json_knowledge_base.py DELETED
@@ -1,12 +0,0 @@
1
- from phi.knowledge.json import JSONKnowledgeBase
2
- from phi.vectordb.pgvector import PgVector2
3
- from src.databases.postgres import sqlalchemy_engine
4
-
5
- json_knowledge_base = JSONKnowledgeBase(
6
- path="data/json",
7
- # Table name: ai.json_documents
8
- vector_db=PgVector2(
9
- collection="json_documents",
10
- db_engine=sqlalchemy_engine
11
- ),
12
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
src/knowledge_bases/pipeline.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from chainlit import make_async
2
+ from src.data_sources.cryptocompare import CryptoCompare
3
+ from src.data_sources.coin_gecko import CoinGecko
4
+ from src.knowledge_bases.json import json_knowledge_base
5
+
6
+ coin_gecko = CoinGecko()
7
+ crypto_compare = CryptoCompare()
8
+
9
+ store_json_data_in_s3 = make_async(json_knowledge_base.store_json_data_in_s3)
10
+
11
+ async def fetch_and_load_crypto_compare_json_data():
12
+ get_all_coins = make_async(crypto_compare.get_all_coins)
13
+ get_news_categories = make_async(crypto_compare.get_news_categories)
14
+ get_top_tier_exchanges_list = make_async(crypto_compare.get_top_tier_exchanges_list)
15
+ get_all_wallets_general_info = make_async(crypto_compare.get_all_wallets_general_info)
16
+ get_all_exchanges_general_info = make_async(crypto_compare.get_all_exchanges_general_info)
17
+
18
+ all_coins = await get_all_coins()
19
+ news_categories = await get_news_categories()
20
+ top_tier_exchanges_list = await get_top_tier_exchanges_list()
21
+ all_wallets_general_info = await get_all_wallets_general_info()
22
+ all_exchanges_general_info = await get_all_exchanges_general_info()
23
+
24
+ await store_json_data_in_s3(all_coins, "crypto_compare_all_coins.json")
25
+ await store_json_data_in_s3(news_categories, "crypto_compare_news_categories.json")
26
+ await store_json_data_in_s3(top_tier_exchanges_list, "crypto_compare_top_tier_exchanges_list.json")
27
+ await store_json_data_in_s3(all_wallets_general_info, "crypto_compare_all_wallets_general_info.json")
28
+ await store_json_data_in_s3(all_exchanges_general_info, "crypto_compare_all_exchanges_general_info.json")
29
+
30
+ async def fetch_and_load_coin_gecko_json_data():
31
+ get_all_coins = make_async(coin_gecko.get_exchanges_list)
32
+
33
+ all_exchange_data = await get_all_coins()
34
+
35
+ await store_json_data_in_s3(all_exchange_data, "coin_gecko_all_exchange_data")
36
+
37
+ async def load_json_data_into_knowledge_base():
38
+ load_knowledge_base = make_async(json_knowledge_base.load_knowledge_base)
39
+
40
+ await load_knowledge_base(recreate=True)
41
+
42
+ async def main():
43
+ await fetch_and_load_coin_gecko_json_data()
44
+ await fetch_and_load_crypto_compare_json_data()
45
+ await load_json_data_into_knowledge_base()
src/libs/logger.py CHANGED
@@ -7,7 +7,7 @@ load_dotenv()
7
 
8
  lf.configure(
9
  token=os.getenv('LOGFIRE_TOKEN'),
10
- pydantic_plugin=lf.PydanticPlugin(record='all'),
11
  console=lf.ConsoleOptions(min_log_level= os.getenv('LOG_LEVEL'))
12
  )
13
  lf.instrument_redis()
 
7
 
8
  lf.configure(
9
  token=os.getenv('LOGFIRE_TOKEN'),
10
+ # pydantic_plugin=lf.PydanticPlugin(record='all'),
11
  console=lf.ConsoleOptions(min_log_level= os.getenv('LOG_LEVEL'))
12
  )
13
  lf.instrument_redis()
src/libs/s3fs.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import s3fs
3
+ from fs_s3fs import S3FS
4
+ from dotenv import load_dotenv
5
+
6
+ load_dotenv()
7
+
8
+ exchanges_data_s3fs = S3FS(
9
+ bucket_name = 'exchanges-data',
10
+ aws_access_key_id = os.getenv('DO_SPACES_ACCESS_KEY'),
11
+ aws_secret_access_key = os.getenv('DO_SPACES_SECRET_KEY'),
12
+ endpoint_url = os.getenv('DO_SPACES_ENDPOINT'),
13
+ region = os.getenv('DO_SPACES_REGION'),
14
+ )
15
+
16
+ # AWS credentials
17
+ s3_credentials = {
18
+ "s3_access_key_id": os.getenv("DO_SPACES_ACCESS_KEY"),
19
+ "s3_secret_access_key": os.getenv("DO_SPACES_SECRET_KEY"),
20
+ "s3_endpoint_url": os.getenv("DO_SPACES_ENDPOINT_URL"),
21
+ "s3_bucket_name": os.getenv("DO_SPACES_BUCKET_NAME"),
22
+ "s3_region": os.getenv("DO_SPACES_REGION_NAME"),
23
+ }
24
+
25
+ def get_s3_credentials():
26
+ return s3_credentials