strideutils 0.2.10__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {strideutils-0.2.10 → strideutils-0.3.0}/PKG-INFO +1 -1
  2. {strideutils-0.2.10 → strideutils-0.3.0}/pyproject.toml +1 -1
  3. strideutils-0.3.0/strideutils/coingecko.py +147 -0
  4. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/config_examples/strideutils_config.yaml.example +24 -12
  5. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/invariant_helpers.py +1 -1
  6. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/run_safely.py +1 -0
  7. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/stride_alerts.py +4 -1
  8. strideutils-0.3.0/strideutils/stride_config.py +367 -0
  9. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/stride_requests.py +37 -97
  10. strideutils-0.2.10/strideutils/coingecko.py +0 -35
  11. strideutils-0.2.10/strideutils/stride_config.py +0 -301
  12. {strideutils-0.2.10 → strideutils-0.3.0}/README.md +0 -0
  13. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/Makefile +0 -0
  14. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/__init__.py +0 -0
  15. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/config_examples/strideutils_secrets.yaml.example +0 -0
  16. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/cryptography.py +0 -0
  17. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/exec_tx.py +0 -0
  18. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/sheets_connector.py +0 -0
  19. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/slack_connector.py +0 -0
  20. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/stride_upstash.py +0 -0
  21. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils/twilio_connector.py +0 -0
  22. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/__init__.pyi +0 -0
  23. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/coingecko.pyi +0 -0
  24. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/cryptography.pyi +0 -0
  25. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/exec_tx.pyi +0 -0
  26. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/invariant_helpers.pyi +0 -0
  27. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/run_safely.pyi +0 -0
  28. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/sheets_connector.pyi +0 -0
  29. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/slack_connector.pyi +0 -0
  30. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/stride_alerts.pyi +0 -0
  31. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/stride_config.pyi +0 -0
  32. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/stride_requests.pyi +0 -0
  33. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/stride_upstash.pyi +0 -0
  34. {strideutils-0.2.10 → strideutils-0.3.0}/strideutils-stubs/twilio_connector.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strideutils
3
- Version: 0.2.10
3
+ Version: 0.3.0
4
4
  Summary:
5
5
  Author: Your Name
6
6
  Author-email: you@example.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "strideutils"
3
- version = "0.2.10"
3
+ version = "0.3.0"
4
4
  description = ""
5
5
  authors = ["Your Name <you@example.com>"]
6
6
  readme = "README.md"
