iwa 0.0.1a6__py3-none-any.whl → 0.0.2__py3-none-any.whl
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.
- iwa/core/chain/models.py +27 -0
- iwa/core/pricing.py +21 -14
- {iwa-0.0.1a6.dist-info → iwa-0.0.2.dist-info}/METADATA +1 -1
- {iwa-0.0.1a6.dist-info → iwa-0.0.2.dist-info}/RECORD +8 -8
- {iwa-0.0.1a6.dist-info → iwa-0.0.2.dist-info}/WHEEL +0 -0
- {iwa-0.0.1a6.dist-info → iwa-0.0.2.dist-info}/entry_points.txt +0 -0
- {iwa-0.0.1a6.dist-info → iwa-0.0.2.dist-info}/licenses/LICENSE +0 -0
- {iwa-0.0.1a6.dist-info → iwa-0.0.2.dist-info}/top_level.txt +0 -0
iwa/core/chain/models.py
CHANGED
|
@@ -78,6 +78,15 @@ class Gnosis(SupportedChain):
|
|
|
78
78
|
if not self.rpcs and secrets.gnosis_rpc:
|
|
79
79
|
self.rpcs = secrets.gnosis_rpc.get_secret_value().split(",")
|
|
80
80
|
|
|
81
|
+
# Defensive: ensure no comma-separated strings in list
|
|
82
|
+
new_rpcs = []
|
|
83
|
+
for rpc in self.rpcs:
|
|
84
|
+
if "," in rpc:
|
|
85
|
+
new_rpcs.extend([r.strip() for r in rpc.split(",") if r.strip()])
|
|
86
|
+
else:
|
|
87
|
+
new_rpcs.append(rpc)
|
|
88
|
+
self.rpcs = new_rpcs
|
|
89
|
+
|
|
81
90
|
|
|
82
91
|
@singleton
|
|
83
92
|
class Ethereum(SupportedChain):
|
|
@@ -98,6 +107,15 @@ class Ethereum(SupportedChain):
|
|
|
98
107
|
if not self.rpcs and secrets.ethereum_rpc:
|
|
99
108
|
self.rpcs = secrets.ethereum_rpc.get_secret_value().split(",")
|
|
100
109
|
|
|
110
|
+
# Defensive: ensure no comma-separated strings in list
|
|
111
|
+
new_rpcs = []
|
|
112
|
+
for rpc in self.rpcs:
|
|
113
|
+
if "," in rpc:
|
|
114
|
+
new_rpcs.extend([r.strip() for r in rpc.split(",") if r.strip()])
|
|
115
|
+
else:
|
|
116
|
+
new_rpcs.append(rpc)
|
|
117
|
+
self.rpcs = new_rpcs
|
|
118
|
+
|
|
101
119
|
|
|
102
120
|
@singleton
|
|
103
121
|
class Base(SupportedChain):
|
|
@@ -118,6 +136,15 @@ class Base(SupportedChain):
|
|
|
118
136
|
if not self.rpcs and secrets.base_rpc:
|
|
119
137
|
self.rpcs = secrets.base_rpc.get_secret_value().split(",")
|
|
120
138
|
|
|
139
|
+
# Defensive: ensure no comma-separated strings in list
|
|
140
|
+
new_rpcs = []
|
|
141
|
+
for rpc in self.rpcs:
|
|
142
|
+
if "," in rpc:
|
|
143
|
+
new_rpcs.extend([r.strip() for r in rpc.split(",") if r.strip()])
|
|
144
|
+
else:
|
|
145
|
+
new_rpcs.append(rpc)
|
|
146
|
+
self.rpcs = new_rpcs
|
|
147
|
+
|
|
121
148
|
|
|
122
149
|
@singleton
|
|
123
150
|
class SupportedChains:
|
iwa/core/pricing.py
CHANGED
|
@@ -45,7 +45,13 @@ class PriceService:
|
|
|
45
45
|
if datetime.now() - entry["timestamp"] < self.cache_ttl:
|
|
46
46
|
return entry["price"]
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
price = self._fetch_price_from_api(token_id, vs_currency)
|
|
49
|
+
if price is not None:
|
|
50
|
+
self.cache[cache_key] = {"price": price, "timestamp": datetime.now()}
|
|
51
|
+
return price
|
|
52
|
+
|
|
53
|
+
def _fetch_price_from_api(self, token_id: str, vs_currency: str) -> Optional[float]:
|
|
54
|
+
"""Fetch price from API with retries and key fallback."""
|
|
49
55
|
max_retries = 2
|
|
50
56
|
for attempt in range(max_retries + 1):
|
|
51
57
|
try:
|
|
@@ -57,9 +63,16 @@ class PriceService:
|
|
|
57
63
|
|
|
58
64
|
response = requests.get(url, params=params, headers=headers, timeout=10)
|
|
59
65
|
|
|
66
|
+
if response.status_code == 401 and self.api_key:
|
|
67
|
+
logger.warning("CoinGecko API key invalid (401). Retrying without key...")
|
|
68
|
+
self.api_key = None
|
|
69
|
+
headers.pop("x-cg-demo-api-key", None)
|
|
70
|
+
response = requests.get(url, params=params, headers=headers, timeout=10)
|
|
71
|
+
|
|
60
72
|
if response.status_code == 429:
|
|
61
73
|
logger.warning(
|
|
62
|
-
f"CoinGecko rate limit reached (429) for {token_id}.
|
|
74
|
+
f"CoinGecko rate limit reached (429) for {token_id}. "
|
|
75
|
+
f"Attempt {attempt + 1}/{max_retries + 1}"
|
|
63
76
|
)
|
|
64
77
|
if attempt < max_retries:
|
|
65
78
|
time.sleep(2 * (attempt + 1))
|
|
@@ -67,25 +80,19 @@ class PriceService:
|
|
|
67
80
|
return None
|
|
68
81
|
|
|
69
82
|
response.raise_for_status()
|
|
70
|
-
|
|
71
83
|
data = response.json()
|
|
84
|
+
|
|
72
85
|
if token_id in data and vs_currency in data[token_id]:
|
|
73
|
-
|
|
86
|
+
return float(data[token_id][vs_currency])
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
logger.warning(
|
|
80
|
-
f"Price for {token_id} in {vs_currency} not found in response: {data}"
|
|
81
|
-
)
|
|
82
|
-
# Don't cache None, might be a temporary hiccup
|
|
83
|
-
return None
|
|
88
|
+
logger.warning(
|
|
89
|
+
f"Price for {token_id} in {vs_currency} not found in response: {data}"
|
|
90
|
+
)
|
|
91
|
+
return None
|
|
84
92
|
|
|
85
93
|
except Exception as e:
|
|
86
94
|
logger.error(f"Failed to fetch price for {token_id} (Attempt {attempt + 1}): {e}")
|
|
87
95
|
if attempt < max_retries:
|
|
88
96
|
time.sleep(1)
|
|
89
97
|
continue
|
|
90
|
-
return None
|
|
91
98
|
return None
|
|
@@ -10,7 +10,7 @@ iwa/core/mnemonic.py,sha256=LiG1VmpydQoHQ0pHUJ1OIlrWJry47VSMnOqPM_Yk-O8,12930
|
|
|
10
10
|
iwa/core/models.py,sha256=kBQ0cBe6uFmL2QfW7mjKiMFeZxhT-FRN-RyK3Ko0vE8,12849
|
|
11
11
|
iwa/core/monitor.py,sha256=OmhKVMkfhvtxig3wDUL6iGwBIClTx0YUqMncCao4SqI,7953
|
|
12
12
|
iwa/core/plugins.py,sha256=FLvOG4S397fKi0aTH1fWBEtexn4yvGv_QzGWqFrhSKE,1102
|
|
13
|
-
iwa/core/pricing.py,sha256=
|
|
13
|
+
iwa/core/pricing.py,sha256=5D2WAaDRuY1iOmj9fwgh_etnjjU6wdJmIgwoy8DbA2E,3614
|
|
14
14
|
iwa/core/secrets.py,sha256=U7DZKrwKuSOFV00Ij3ISrrO1cWn_t1GBW_0PyAqjcD4,2588
|
|
15
15
|
iwa/core/tables.py,sha256=y7Cg67PAGHYVMVyAjbo_CQ9t2iz7UXE-OTuUHRyFRTo,2021
|
|
16
16
|
iwa/core/test.py,sha256=gey0dql5eajo1itOhgkSrgfyGWue2eSfpr0xzX3vc38,643
|
|
@@ -22,7 +22,7 @@ iwa/core/chain/__init__.py,sha256=XJMmn0ed-_aVkY2iEMKpuTxPgIKBd41dexSVmEZTa-o,16
|
|
|
22
22
|
iwa/core/chain/errors.py,sha256=9SEbhxZ-qASPkzt-DoI51qq0GRJVqRgqgL720gO7a64,1275
|
|
23
23
|
iwa/core/chain/interface.py,sha256=3tyMvnOZCTTvM0Y3YgxuN6zlXyJ1EIZUoyVosGtsUI8,20228
|
|
24
24
|
iwa/core/chain/manager.py,sha256=cFEzh6pK5OyVhjhpeMAqhc9RnRDQR1DjIGiGKp-FXBI,1159
|
|
25
|
-
iwa/core/chain/models.py,sha256=
|
|
25
|
+
iwa/core/chain/models.py,sha256=h3-vygtsAHaY1-JSqTujr0JYs7OpzBfYTRsh-vOoEV4,4962
|
|
26
26
|
iwa/core/chain/rate_limiter.py,sha256=gU7TmWdH9D_wbXKT1X7mIgoIUCWVuebgvRhxiyLGAmI,6613
|
|
27
27
|
iwa/core/contracts/__init__.py,sha256=P5GFY_pnuI02teqVY2U0t98bn1_SSPAbcAzRMpCdTi4,34
|
|
28
28
|
iwa/core/contracts/contract.py,sha256=ERWViqZNqhsmf-tKVxn5XfQTJ8S_1MXVk0Tjq8davd0,11228
|
|
@@ -149,7 +149,7 @@ iwa/web/tests/test_web_endpoints.py,sha256=vZUGmrudkQHA8gBmSyO8i2SgZpsr1He-YRm2J
|
|
|
149
149
|
iwa/web/tests/test_web_olas.py,sha256=oN__4nUT_H_j-_ALEqSp-si5xMbY0Bcxhvhuhxsg4Q8,16292
|
|
150
150
|
iwa/web/tests/test_web_swap.py,sha256=7A4gBJFL01kIXPtW1E1J17SCsVc_0DmUn-R8kKrnnVA,2974
|
|
151
151
|
iwa/web/tests/test_web_swap_coverage.py,sha256=zGNrzlhZ_vWDCvWmLcoUwFgqxnrp_ACbo49AtWBS_Kw,5584
|
|
152
|
-
iwa-0.0.
|
|
152
|
+
iwa-0.0.2.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
|
|
153
153
|
tests/legacy_cow.py,sha256=oOkZvIxL70ReEoD9oHQbOD5GpjIr6AGNHcOCgfPlerU,8389
|
|
154
154
|
tests/legacy_safe.py,sha256=AssM2g13E74dNGODu_H0Q0y412lgqsrYnEzI97nm_Ts,2972
|
|
155
155
|
tests/legacy_transaction_retry_logic.py,sha256=D9RqZ7DBu61Xr2djBAodU2p9UE939LL-DnQXswX5iQk,1497
|
|
@@ -199,8 +199,8 @@ tests/test_ui_coverage.py,sha256=N-7uhPlKOXCKyS32VjwG3JQRnAS1PoAJxR-InaOZtCQ,242
|
|
|
199
199
|
tests/test_utils.py,sha256=vkP49rYNI8BRzLpWR3WnKdDr8upeZjZcs7Rx0pjbQMo,1292
|
|
200
200
|
tests/test_workers.py,sha256=MInwdkFY5LdmFB3o1odIaSD7AQZb3263hNafO1De5PE,2793
|
|
201
201
|
tools/verify_drain.py,sha256=1On4GmXWETA-CHfFjd7qAqIQuSgKIaEomKKXM7S8wfk,6881
|
|
202
|
-
iwa-0.0.
|
|
203
|
-
iwa-0.0.
|
|
204
|
-
iwa-0.0.
|
|
205
|
-
iwa-0.0.
|
|
206
|
-
iwa-0.0.
|
|
202
|
+
iwa-0.0.2.dist-info/METADATA,sha256=LI8zcRvzlRmevpeYLa1O5KdZbF6GX5L-Xp7QLUcgSI8,7294
|
|
203
|
+
iwa-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
204
|
+
iwa-0.0.2.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
|
|
205
|
+
iwa-0.0.2.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
|
|
206
|
+
iwa-0.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|