defillama-sdk 0.1.0__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.
- defillama_api/__init__.py +71 -0
- defillama_api/client.py +157 -0
- defillama_api/constants/__init__.py +11 -0
- defillama_api/constants/dimensions.py +69 -0
- defillama_api/errors.py +41 -0
- defillama_api/modules/__init__.py +29 -0
- defillama_api/modules/account.py +29 -0
- defillama_api/modules/bridges.py +81 -0
- defillama_api/modules/dat.py +31 -0
- defillama_api/modules/ecosystem.py +54 -0
- defillama_api/modules/emissions.py +32 -0
- defillama_api/modules/etfs.py +58 -0
- defillama_api/modules/fees.py +242 -0
- defillama_api/modules/prices.py +122 -0
- defillama_api/modules/stablecoins.py +76 -0
- defillama_api/modules/tvl.py +84 -0
- defillama_api/modules/volumes.py +116 -0
- defillama_api/modules/yields.py +85 -0
- defillama_api/py.typed +0 -0
- defillama_api/types/__init__.py +14 -0
- defillama_api/types/account.py +10 -0
- defillama_api/types/bridges.py +147 -0
- defillama_api/types/dat.py +144 -0
- defillama_api/types/ecosystem.py +175 -0
- defillama_api/types/emissions.py +154 -0
- defillama_api/types/etfs.py +37 -0
- defillama_api/types/fees.py +217 -0
- defillama_api/types/prices.py +99 -0
- defillama_api/types/stablecoins.py +159 -0
- defillama_api/types/tvl.py +189 -0
- defillama_api/types/volumes.py +147 -0
- defillama_api/types/yields.py +170 -0
- defillama_sdk-0.1.0.dist-info/METADATA +688 -0
- defillama_sdk-0.1.0.dist-info/RECORD +36 -0
- defillama_sdk-0.1.0.dist-info/WHEEL +5 -0
- defillama_sdk-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"""Fees module implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from urllib.parse import quote
|
|
5
|
+
|
|
6
|
+
from ..client import BaseClient
|
|
7
|
+
from ..types.fees import (
|
|
8
|
+
ChartBreakdownDataPoint,
|
|
9
|
+
ChartDataPoint,
|
|
10
|
+
FeesChartOptions,
|
|
11
|
+
FeesMetricsByProtocolResponse,
|
|
12
|
+
FeesMetricsResponse,
|
|
13
|
+
FeesOverviewOptions,
|
|
14
|
+
FeesOverviewResponse,
|
|
15
|
+
FeesSummaryOptions,
|
|
16
|
+
FeesSummaryResponse,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _data_type_value(value: Optional[object]) -> Optional[str]:
|
|
21
|
+
if value is None:
|
|
22
|
+
return None
|
|
23
|
+
if hasattr(value, "value"):
|
|
24
|
+
return str(getattr(value, "value"))
|
|
25
|
+
return str(value)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class FeesModule:
|
|
29
|
+
"""Access fees and revenue data from DefiLlama."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, client: BaseClient) -> None:
|
|
32
|
+
self._client = client
|
|
33
|
+
|
|
34
|
+
def getOverview(self, options: Optional[FeesOverviewOptions] = None) -> FeesOverviewResponse:
|
|
35
|
+
"""Get fees overview across all protocols."""
|
|
36
|
+
|
|
37
|
+
params = {}
|
|
38
|
+
if options:
|
|
39
|
+
if options.get("excludeTotalDataChart") is not None:
|
|
40
|
+
params["excludeTotalDataChart"] = options.get("excludeTotalDataChart")
|
|
41
|
+
if options.get("excludeTotalDataChartBreakdown") is not None:
|
|
42
|
+
params["excludeTotalDataChartBreakdown"] = options.get(
|
|
43
|
+
"excludeTotalDataChartBreakdown"
|
|
44
|
+
)
|
|
45
|
+
data_type = _data_type_value(options.get("dataType"))
|
|
46
|
+
if data_type:
|
|
47
|
+
params["dataType"] = data_type
|
|
48
|
+
return self._client.get(
|
|
49
|
+
"/overview/fees",
|
|
50
|
+
params=params or None,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def getOverviewByChain(
|
|
54
|
+
self, chain: str, options: Optional[FeesOverviewOptions] = None
|
|
55
|
+
) -> FeesOverviewResponse:
|
|
56
|
+
"""Get fees overview for a chain."""
|
|
57
|
+
|
|
58
|
+
params = {}
|
|
59
|
+
if options:
|
|
60
|
+
if options.get("excludeTotalDataChart") is not None:
|
|
61
|
+
params["excludeTotalDataChart"] = options.get("excludeTotalDataChart")
|
|
62
|
+
if options.get("excludeTotalDataChartBreakdown") is not None:
|
|
63
|
+
params["excludeTotalDataChartBreakdown"] = options.get(
|
|
64
|
+
"excludeTotalDataChartBreakdown"
|
|
65
|
+
)
|
|
66
|
+
data_type = _data_type_value(options.get("dataType"))
|
|
67
|
+
if data_type:
|
|
68
|
+
params["dataType"] = data_type
|
|
69
|
+
return self._client.get(
|
|
70
|
+
f"/overview/fees/{quote(chain)}",
|
|
71
|
+
params=params or None,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def getSummary(
|
|
75
|
+
self, protocol: str, options: Optional[FeesSummaryOptions] = None
|
|
76
|
+
) -> FeesSummaryResponse:
|
|
77
|
+
"""Get fees summary for a protocol."""
|
|
78
|
+
|
|
79
|
+
params = {}
|
|
80
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
81
|
+
if data_type:
|
|
82
|
+
params["dataType"] = data_type
|
|
83
|
+
return self._client.get(
|
|
84
|
+
f"/summary/fees/{quote(protocol)}",
|
|
85
|
+
params=params or None,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def getChart(self, options: Optional[FeesChartOptions] = None) -> list[ChartDataPoint]:
|
|
89
|
+
"""Get historical fees chart."""
|
|
90
|
+
|
|
91
|
+
params = {}
|
|
92
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
93
|
+
if data_type:
|
|
94
|
+
params["dataType"] = data_type
|
|
95
|
+
return self._client.get(
|
|
96
|
+
"/chart/fees",
|
|
97
|
+
base="v2",
|
|
98
|
+
requires_auth=True,
|
|
99
|
+
params=params or None,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
def getChartByChain(
|
|
103
|
+
self, chain: str, options: Optional[FeesChartOptions] = None
|
|
104
|
+
) -> list[ChartDataPoint]:
|
|
105
|
+
"""Get historical fees chart for a chain."""
|
|
106
|
+
|
|
107
|
+
params = {}
|
|
108
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
109
|
+
if data_type:
|
|
110
|
+
params["dataType"] = data_type
|
|
111
|
+
return self._client.get(
|
|
112
|
+
f"/chart/fees/chain/{quote(chain)}",
|
|
113
|
+
base="v2",
|
|
114
|
+
requires_auth=True,
|
|
115
|
+
params=params or None,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def getChartByProtocol(
|
|
119
|
+
self, protocol: str, options: Optional[FeesChartOptions] = None
|
|
120
|
+
) -> list[ChartDataPoint]:
|
|
121
|
+
"""Get historical fees chart for a protocol."""
|
|
122
|
+
|
|
123
|
+
params = {}
|
|
124
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
125
|
+
if data_type:
|
|
126
|
+
params["dataType"] = data_type
|
|
127
|
+
return self._client.get(
|
|
128
|
+
f"/chart/fees/protocol/{quote(protocol)}",
|
|
129
|
+
base="v2",
|
|
130
|
+
requires_auth=True,
|
|
131
|
+
params=params or None,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def getChartByProtocolChainBreakdown(
|
|
135
|
+
self, protocol: str, options: Optional[FeesChartOptions] = None
|
|
136
|
+
) -> list[ChartBreakdownDataPoint]:
|
|
137
|
+
"""Get fees chart with protocol chain breakdown."""
|
|
138
|
+
|
|
139
|
+
params = {}
|
|
140
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
141
|
+
if data_type:
|
|
142
|
+
params["dataType"] = data_type
|
|
143
|
+
return self._client.get(
|
|
144
|
+
f"/chart/fees/protocol/{quote(protocol)}/chain-breakdown",
|
|
145
|
+
base="v2",
|
|
146
|
+
requires_auth=True,
|
|
147
|
+
params=params or None,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def getChartByProtocolVersionBreakdown(
|
|
151
|
+
self, protocol: str, options: Optional[FeesChartOptions] = None
|
|
152
|
+
) -> list[ChartBreakdownDataPoint]:
|
|
153
|
+
"""Get fees chart with protocol version breakdown."""
|
|
154
|
+
|
|
155
|
+
params = {}
|
|
156
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
157
|
+
if data_type:
|
|
158
|
+
params["dataType"] = data_type
|
|
159
|
+
return self._client.get(
|
|
160
|
+
f"/chart/fees/protocol/{quote(protocol)}/version-breakdown",
|
|
161
|
+
base="v2",
|
|
162
|
+
requires_auth=True,
|
|
163
|
+
params=params or None,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
def getChartByChainProtocolBreakdown(
|
|
167
|
+
self, chain: str, options: Optional[FeesChartOptions] = None
|
|
168
|
+
) -> list[ChartBreakdownDataPoint]:
|
|
169
|
+
"""Get fees chart with chain protocol breakdown."""
|
|
170
|
+
|
|
171
|
+
params = {}
|
|
172
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
173
|
+
if data_type:
|
|
174
|
+
params["dataType"] = data_type
|
|
175
|
+
return self._client.get(
|
|
176
|
+
f"/chart/fees/chain/{quote(chain)}/protocol-breakdown",
|
|
177
|
+
base="v2",
|
|
178
|
+
requires_auth=True,
|
|
179
|
+
params=params or None,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
def getChartChainBreakdown(
|
|
183
|
+
self, options: Optional[FeesChartOptions] = None
|
|
184
|
+
) -> list[ChartBreakdownDataPoint]:
|
|
185
|
+
"""Get fees chart with chain breakdown across protocols."""
|
|
186
|
+
|
|
187
|
+
params = {}
|
|
188
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
189
|
+
if data_type:
|
|
190
|
+
params["dataType"] = data_type
|
|
191
|
+
return self._client.get(
|
|
192
|
+
"/chart/fees/chain-breakdown",
|
|
193
|
+
base="v2",
|
|
194
|
+
requires_auth=True,
|
|
195
|
+
params=params or None,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
def getMetrics(self, options: Optional[FeesChartOptions] = None) -> FeesMetricsResponse:
|
|
199
|
+
"""Get fee metrics across protocols."""
|
|
200
|
+
|
|
201
|
+
params = {}
|
|
202
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
203
|
+
if data_type:
|
|
204
|
+
params["dataType"] = data_type
|
|
205
|
+
return self._client.get(
|
|
206
|
+
"/metrics/fees",
|
|
207
|
+
base="v2",
|
|
208
|
+
requires_auth=True,
|
|
209
|
+
params=params or None,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def getMetricsByChain(
|
|
213
|
+
self, chain: str, options: Optional[FeesChartOptions] = None
|
|
214
|
+
) -> FeesMetricsResponse:
|
|
215
|
+
"""Get fee metrics for a chain."""
|
|
216
|
+
|
|
217
|
+
params = {}
|
|
218
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
219
|
+
if data_type:
|
|
220
|
+
params["dataType"] = data_type
|
|
221
|
+
return self._client.get(
|
|
222
|
+
f"/metrics/fees/chain/{quote(chain)}",
|
|
223
|
+
base="v2",
|
|
224
|
+
requires_auth=True,
|
|
225
|
+
params=params or None,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
def getMetricsByProtocol(
|
|
229
|
+
self, protocol: str, options: Optional[FeesChartOptions] = None
|
|
230
|
+
) -> FeesMetricsByProtocolResponse:
|
|
231
|
+
"""Get fee metrics for a protocol."""
|
|
232
|
+
|
|
233
|
+
params = {}
|
|
234
|
+
data_type = _data_type_value(options.get("dataType") if options else None)
|
|
235
|
+
if data_type:
|
|
236
|
+
params["dataType"] = data_type
|
|
237
|
+
return self._client.get(
|
|
238
|
+
f"/metrics/fees/protocol/{quote(protocol)}",
|
|
239
|
+
base="v2",
|
|
240
|
+
requires_auth=True,
|
|
241
|
+
params=params or None,
|
|
242
|
+
)
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Prices module implementation."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Dict, List, Optional
|
|
5
|
+
from urllib.parse import quote
|
|
6
|
+
|
|
7
|
+
from ..client import BaseClient
|
|
8
|
+
from ..types.prices import (
|
|
9
|
+
BatchHistoricalResponse,
|
|
10
|
+
BlockInfo,
|
|
11
|
+
ChartOptions,
|
|
12
|
+
ChartResponse,
|
|
13
|
+
CoinPricesResponse,
|
|
14
|
+
FirstPriceResponse,
|
|
15
|
+
PercentageOptions,
|
|
16
|
+
PercentageResponse,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class PricesModule:
|
|
21
|
+
"""Access token price data from DefiLlama."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, client: BaseClient) -> None:
|
|
24
|
+
self._client = client
|
|
25
|
+
|
|
26
|
+
def getCurrentPrices(
|
|
27
|
+
self, coins: List[str], searchWidth: Optional[str] = None
|
|
28
|
+
) -> CoinPricesResponse:
|
|
29
|
+
"""Get current prices for multiple tokens."""
|
|
30
|
+
|
|
31
|
+
coins_param = ",".join(coins)
|
|
32
|
+
params = {"searchWidth": searchWidth} if searchWidth else None
|
|
33
|
+
return self._client.get(
|
|
34
|
+
f"/prices/current/{coins_param}",
|
|
35
|
+
base="coins",
|
|
36
|
+
params=params,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def getHistoricalPrices(
|
|
40
|
+
self, timestamp: int, coins: List[str], searchWidth: Optional[str] = None
|
|
41
|
+
) -> CoinPricesResponse:
|
|
42
|
+
"""Get historical prices at a specific timestamp."""
|
|
43
|
+
|
|
44
|
+
coins_param = ",".join(coins)
|
|
45
|
+
params = {"searchWidth": searchWidth} if searchWidth else None
|
|
46
|
+
return self._client.get(
|
|
47
|
+
f"/prices/historical/{timestamp}/{coins_param}",
|
|
48
|
+
base="coins",
|
|
49
|
+
params=params,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def getBatchHistoricalPrices(
|
|
53
|
+
self, coins: Dict[str, List[int]], searchWidth: Optional[str] = None
|
|
54
|
+
) -> BatchHistoricalResponse:
|
|
55
|
+
"""Get multiple historical price points in one request."""
|
|
56
|
+
|
|
57
|
+
params = {
|
|
58
|
+
"coins": json.dumps(coins),
|
|
59
|
+
"searchWidth": searchWidth,
|
|
60
|
+
}
|
|
61
|
+
return self._client.get(
|
|
62
|
+
"/batchHistorical",
|
|
63
|
+
base="coins",
|
|
64
|
+
params=params,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def getChart(
|
|
68
|
+
self, coins: List[str], options: Optional[ChartOptions] = None
|
|
69
|
+
) -> ChartResponse:
|
|
70
|
+
"""Get price chart data at regular intervals."""
|
|
71
|
+
|
|
72
|
+
coins_param = ",".join(coins)
|
|
73
|
+
params = None
|
|
74
|
+
if options:
|
|
75
|
+
params = {
|
|
76
|
+
"start": options.get("start"),
|
|
77
|
+
"end": options.get("end"),
|
|
78
|
+
"span": options.get("span"),
|
|
79
|
+
"period": options.get("period"),
|
|
80
|
+
"searchWidth": options.get("searchWidth"),
|
|
81
|
+
}
|
|
82
|
+
return self._client.get(
|
|
83
|
+
f"/chart/{coins_param}",
|
|
84
|
+
base="coins",
|
|
85
|
+
params=params,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def getPercentageChange(
|
|
89
|
+
self, coins: List[str], options: Optional[PercentageOptions] = None
|
|
90
|
+
) -> PercentageResponse:
|
|
91
|
+
"""Get percentage price change over a period."""
|
|
92
|
+
|
|
93
|
+
coins_param = ",".join(coins)
|
|
94
|
+
params = None
|
|
95
|
+
if options:
|
|
96
|
+
params = {
|
|
97
|
+
"timestamp": options.get("timestamp"),
|
|
98
|
+
"lookForward": options.get("lookForward"),
|
|
99
|
+
"period": options.get("period"),
|
|
100
|
+
}
|
|
101
|
+
return self._client.get(
|
|
102
|
+
f"/percentage/{coins_param}",
|
|
103
|
+
base="coins",
|
|
104
|
+
params=params,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def getFirstPrices(self, coins: List[str]) -> FirstPriceResponse:
|
|
108
|
+
"""Get the earliest recorded price for tokens."""
|
|
109
|
+
|
|
110
|
+
coins_param = ",".join(coins)
|
|
111
|
+
return self._client.get(
|
|
112
|
+
f"/prices/first/{coins_param}",
|
|
113
|
+
base="coins",
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def getBlockAtTimestamp(self, chain: str, timestamp: int) -> BlockInfo:
|
|
117
|
+
"""Get the closest block to a given timestamp."""
|
|
118
|
+
|
|
119
|
+
return self._client.get(
|
|
120
|
+
f"/block/{quote(chain)}/{timestamp}",
|
|
121
|
+
base="coins",
|
|
122
|
+
)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Stablecoins module implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
from urllib.parse import quote
|
|
5
|
+
|
|
6
|
+
from ..client import BaseClient
|
|
7
|
+
from ..types.stablecoins import (
|
|
8
|
+
StablecoinChainDataPoint,
|
|
9
|
+
StablecoinChainMcap,
|
|
10
|
+
StablecoinChartDataPoint,
|
|
11
|
+
StablecoinDetails,
|
|
12
|
+
StablecoinDominanceDataPoint,
|
|
13
|
+
StablecoinPricePoint,
|
|
14
|
+
StablecoinsResponse,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class StablecoinsModule:
|
|
19
|
+
"""Access stablecoin data from DefiLlama."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, client: BaseClient) -> None:
|
|
22
|
+
self._client = client
|
|
23
|
+
|
|
24
|
+
def getStablecoins(self, includePrices: Optional[bool] = None) -> StablecoinsResponse:
|
|
25
|
+
"""Get all stablecoins with current market caps."""
|
|
26
|
+
|
|
27
|
+
params = {"includePrices": includePrices} if includePrices is not None else None
|
|
28
|
+
return self._client.get(
|
|
29
|
+
"/stablecoins",
|
|
30
|
+
base="stablecoins",
|
|
31
|
+
params=params,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def getAllCharts(self) -> List[StablecoinChartDataPoint]:
|
|
35
|
+
"""Get historical market cap data for all stablecoins."""
|
|
36
|
+
|
|
37
|
+
return self._client.get("/stablecoincharts/all", base="stablecoins")
|
|
38
|
+
|
|
39
|
+
def getChartsByChain(self, chain: str) -> List[StablecoinChainDataPoint]:
|
|
40
|
+
"""Get historical market cap data for stablecoins on a chain."""
|
|
41
|
+
|
|
42
|
+
return self._client.get(
|
|
43
|
+
f"/stablecoincharts/{quote(chain)}",
|
|
44
|
+
base="stablecoins",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def getStablecoin(self, asset: str) -> StablecoinDetails:
|
|
48
|
+
"""Get detailed information about a stablecoin."""
|
|
49
|
+
|
|
50
|
+
return self._client.get(
|
|
51
|
+
f"/stablecoin/{quote(asset)}",
|
|
52
|
+
base="stablecoins",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def getChains(self) -> List[StablecoinChainMcap]:
|
|
56
|
+
"""Get stablecoin market cap for all chains."""
|
|
57
|
+
|
|
58
|
+
return self._client.get("/stablecoinchains", base="stablecoins")
|
|
59
|
+
|
|
60
|
+
def getPrices(self) -> List[StablecoinPricePoint]:
|
|
61
|
+
"""Get historical prices for all stablecoins."""
|
|
62
|
+
|
|
63
|
+
return self._client.get("/stablecoinprices", base="stablecoins")
|
|
64
|
+
|
|
65
|
+
def getDominance(
|
|
66
|
+
self, chain: str, stablecoinId: Optional[int] = None
|
|
67
|
+
) -> List[StablecoinDominanceDataPoint]:
|
|
68
|
+
"""Get stablecoin dominance data for a chain."""
|
|
69
|
+
|
|
70
|
+
params = {"stablecoin": stablecoinId} if stablecoinId is not None else None
|
|
71
|
+
return self._client.get(
|
|
72
|
+
f"/stablecoindominance/{quote(chain)}",
|
|
73
|
+
requires_auth=True,
|
|
74
|
+
api_namespace="stablecoins",
|
|
75
|
+
params=params,
|
|
76
|
+
)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""TVL module implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional, Union
|
|
4
|
+
from urllib.parse import quote
|
|
5
|
+
|
|
6
|
+
from ..client import BaseClient
|
|
7
|
+
from ..types.tvl import (
|
|
8
|
+
Chain,
|
|
9
|
+
ChainAssetsResponse,
|
|
10
|
+
HistoricalChainTvl,
|
|
11
|
+
HistoricalChainsTvl,
|
|
12
|
+
Protocol,
|
|
13
|
+
ProtocolDetails,
|
|
14
|
+
ProtocolInflowsResponse,
|
|
15
|
+
TokenProtocolHolding,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TvlModule:
|
|
20
|
+
"""Access TVL data from DefiLlama."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, client: BaseClient) -> None:
|
|
23
|
+
self._client = client
|
|
24
|
+
|
|
25
|
+
def getProtocols(self) -> List[Protocol]:
|
|
26
|
+
"""Get all protocols with current TVL."""
|
|
27
|
+
|
|
28
|
+
return self._client.get("/protocols")
|
|
29
|
+
|
|
30
|
+
def getProtocol(self, protocol: str) -> ProtocolDetails:
|
|
31
|
+
"""Get detailed protocol information with historical TVL."""
|
|
32
|
+
|
|
33
|
+
return self._client.get(f"/protocol/{quote(protocol)}")
|
|
34
|
+
|
|
35
|
+
def getTvl(self, protocol: str) -> float:
|
|
36
|
+
"""Get current TVL for a protocol."""
|
|
37
|
+
|
|
38
|
+
return self._client.get(f"/tvl/{quote(protocol)}")
|
|
39
|
+
|
|
40
|
+
def getChains(self) -> List[Chain]:
|
|
41
|
+
"""Get current TVL for all chains."""
|
|
42
|
+
|
|
43
|
+
return self._client.get("/v2/chains")
|
|
44
|
+
|
|
45
|
+
def getHistoricalChainTvl(
|
|
46
|
+
self, chain: Optional[str] = None
|
|
47
|
+
) -> Union[List[HistoricalChainsTvl], List[HistoricalChainTvl]]:
|
|
48
|
+
"""Get historical TVL data for all chains or a specific chain."""
|
|
49
|
+
|
|
50
|
+
if chain:
|
|
51
|
+
return self._client.get(f"/v2/historicalChainTvl/{quote(chain)}")
|
|
52
|
+
return self._client.get("/v2/historicalChainTvl")
|
|
53
|
+
|
|
54
|
+
def getTokenProtocols(self, symbol: str) -> List[TokenProtocolHolding]:
|
|
55
|
+
"""Get protocols that hold a specific token."""
|
|
56
|
+
|
|
57
|
+
return self._client.get(
|
|
58
|
+
f"/tokenProtocols/{quote(symbol)}",
|
|
59
|
+
requires_auth=True,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def getInflows(
|
|
63
|
+
self,
|
|
64
|
+
protocol: str,
|
|
65
|
+
start_timestamp: int,
|
|
66
|
+
end_timestamp: int,
|
|
67
|
+
tokens_to_exclude: Optional[str] = None,
|
|
68
|
+
) -> ProtocolInflowsResponse:
|
|
69
|
+
"""Get token inflows/outflows for a protocol."""
|
|
70
|
+
|
|
71
|
+
params = {
|
|
72
|
+
"end": end_timestamp,
|
|
73
|
+
"tokensToExclude": tokens_to_exclude or "",
|
|
74
|
+
}
|
|
75
|
+
return self._client.get(
|
|
76
|
+
f"/inflows/{quote(protocol)}/{start_timestamp}",
|
|
77
|
+
requires_auth=True,
|
|
78
|
+
params=params,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
def getChainAssets(self) -> ChainAssetsResponse:
|
|
82
|
+
"""Get asset breakdown for all chains."""
|
|
83
|
+
|
|
84
|
+
return self._client.get("/chainAssets", requires_auth=True)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Volumes module implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from urllib.parse import quote
|
|
5
|
+
|
|
6
|
+
from ..client import BaseClient
|
|
7
|
+
from ..types.volumes import (
|
|
8
|
+
DexOverviewOptions,
|
|
9
|
+
DexOverviewResponse,
|
|
10
|
+
DexSummaryOptions,
|
|
11
|
+
DexSummaryResponse,
|
|
12
|
+
DerivativesOverviewResponse,
|
|
13
|
+
DerivativesSummaryResponse,
|
|
14
|
+
OptionsOverviewOptions,
|
|
15
|
+
OptionsOverviewResponse,
|
|
16
|
+
OptionsSummaryResponse,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class VolumesModule:
|
|
21
|
+
"""Access volume data from DefiLlama."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, client: BaseClient) -> None:
|
|
24
|
+
self._client = client
|
|
25
|
+
|
|
26
|
+
def getDexOverview(
|
|
27
|
+
self, options: Optional[DexOverviewOptions] = None
|
|
28
|
+
) -> DexOverviewResponse:
|
|
29
|
+
"""Get overview of DEX volume data."""
|
|
30
|
+
|
|
31
|
+
params = {}
|
|
32
|
+
if options:
|
|
33
|
+
if options.get("excludeTotalDataChart") is not None:
|
|
34
|
+
params["excludeTotalDataChart"] = options.get("excludeTotalDataChart")
|
|
35
|
+
if options.get("excludeTotalDataChartBreakdown") is not None:
|
|
36
|
+
params["excludeTotalDataChartBreakdown"] = options.get(
|
|
37
|
+
"excludeTotalDataChartBreakdown"
|
|
38
|
+
)
|
|
39
|
+
if options.get("dataType"):
|
|
40
|
+
params["dataType"] = options.get("dataType")
|
|
41
|
+
return self._client.get(
|
|
42
|
+
"/overview/dexs",
|
|
43
|
+
params=params or None,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def getDexOverviewByChain(
|
|
47
|
+
self, chain: str, options: Optional[DexOverviewOptions] = None
|
|
48
|
+
) -> DexOverviewResponse:
|
|
49
|
+
"""Get DEX volume overview for a chain."""
|
|
50
|
+
|
|
51
|
+
params = {}
|
|
52
|
+
if options:
|
|
53
|
+
if options.get("excludeTotalDataChart") is not None:
|
|
54
|
+
params["excludeTotalDataChart"] = options.get("excludeTotalDataChart")
|
|
55
|
+
if options.get("excludeTotalDataChartBreakdown") is not None:
|
|
56
|
+
params["excludeTotalDataChartBreakdown"] = options.get(
|
|
57
|
+
"excludeTotalDataChartBreakdown"
|
|
58
|
+
)
|
|
59
|
+
return self._client.get(
|
|
60
|
+
f"/overview/dexs/{quote(chain)}",
|
|
61
|
+
params=params or None,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def getDexSummary(
|
|
65
|
+
self, protocol: str, options: Optional[DexSummaryOptions] = None
|
|
66
|
+
) -> DexSummaryResponse:
|
|
67
|
+
"""Get DEX volume summary for a protocol."""
|
|
68
|
+
|
|
69
|
+
params = {}
|
|
70
|
+
if options and options.get("dataType"):
|
|
71
|
+
params["dataType"] = options.get("dataType")
|
|
72
|
+
return self._client.get(
|
|
73
|
+
f"/summary/dexs/{quote(protocol)}",
|
|
74
|
+
params=params or None,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def getOptionsOverview(
|
|
78
|
+
self, options: Optional[OptionsOverviewOptions] = None
|
|
79
|
+
) -> OptionsOverviewResponse:
|
|
80
|
+
"""Get options volume overview."""
|
|
81
|
+
|
|
82
|
+
params = {}
|
|
83
|
+
if options:
|
|
84
|
+
if options.get("excludeTotalDataChart") is not None:
|
|
85
|
+
params["excludeTotalDataChart"] = options.get("excludeTotalDataChart")
|
|
86
|
+
if options.get("excludeTotalDataChartBreakdown") is not None:
|
|
87
|
+
params["excludeTotalDataChartBreakdown"] = options.get(
|
|
88
|
+
"excludeTotalDataChartBreakdown"
|
|
89
|
+
)
|
|
90
|
+
return self._client.get(
|
|
91
|
+
"/overview/options",
|
|
92
|
+
params=params or None,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def getOptionsOverviewByChain(self, chain: str) -> OptionsOverviewResponse:
|
|
96
|
+
"""Get options volume for a chain."""
|
|
97
|
+
|
|
98
|
+
return self._client.get(f"/overview/options/{quote(chain)}")
|
|
99
|
+
|
|
100
|
+
def getOptionsSummary(self, protocol: str) -> OptionsSummaryResponse:
|
|
101
|
+
"""Get options volume summary for a protocol."""
|
|
102
|
+
|
|
103
|
+
return self._client.get(f"/summary/options/{quote(protocol)}")
|
|
104
|
+
|
|
105
|
+
def getDerivativesOverview(self) -> DerivativesOverviewResponse:
|
|
106
|
+
"""Get derivatives volume overview."""
|
|
107
|
+
|
|
108
|
+
return self._client.get("/overview/derivatives", requires_auth=True)
|
|
109
|
+
|
|
110
|
+
def getDerivativesSummary(self, protocol: str) -> DerivativesSummaryResponse:
|
|
111
|
+
"""Get derivatives volume summary for a protocol."""
|
|
112
|
+
|
|
113
|
+
return self._client.get(
|
|
114
|
+
f"/summary/derivatives/{quote(protocol)}",
|
|
115
|
+
requires_auth=True,
|
|
116
|
+
)
|