@@ -0,0 +1,147 @@
1
+ """
2
+ Exposes an easy API to get prices from coingecko
3
+ """
4
+
5
+ from typing import List
6
+
7
+ import pandas as pd
8
+ import requests
9
+
10
+ from strideutils import stride_config, stride_requests
11
+ from strideutils.stride_config import config
12
+
13
+ COINGECKO_ENDPOINT = "https://pro-api.coingecko.com/"
14
+ COINGECKO_PRICE_QUERY = "api/v3/simple/price?ids={ticker_id}&vs_currencies=usd"
15
+
16
+
17
+ def get_coingecko_name(chain_config: stride_config.ChainConfig) -> str:
18
+ """
19
+ Returns the coingecko name for a given chain
20
+ """
21
+ try:
22
+ return chain_config.coingecko_name
23
+ except AttributeError:
24
+ return chain_config.name
25
+
26
+
27
+ def get_token_price(
28
+ ticker: str,
29
+ api_token: str = config.COINGECKO_API_TOKEN,
30
+ cache_response: bool = False,
31
+ ):
32
+ """
33
+ Reads token price from coingecko
34
+ If a redis_client is provided, then store the value.
35
+ """
36
+ # TODO: Consider using the coingecko ID for stTokens instead of the redemption rate
37
+ # Get redemption rate for calculating st token prices
38
+ redemption_rate = float(1)
39
+ if ticker.startswith('st') and ticker[3].isupper():
40
+ redemption_rate = stride_requests.get_redemption_rate(ticker[2:])
41
+ ticker = ticker[2:]
42
+ # get coingecko_name
43
+ try:
44
+ coingecko_name = get_coingecko_name(config.get_chain(ticker=ticker))
45
+ except KeyError:
46
+ coingecko_name = ticker
47
+ # query endopint
48
+ endpoint = COINGECKO_ENDPOINT + COINGECKO_PRICE_QUERY.format(ticker_id=coingecko_name)
49
+ headers = {'x-cg-pro-api-key': api_token}
50
+ response = stride_requests.request(endpoint, headers=headers, cache_response=cache_response)
51
+ price = response[coingecko_name]["usd"] * redemption_rate
52
+
53
+ return price
54
+
55
+
56
+ def get_token_price_history(token: str, num_days=90, use_key=False, memo={}) -> pd.Series:
57
+ """
58
+ returns a Pandas Series with token price data going back num_days
59
+ e.g. get_token_price_history('uatom', 30) returns a Series with 30 days of ATOM price data
60
+ TODO: Figure out why API key is throwing an error when used.
61
+ """
62
+ price_key = (token, num_days)
63
+ if price_key not in memo:
64
+ tstr = get_coingecko_name(config.get_chain(ticker=token))
65
+ rurl = f"https://api.coingecko.com/api/v3/coins/{tstr}/market_chart?vs_currency=usd&days={num_days}"
66
+ rel_headers = {"x-cg-pro-api-key": config.COINGECKO_API_TOKEN}
67
+ if not use_key:
68
+ rel_headers = None
69
+ r = requests.get(
70
+ rurl,
71
+ headers=rel_headers,
72
+ )
73
+ assert r.status_code == 200
74
+ out_df = pd.DataFrame(r.json()["prices"])
75
+ out_df.columns = ["time", "price"]
76
+ out_df["time"] = pd.to_datetime(out_df["time"], unit="ms")
77
+ out_df["price"] = out_df["price"].astype(float)
78
+ out_df.set_index("time", inplace=True)
79
+ memo[token] = out_df
80
+ return memo[token]
81
+
82
+
83
+ def get_token_volume_history(token: str, num_days=90, use_key=False, memo={}) -> pd.Series:
84
+ """
85
+ returns a Pandas Series with token volume data going back num_days
86
+ e.g. get_token_volume_history('uatom', 30) returns a Series with 30 days of ATOM volume data
87
+ TODO: Figure out why API key is throwing an error when used.
88
+ """
89
+ volume_key = (token, num_days)
90
+ if volume_key not in memo:
91
+ tstr = get_coingecko_name(config.get_chain(ticker=token))
92
+ rurl = f"https://api.coingecko.com/api/v3/coins/{tstr}/market_chart?vs_currency=usd&days={num_days}"
93
+ rel_headers = {"x-cg-pro-api-key": config.COINGECKO_API_TOKEN}
94
+ if not use_key:
95
+ rel_headers = None
96
+ r = requests.get(
97
+ rurl,
98
+ headers=rel_headers,
99
+ )
100
+ assert r.status_code == 200
101
+ out_df = pd.DataFrame(r.json()["total_volumes"])
102
+ out_df.columns = ["time", "volume"]
103
+ out_df["time"] = pd.to_datetime(out_df["time"], unit="ms")
104
+ out_df["volume"] = out_df["volume"].astype(float)
105
+ out_df.set_index("time", inplace=True)
106
+ memo[token] = out_df
107
+ return memo[token]
108
+
109
+
110
+ def get_dataframe_of_prices(token_list: List[str], num_days: int = 90) -> pd.DataFrame:
111
+ """
112
+ returns a Pandas DataFrame with token price data going back num_days, for the given tokens
113
+ e.g. get_dataframe_of_prices(["ATOM", "OSMO", "STRD"], 30) returns a DataFrame of 30 days of price data
114
+ """
115
+ # gather the dataframe
116
+ df = {}
117
+ for token in token_list:
118
+ df[token] = get_token_price_history(token, num_days)["price"]
119
+ df = pd.DataFrame(df)
120
+ # resample based on how much data we're gathering
121
+ if num_days > 90:
122
+ df = df.resample("1D").last()
123
+ elif num_days >= 2:
124
+ df = df.resample("1H").last()
125
+ else:
126
+ df = df.resample("5min").last()
127
+ return df
128
+
129
+
130
+ def get_dataframe_of_volumes(token_list: List[str], num_days: int = 90) -> pd.DataFrame:
131
+ """
132
+ returns a Pandas DataFrame with token volume data going back num_days, for the given tokens
133
+ e.g. get_dataframe_of_volumes(["ATOM", "OSMO", "STRD"], 30) returns a DataFrame of 30 days of volume data
134
+ """
135
+ # gather the dataframe
136
+ df = {}
137
+ for token in token_list:
138
+ df[token] = get_token_volume_history(token, num_days)["volume"]
139
+ df = pd.DataFrame(df)
140
+ # resample based on how much data we're gathering
141
+ if num_days > 90:
142
+ df = df.resample("1D").last()
143
+ elif num_days >= 2:
144
+ df = df.resample("1H").last()
145
+ else:
146
+ df = df.resample("5min").last()
147
+ return df
@@ -25,8 +25,8 @@ stride:
25
25
  denom_decimals: 6
26
26
  api_endpoint:
27
27
  rpc_endpoint:
28
- library_api:
29
- library_rpc:
28
+ library_api_endpoint:
29
+ library_rpc_endpoint:
30
30
 
31
31
  # Host Zone Chains
32
32
  host_zones:
@@ -37,8 +37,8 @@ host_zones:
37
37
  denom: uatom
38
38
  ticker: ATOM
39
39
  denom_decimals: 6
40
+ denom_on_stride: ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2
40
41
  inflation_frequency_hours: -1 # Every block
41
- stride_token_hash: ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2
42
42
  api_endpoint:
43
43
  rpc_endpoint:
44
44
 
@@ -48,8 +48,8 @@ host_zones:
48
48
  denom: uosmo
49
49
  ticker: OSMO
50
50
  denom_decimals: 6
51
+ denom_on_stride: ibc/D24B4564BCD51D3D02D9987D92571EAC5915676A9BD6D9B0C1D0254CB8A5EA34
51
52
  inflation_frequency_hours: 24
52
- stride_token_hash: ibc/D24B4564BCD51D3D02D9987D92571EAC5915676A9BD6D9B0C1D0254CB8A5EA34
53
53
  api_endpoint:
54
54
  rpc_endpoint:
55
55
 
@@ -59,8 +59,8 @@ host_zones:
59
59
  denom: aevmos
60
60
  ticker: EVMOS
61
61
  denom_decimals: 18
62
+ denom_on_stride: ibc/4B322204B4F59D770680FE4D7A565DDC3F37BFF035474B717476C66A4F83DD72
62
63
  inflation_frequency_hours: 24
63
- stride_token_hash: ibc/4B322204B4F59D770680FE4D7A565DDC3F37BFF035474B717476C66A4F83DD72
64
64
  api_endpoint:
65
65
  rpc_endpoint:
66
66
 
@@ -71,8 +71,8 @@ host_zones:
71
71
  denom: inj
72
72
  ticker: INJ
73
73
  denom_decimals: 18
74
+ denom_on_stride: ibc/A7454562FF29FE068F42F9DE4805ABEF54F599D1720B345D6518D9B5C64EA6D2
74
75
  inflation_frequency_hours: -1 # Every block
75
- stride_token_hash: ibc/A7454562FF29FE068F42F9DE4805ABEF54F599D1720B345D6518D9B5C64EA6D2
76
76
  api_endpoint:
77
77
  rpc_endpoint:
78
78
 
@@ -83,8 +83,8 @@ host_zones:
83
83
  coingecko_name: juno-network
84
84
  ticker: JUNO
85
85
  denom_decimals: 6
86
+ denom_on_stride: ibc/DA356E369C3E5CF6A9F1DCD99CE8ED55FBD595E676A5CF033CE784C060492D5A
86
87
  inflation_frequency_hours: -1 # Every block
87
- stride_token_hash: ibc/DA356E369C3E5CF6A9F1DCD99CE8ED55FBD595E676A5CF033CE784C060492D5A
88
88
  api_endpoint:
89
89
  rpc_endpoint:
90
90
 
@@ -94,8 +94,8 @@ host_zones:
94
94
  denom: ustars
95
95
  ticker: STARS
96
96
  denom_decimals: 6
97
+ denom_on_stride: ibc/7EAE5BEF3A26B64AFBD89828AFDDB1DC7024A0276D22745201632C40E6E634D0
97
98
  inflation_frequency_hours: -1 # Every block
98
- stride_token_hash: ibc/7EAE5BEF3A26B64AFBD89828AFDDB1DC7024A0276D22745201632C40E6E634D0
99
99
  api_endpoint:
100
100
  rpc_endpoint:
101
101
 
@@ -106,8 +106,8 @@ host_zones:
106
106
  denom: uluna
107
107
  ticker: LUNA
108
108
  denom_decimals: 6
109
+ denom_on_stride: ibc/E61BCB1126F42A2ED73B4CEA2221C9635BC2102F0417543C38071779F991942E
109
110
  inflation_frequency_hours: -1 # Every block
110
- stride_token_hash: ibc/E61BCB1126F42A2ED73B4CEA2221C9635BC2102F0417543C38071779F991942E
111
111
  api_endpoint:
112
112
  rpc_endpoint:
113
113
 
@@ -117,8 +117,8 @@ host_zones:
117
117
  denom: uumee
118
118
  ticker: UMEE
119
119
  denom_decimals: 6
120
+ denom_on_stride: ibc/1A2271226209D309902AFF4F21BD21237CB514DD24EA2EE0423BF74C6135D8B8
120
121
  inflation_frequency_hours: -1 # Every block
121
- stride_token_hash: ibc/1A2271226209D309902AFF4F21BD21237CB514DD24EA2EE0423BF74C6135D8B8
122
122
  api_endpoint:
123
123
  rpc_endpoint:
124
124
 
@@ -128,8 +128,8 @@ host_zones:
128
128
  denom: ucmdx
129
129
  ticker: CMDX
130
130
  denom_decimals: 6
131
+ denom_on_stride: ibc/EB66980014602E6BD50A1CB9FFB8FA694DC3EC10A48D2C1C649D732954F88D4A
131
132
  inflation_frequency_hours: -1 # Every block
132
- stride_token_hash: ibc/EB66980014602E6BD50A1CB9FFB8FA694DC3EC10A48D2C1C649D732954F88D4A
133
133
  api_endpoint:
134
134
  rpc_endpoint:
135
135
 
@@ -139,11 +139,23 @@ host_zones:
139
139
  denom: usomm
140
140
  ticker: SOMM
141
141
  denom_decimals: 6
142
+ denom_on_stride: ibc/B86EFF6D227E3E33D7E3B5E65D0C1BB5BD79CCB56D35A9D824F0DD5D52CA43BA
142
143
  inflation_frequency_hours: -1 # Every block
143
- stride_token_hash: ibc/B86EFF6D227E3E33D7E3B5E65D0C1BB5BD79CCB56D35A9D824F0DD5D52CA43BA
144
144
  api_endpoint:
145
145
  rpc_endpoint:
146
146
 
147
+ celestia:
148
+ name: celestia
149
+ id: celestia
150
+ coingecko_name: celestia
151
+ denom: utia
152
+ ticker: TIA
153
+ denom_on_stride: ibc/BF3B4F53F3694B66E13C23107C84B6485BD2B96296BB7EC680EA77BBA75B4801
154
+ inflation_frequency_hours: -1 # Every block
155
+ api_endpoint: https://celestia-strd-api.polkachu.com
156
+ rpc_endpoint: https://celestia-strd-rpc.polkachu.com
157
+ ica_enabled: false
158
+
147
159
  # Other endpoints
148
160
  app_chains:
149
161
  neutron:
@@ -16,7 +16,7 @@ def check_slack_on_mainnet(str_output: bool = True, verbose: bool = False) -> Un
16
16
  output = ""
17
17
  for zone in config.host_zones:
18
18
  host_zone_id = zone.id
19
- host_zone = stride_requests.get_host_zone_json(host_zone_id)
19
+ host_zone = stride_requests.get_host_zone(host_zone_id)
20
20
 
21
21
  rr = host_zone['redemption_rate']
22
22
  min_rr, max_rr = host_zone['min_redemption_rate'], host_zone['max_redemption_rate']
@@ -32,6 +32,7 @@ def try_and_log_with_status(
32
32
  func()
33
33
  msg = [f':white_check_mark: {func_name}']
34
34
  except Exception:
35
+ print(traceback.format_exc())
35
36
  msg = [f':x: {func_name} ']
36
37
  tracebacks.append(f"{func_name} \n\n" + traceback.format_exc())
37
38
  msgs += msg
@@ -43,6 +43,7 @@ def notify(
43
43
  tag: Optional[Union[str, Iterable[str]]] = None,
44
44
  call: Optional[Union[str, Iterable[str]]] = None,
45
45
  beta_alert: bool = False,
46
+ debug_readme: str = config.alerts_playbook,
46
47
  debug_readme_section: str = "",
47
48
  ) -> None:
48
49
  """
@@ -59,7 +60,7 @@ def notify(
59
60
  msgs: List = cast(List, [msgs] if type(msgs) is str else msgs)
60
61
  top_level_message = str(msgs[0])
61
62
 
62
- debug_msg = f"Read more: {config.alerts_playbook}{debug_readme_section}"
63
+ debug_msg = f"Read more: {debug_readme}{debug_readme_section}"
63
64
 
64
65
  channel = "#alerts-info"
65
66
  if urgency == AlertType.DEBUG:
@@ -88,6 +89,7 @@ def raise_alert(
88
89
  tag: Optional[Union[str, Iterable[str]]] = None,
89
90
  call: Optional[Union[str, Iterable[str]]] = None,
90
91
  beta_alert: bool = False,
92
+ debug_readme: str = config.alerts_playbook,
91
93
  debug_readme_section: str = "",
92
94
  ) -> Callable:
93
95
  """
@@ -122,6 +124,7 @@ def raise_alert(
122
124
  tag=tag,
123
125
  call=call,
124
126
  beta_alert=beta_alert,
127
+ debug_readme=debug_readme,
125
128
  debug_readme_section=debug_readme_section,
126
129
  )
127
130