defistream 1.0.0__py3-none-any.whl → 1.0.1__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.
defistream/__init__.py CHANGED
@@ -1,19 +1,22 @@
1
1
  """
2
2
  DeFiStream Python Client
3
3
 
4
- Official Python client for the DeFiStream API - access historical
5
- DeFi events from 45+ EVM networks.
4
+ Official Python client for the DeFiStream API.
6
5
 
7
6
  Example:
8
7
  >>> from defistream import DeFiStream
9
8
  >>> client = DeFiStream(api_key="dsk_...")
10
9
  >>>
11
- >>> # Builder pattern
12
- >>> query = client.erc20.transfers("USDT").network("ETH").start_block(24000000).end_block(24100000)
13
- >>> transfers = query.as_dict()
10
+ >>> # Builder pattern - returns pandas DataFrame
11
+ >>> df = (
12
+ ... client.erc20.transfers("USDT")
13
+ ... .network("ETH")
14
+ ... .block_range(21000000, 21010000)
15
+ ... .as_df()
16
+ ... )
14
17
  >>>
15
18
  >>> # Save to file
16
- >>> query.to_csv_file("transfers.csv")
19
+ >>> query.as_file("transfers.parquet")
17
20
  """
18
21
 
19
22
  from .client import AsyncDeFiStream, DeFiStream
@@ -32,20 +35,17 @@ from .models import (
32
35
  AAVELiquidationEvent,
33
36
  AAVERepayEvent,
34
37
  AAVEWithdrawEvent,
35
- ERC20ApprovalEvent,
36
38
  ERC20TransferEvent,
37
39
  EventBase,
38
40
  LidoDepositEvent,
39
41
  LidoWithdrawEvent,
40
42
  NativeTransferEvent,
41
43
  ResponseMetadata,
42
- UniswapBurnEvent,
43
- UniswapMintEvent,
44
44
  UniswapSwapEvent,
45
45
  )
46
46
  from .query import AsyncQueryBuilder, QueryBuilder
47
47
 
48
- __version__ = "0.1.0"
48
+ __version__ = "1.0.1"
49
49
 
50
50
  __all__ = [
51
51
  # Clients
@@ -66,7 +66,6 @@ __all__ = [
66
66
  "EventBase",
67
67
  "ResponseMetadata",
68
68
  "ERC20TransferEvent",
69
- "ERC20ApprovalEvent",
70
69
  "NativeTransferEvent",
71
70
  "AAVEDepositEvent",
72
71
  "AAVEWithdrawEvent",
@@ -74,8 +73,6 @@ __all__ = [
74
73
  "AAVERepayEvent",
75
74
  "AAVELiquidationEvent",
76
75
  "UniswapSwapEvent",
77
- "UniswapMintEvent",
78
- "UniswapBurnEvent",
79
76
  "LidoDepositEvent",
80
77
  "LidoWithdrawEvent",
81
78
  ]
defistream/protocols.py CHANGED
@@ -21,34 +21,25 @@ class ERC20Protocol:
21
21
  Start a query for ERC20 transfer events.
22
22
 
23
23
  Args:
24
- token: Optional token symbol (USDT, USDC, WETH, etc.)
24
+ token: Token symbol (USDT, USDC, WETH, etc.) or contract address
25
25
 
26
26
  Returns:
27
27
  QueryBuilder for chaining filters
28
28
 
29
29
  Example:
30
- query = client.erc20.transfers("USDT").network("ETH").start_block(24000000).end_block(24100000)
31
- df = query.as_pandas()
30
+ df = (
31
+ client.erc20.transfers("USDT")
32
+ .network("ETH")
33
+ .block_range(21000000, 21010000)
34
+ .as_df()
35
+ )
32
36
  """
33
37
  params = {"token": token} if token else {}
34
38
  return QueryBuilder(self._client, "/erc20/events/transfer", params)
35
39
 
36
- def approvals(self, token: str | None = None) -> QueryBuilder:
37
- """
38
- Start a query for ERC20 approval events.
39
-
40
- Args:
41
- token: Optional token symbol
42
-
43
- Returns:
44
- QueryBuilder for chaining filters
45
- """
46
- params = {"token": token} if token else {}
47
- return QueryBuilder(self._client, "/erc20/events/approval", params)
48
-
49
40
 
50
41
  class NativeTokenProtocol:
51
- """Native token (ETH, MATIC, BNB, etc.) events with builder pattern."""
42
+ """Native token (ETH, MATIC, etc.) events with builder pattern."""
52
43
 
53
44
  def __init__(self, client: "BaseClient"):
54
45
  self._client = client
@@ -61,8 +52,13 @@ class NativeTokenProtocol:
61
52
  QueryBuilder for chaining filters
62
53
 
63
54
  Example:
64
- query = client.native_token.transfers().network("ETH").start_block(24000000).end_block(24100000)
65
- transfers = query.min_amount(1.0).as_dict()
55
+ df = (
56
+ client.native_token.transfers()
57
+ .network("ETH")
58
+ .block_range(21000000, 21010000)
59
+ .min_amount(1.0)
60
+ .as_df()
61
+ )
66
62
  """
67
63
  return QueryBuilder(self._client, "/native_token/events/transfer")
68
64
 
@@ -89,6 +85,10 @@ class AAVEProtocol:
89
85
  """Start a query for AAVE repay events."""
90
86
  return QueryBuilder(self._client, "/aave/events/repay")
91
87
 
88
+ def flashloans(self) -> QueryBuilder:
89
+ """Start a query for AAVE flash loan events."""
90
+ return QueryBuilder(self._client, "/aave/events/flashloan")
91
+
92
92
  def liquidations(self) -> QueryBuilder:
93
93
  """Start a query for AAVE liquidation events."""
94
94
  return QueryBuilder(self._client, "/aave/events/liquidation")
@@ -110,16 +110,20 @@ class UniswapProtocol:
110
110
  Start a query for Uniswap V3 swap events.
111
111
 
112
112
  Args:
113
- symbol0: Optional first token symbol (e.g., WETH)
114
- symbol1: Optional second token symbol (e.g., USDC)
115
- fee: Optional fee tier (100, 500, 3000, 10000)
113
+ symbol0: First token symbol (e.g., WETH)
114
+ symbol1: Second token symbol (e.g., USDC)
115
+ fee: Fee tier (100, 500, 3000, 10000)
116
116
 
117
117
  Returns:
118
118
  QueryBuilder for chaining filters
119
119
 
120
120
  Example:
121
- query = client.uniswap.swaps("WETH", "USDC", 500).network("ETH").start_block(24000000).end_block(24100000)
122
- df = query.as_pandas()
121
+ df = (
122
+ client.uniswap.swaps("WETH", "USDC", 500)
123
+ .network("ETH")
124
+ .block_range(21000000, 21010000)
125
+ .as_df()
126
+ )
123
127
  """
124
128
  params: dict[str, Any] = {}
125
129
  if symbol0:
@@ -130,13 +134,13 @@ class UniswapProtocol:
130
134
  params["fee"] = fee
131
135
  return QueryBuilder(self._client, "/uniswap/events/swap", params)
132
136
 
133
- def mints(
137
+ def deposits(
134
138
  self,
135
139
  symbol0: str | None = None,
136
140
  symbol1: str | None = None,
137
141
  fee: int | None = None,
138
142
  ) -> QueryBuilder:
139
- """Start a query for Uniswap V3 mint (add liquidity) events."""
143
+ """Start a query for Uniswap V3 deposit (add liquidity) events."""
140
144
  params: dict[str, Any] = {}
141
145
  if symbol0:
142
146
  params["symbol0"] = symbol0
@@ -144,15 +148,15 @@ class UniswapProtocol:
144
148
  params["symbol1"] = symbol1
145
149
  if fee:
146
150
  params["fee"] = fee
147
- return QueryBuilder(self._client, "/uniswap/events/mint", params)
151
+ return QueryBuilder(self._client, "/uniswap/events/deposit", params)
148
152
 
149
- def burns(
153
+ def withdrawals(
150
154
  self,
151
155
  symbol0: str | None = None,
152
156
  symbol1: str | None = None,
153
157
  fee: int | None = None,
154
158
  ) -> QueryBuilder:
155
- """Start a query for Uniswap V3 burn (remove liquidity) events."""
159
+ """Start a query for Uniswap V3 withdrawal (remove liquidity) events."""
156
160
  params: dict[str, Any] = {}
157
161
  if symbol0:
158
162
  params["symbol0"] = symbol0
@@ -160,7 +164,23 @@ class UniswapProtocol:
160
164
  params["symbol1"] = symbol1
161
165
  if fee:
162
166
  params["fee"] = fee
163
- return QueryBuilder(self._client, "/uniswap/events/burn", params)
167
+ return QueryBuilder(self._client, "/uniswap/events/withdraw", params)
168
+
169
+ def collects(
170
+ self,
171
+ symbol0: str | None = None,
172
+ symbol1: str | None = None,
173
+ fee: int | None = None,
174
+ ) -> QueryBuilder:
175
+ """Start a query for Uniswap V3 collect (fee collection) events."""
176
+ params: dict[str, Any] = {}
177
+ if symbol0:
178
+ params["symbol0"] = symbol0
179
+ if symbol1:
180
+ params["symbol1"] = symbol1
181
+ if fee:
182
+ params["fee"] = fee
183
+ return QueryBuilder(self._client, "/uniswap/events/collect", params)
164
184
 
165
185
 
166
186
  class LidoProtocol:
@@ -169,17 +189,31 @@ class LidoProtocol:
169
189
  def __init__(self, client: "BaseClient"):
170
190
  self._client = client
171
191
 
192
+ # L1 ETH events
172
193
  def deposits(self) -> QueryBuilder:
173
- """Start a query for Lido stETH deposit events."""
194
+ """Start a query for Lido stETH deposit events (ETH L1 only)."""
174
195
  return QueryBuilder(self._client, "/lido/events/deposit")
175
196
 
176
- def withdrawals(self) -> QueryBuilder:
177
- """Start a query for Lido withdrawal events."""
178
- return QueryBuilder(self._client, "/lido/events/withdraw")
197
+ def withdrawal_requests(self) -> QueryBuilder:
198
+ """Start a query for Lido withdrawal request events (ETH L1 only)."""
199
+ return QueryBuilder(self._client, "/lido/events/withdrawal_request")
200
+
201
+ def withdrawals_claimed(self) -> QueryBuilder:
202
+ """Start a query for Lido claimed withdrawal events (ETH L1 only)."""
203
+ return QueryBuilder(self._client, "/lido/events/withdrawal_claimed")
204
+
205
+ # L2 events
206
+ def l2_deposits(self) -> QueryBuilder:
207
+ """Start a query for Lido L2 deposit events (L2 networks only)."""
208
+ return QueryBuilder(self._client, "/lido/events/l2_deposit")
209
+
210
+ def l2_withdrawal_requests(self) -> QueryBuilder:
211
+ """Start a query for Lido L2 withdrawal request events (L2 networks only)."""
212
+ return QueryBuilder(self._client, "/lido/events/l2_withdrawal_request")
179
213
 
180
214
 
181
215
  class StaderProtocol:
182
- """Stader EthX staking events with builder pattern."""
216
+ """Stader ETHx staking events with builder pattern (ETH only)."""
183
217
 
184
218
  def __init__(self, client: "BaseClient"):
185
219
  self._client = client
@@ -188,24 +222,36 @@ class StaderProtocol:
188
222
  """Start a query for Stader deposit events."""
189
223
  return QueryBuilder(self._client, "/stader/events/deposit")
190
224
 
225
+ def withdrawal_requests(self) -> QueryBuilder:
226
+ """Start a query for Stader withdrawal request events."""
227
+ return QueryBuilder(self._client, "/stader/events/withdrawal_request")
228
+
191
229
  def withdrawals(self) -> QueryBuilder:
192
230
  """Start a query for Stader withdrawal events."""
193
- return QueryBuilder(self._client, "/stader/events/withdraw")
231
+ return QueryBuilder(self._client, "/stader/events/withdrawal")
194
232
 
195
233
 
196
234
  class ThresholdProtocol:
197
- """Threshold tBTC events with builder pattern."""
235
+ """Threshold tBTC events with builder pattern (ETH only)."""
198
236
 
199
237
  def __init__(self, client: "BaseClient"):
200
238
  self._client = client
201
239
 
202
- def mints(self) -> QueryBuilder:
203
- """Start a query for tBTC mint events."""
204
- return QueryBuilder(self._client, "/threshold/events/mint")
240
+ def deposit_requests(self) -> QueryBuilder:
241
+ """Start a query for tBTC deposit request (reveal) events."""
242
+ return QueryBuilder(self._client, "/threshold/events/deposit_request")
205
243
 
206
- def burns(self) -> QueryBuilder:
207
- """Start a query for tBTC burn/redeem events."""
208
- return QueryBuilder(self._client, "/threshold/events/burn")
244
+ def deposits(self) -> QueryBuilder:
245
+ """Start a query for tBTC deposit (mint) events."""
246
+ return QueryBuilder(self._client, "/threshold/events/deposit")
247
+
248
+ def withdrawal_requests(self) -> QueryBuilder:
249
+ """Start a query for tBTC withdrawal request events."""
250
+ return QueryBuilder(self._client, "/threshold/events/withdrawal_request")
251
+
252
+ def withdrawals(self) -> QueryBuilder:
253
+ """Start a query for tBTC withdrawal (unmint) events."""
254
+ return QueryBuilder(self._client, "/threshold/events/withdrawal")
209
255
 
210
256
 
211
257
  # Async protocol implementations
@@ -220,11 +266,6 @@ class AsyncERC20Protocol:
220
266
  params = {"token": token} if token else {}
221
267
  return AsyncQueryBuilder(self._client, "/erc20/events/transfer", params)
222
268
 
223
- def approvals(self, token: str | None = None) -> AsyncQueryBuilder:
224
- """Start a query for ERC20 approval events."""
225
- params = {"token": token} if token else {}
226
- return AsyncQueryBuilder(self._client, "/erc20/events/approval", params)
227
-
228
269
 
229
270
  class AsyncNativeTokenProtocol:
230
271
  """Async native token events with builder pattern."""
@@ -259,6 +300,10 @@ class AsyncAAVEProtocol:
259
300
  """Start a query for AAVE repay events."""
260
301
  return AsyncQueryBuilder(self._client, "/aave/events/repay")
261
302
 
303
+ def flashloans(self) -> AsyncQueryBuilder:
304
+ """Start a query for AAVE flash loan events."""
305
+ return AsyncQueryBuilder(self._client, "/aave/events/flashloan")
306
+
262
307
  def liquidations(self) -> AsyncQueryBuilder:
263
308
  """Start a query for AAVE liquidation events."""
264
309
  return AsyncQueryBuilder(self._client, "/aave/events/liquidation")
@@ -286,13 +331,29 @@ class AsyncUniswapProtocol:
286
331
  params["fee"] = fee
287
332
  return AsyncQueryBuilder(self._client, "/uniswap/events/swap", params)
288
333
 
289
- def mints(
334
+ def deposits(
335
+ self,
336
+ symbol0: str | None = None,
337
+ symbol1: str | None = None,
338
+ fee: int | None = None,
339
+ ) -> AsyncQueryBuilder:
340
+ """Start a query for Uniswap V3 deposit events."""
341
+ params: dict[str, Any] = {}
342
+ if symbol0:
343
+ params["symbol0"] = symbol0
344
+ if symbol1:
345
+ params["symbol1"] = symbol1
346
+ if fee:
347
+ params["fee"] = fee
348
+ return AsyncQueryBuilder(self._client, "/uniswap/events/deposit", params)
349
+
350
+ def withdrawals(
290
351
  self,
291
352
  symbol0: str | None = None,
292
353
  symbol1: str | None = None,
293
354
  fee: int | None = None,
294
355
  ) -> AsyncQueryBuilder:
295
- """Start a query for Uniswap V3 mint events."""
356
+ """Start a query for Uniswap V3 withdrawal events."""
296
357
  params: dict[str, Any] = {}
297
358
  if symbol0:
298
359
  params["symbol0"] = symbol0
@@ -300,15 +361,15 @@ class AsyncUniswapProtocol:
300
361
  params["symbol1"] = symbol1
301
362
  if fee:
302
363
  params["fee"] = fee
303
- return AsyncQueryBuilder(self._client, "/uniswap/events/mint", params)
364
+ return AsyncQueryBuilder(self._client, "/uniswap/events/withdraw", params)
304
365
 
305
- def burns(
366
+ def collects(
306
367
  self,
307
368
  symbol0: str | None = None,
308
369
  symbol1: str | None = None,
309
370
  fee: int | None = None,
310
371
  ) -> AsyncQueryBuilder:
311
- """Start a query for Uniswap V3 burn events."""
372
+ """Start a query for Uniswap V3 collect events."""
312
373
  params: dict[str, Any] = {}
313
374
  if symbol0:
314
375
  params["symbol0"] = symbol0
@@ -316,7 +377,7 @@ class AsyncUniswapProtocol:
316
377
  params["symbol1"] = symbol1
317
378
  if fee:
318
379
  params["fee"] = fee
319
- return AsyncQueryBuilder(self._client, "/uniswap/events/burn", params)
380
+ return AsyncQueryBuilder(self._client, "/uniswap/events/collect", params)
320
381
 
321
382
 
322
383
  class AsyncLidoProtocol:
@@ -326,12 +387,24 @@ class AsyncLidoProtocol:
326
387
  self._client = client
327
388
 
328
389
  def deposits(self) -> AsyncQueryBuilder:
329
- """Start a query for Lido deposit events."""
390
+ """Start a query for Lido deposit events (ETH L1 only)."""
330
391
  return AsyncQueryBuilder(self._client, "/lido/events/deposit")
331
392
 
332
- def withdrawals(self) -> AsyncQueryBuilder:
333
- """Start a query for Lido withdrawal events."""
334
- return AsyncQueryBuilder(self._client, "/lido/events/withdraw")
393
+ def withdrawal_requests(self) -> AsyncQueryBuilder:
394
+ """Start a query for Lido withdrawal request events (ETH L1 only)."""
395
+ return AsyncQueryBuilder(self._client, "/lido/events/withdrawal_request")
396
+
397
+ def withdrawals_claimed(self) -> AsyncQueryBuilder:
398
+ """Start a query for Lido claimed withdrawal events (ETH L1 only)."""
399
+ return AsyncQueryBuilder(self._client, "/lido/events/withdrawal_claimed")
400
+
401
+ def l2_deposits(self) -> AsyncQueryBuilder:
402
+ """Start a query for Lido L2 deposit events."""
403
+ return AsyncQueryBuilder(self._client, "/lido/events/l2_deposit")
404
+
405
+ def l2_withdrawal_requests(self) -> AsyncQueryBuilder:
406
+ """Start a query for Lido L2 withdrawal request events."""
407
+ return AsyncQueryBuilder(self._client, "/lido/events/l2_withdrawal_request")
335
408
 
336
409
 
337
410
  class AsyncStaderProtocol:
@@ -344,9 +417,13 @@ class AsyncStaderProtocol:
344
417
  """Start a query for Stader deposit events."""
345
418
  return AsyncQueryBuilder(self._client, "/stader/events/deposit")
346
419
 
420
+ def withdrawal_requests(self) -> AsyncQueryBuilder:
421
+ """Start a query for Stader withdrawal request events."""
422
+ return AsyncQueryBuilder(self._client, "/stader/events/withdrawal_request")
423
+
347
424
  def withdrawals(self) -> AsyncQueryBuilder:
348
425
  """Start a query for Stader withdrawal events."""
349
- return AsyncQueryBuilder(self._client, "/stader/events/withdraw")
426
+ return AsyncQueryBuilder(self._client, "/stader/events/withdrawal")
350
427
 
351
428
 
352
429
  class AsyncThresholdProtocol:
@@ -355,10 +432,18 @@ class AsyncThresholdProtocol:
355
432
  def __init__(self, client: "BaseClient"):
356
433
  self._client = client
357
434
 
358
- def mints(self) -> AsyncQueryBuilder:
359
- """Start a query for tBTC mint events."""
360
- return AsyncQueryBuilder(self._client, "/threshold/events/mint")
435
+ def deposit_requests(self) -> AsyncQueryBuilder:
436
+ """Start a query for tBTC deposit request events."""
437
+ return AsyncQueryBuilder(self._client, "/threshold/events/deposit_request")
361
438
 
362
- def burns(self) -> AsyncQueryBuilder:
363
- """Start a query for tBTC burn events."""
364
- return AsyncQueryBuilder(self._client, "/threshold/events/burn")
439
+ def deposits(self) -> AsyncQueryBuilder:
440
+ """Start a query for tBTC deposit events."""
441
+ return AsyncQueryBuilder(self._client, "/threshold/events/deposit")
442
+
443
+ def withdrawal_requests(self) -> AsyncQueryBuilder:
444
+ """Start a query for tBTC withdrawal request events."""
445
+ return AsyncQueryBuilder(self._client, "/threshold/events/withdrawal_request")
446
+
447
+ def withdrawals(self) -> AsyncQueryBuilder:
448
+ """Start a query for tBTC withdrawal events."""
449
+ return AsyncQueryBuilder(self._client, "/threshold/events/withdrawal")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: defistream
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Python client for the DeFiStream API
5
5
  Project-URL: Homepage, https://defistream.dev
6
6
  Project-URL: Documentation, https://docs.defistream.dev
@@ -34,7 +34,11 @@ Description-Content-Type: text/markdown
34
34
 
35
35
  # DeFiStream Python Client
36
36
 
37
- Official Python client for the [DeFiStream API](https://defistream.dev) - access historical DeFi events from 45+ EVM networks.
37
+ Official Python client for the [DeFiStream API](https://defistream.dev).
38
+
39
+ ## Getting an API Key
40
+
41
+ To use the DeFiStream API, you need to sign up for an account at [defistream.dev](https://defistream.dev) to obtain your API key.
38
42
 
39
43
  ## Installation
40
44
 
@@ -61,44 +65,41 @@ client = DeFiStream()
61
65
  client = DeFiStream(api_key="dsk_your_api_key")
62
66
 
63
67
  # Query ERC20 transfers using builder pattern
64
- transfers = (
68
+ df = (
65
69
  client.erc20.transfers("USDT")
66
70
  .network("ETH")
67
- .start_block(24000000)
68
- .end_block(24100000)
69
- .as_dict()
71
+ .block_range(21000000, 21010000)
72
+ .as_df()
70
73
  )
71
74
 
72
- for transfer in transfers:
73
- print(f"{transfer['sender']} -> {transfer['receiver']}: {transfer['amount']}")
75
+ print(df.head())
74
76
  ```
75
77
 
76
78
  ## Features
77
79
 
78
80
  - **Builder pattern**: Fluent query API with chainable methods
79
81
  - **Type-safe**: Full type hints and Pydantic models
80
- - **Multiple formats**: JSON, CSV, Parquet, pandas DataFrame, polars DataFrame
82
+ - **Multiple formats**: DataFrame (pandas/polars), CSV, Parquet, JSON
81
83
  - **Async support**: Native async/await with `AsyncDeFiStream`
82
- - **All protocols**: AAVE, Uniswap, Lido, ERC20, Native tokens, and more
83
- - **Verbose mode**: Include all metadata fields (tx_hash, tx_id, log_index, network, name)
84
+ - **All protocols**: ERC20, AAVE, Uniswap, Lido, Stader, Threshold, Native tokens
84
85
 
85
86
  ## Supported Protocols
86
87
 
87
88
  | Protocol | Events |
88
89
  |----------|--------|
89
- | ERC20 | `transfers`, `approvals` |
90
+ | ERC20 | `transfers` |
90
91
  | Native Token | `transfers` |
91
- | AAVE V3 | `deposits`, `withdrawals`, `borrows`, `repays`, `liquidations` |
92
- | Uniswap V3 | `swaps`, `mints`, `burns` |
93
- | Lido | `deposits`, `withdrawals` |
94
- | Stader | `deposits`, `withdrawals` |
95
- | Threshold | `mints`, `burns` |
92
+ | AAVE V3 | `deposits`, `withdrawals`, `borrows`, `repays`, `flashloans`, `liquidations` |
93
+ | Uniswap V3 | `swaps`, `deposits`, `withdrawals`, `collects` |
94
+ | Lido | `deposits`, `withdrawal_requests`, `withdrawals_claimed`, `l2_deposits`, `l2_withdrawal_requests` |
95
+ | Stader | `deposits`, `withdrawal_requests`, `withdrawals` |
96
+ | Threshold | `deposit_requests`, `deposits`, `withdrawal_requests`, `withdrawals` |
96
97
 
97
98
  ## Usage Examples
98
99
 
99
100
  ### Builder Pattern
100
101
 
101
- The client uses a fluent builder pattern. The query is only executed when you call a terminal method like `as_dict()`, `as_df()`, or `as_file()`.
102
+ The client uses a fluent builder pattern. The query is only executed when you call a terminal method like `as_df()`, `as_file()`, or `as_dict()`.
102
103
 
103
104
  ```python
104
105
  from defistream import DeFiStream
@@ -108,21 +109,19 @@ client = DeFiStream()
108
109
  # Build query step by step
109
110
  query = client.erc20.transfers("USDT")
110
111
  query = query.network("ETH")
111
- query = query.start_block(24000000)
112
- query = query.end_block(24100000)
112
+ query = query.block_range(21000000, 21010000)
113
113
  query = query.min_amount(1000)
114
114
 
115
- # Execute and get results
116
- transfers = query.as_dict()
115
+ # Execute and get DataFrame
116
+ df = query.as_df()
117
117
 
118
118
  # Or chain everything
119
- transfers = (
119
+ df = (
120
120
  client.erc20.transfers("USDT")
121
121
  .network("ETH")
122
- .start_block(24000000)
123
- .end_block(24100000)
122
+ .block_range(21000000, 21010000)
124
123
  .min_amount(1000)
125
- .as_dict()
124
+ .as_df()
126
125
  )
127
126
  ```
128
127
 
@@ -130,35 +129,21 @@ transfers = (
130
129
 
131
130
  ```python
132
131
  # Get USDT transfers over 10,000 USDT
133
- transfers = (
132
+ df = (
134
133
  client.erc20.transfers("USDT")
135
134
  .network("ETH")
136
- .start_block(24000000)
137
- .end_block(24100000)
135
+ .block_range(21000000, 21010000)
138
136
  .min_amount(10000)
139
- .as_dict()
137
+ .as_df()
140
138
  )
141
139
 
142
140
  # Filter by sender
143
- transfers = (
141
+ df = (
144
142
  client.erc20.transfers("USDT")
145
143
  .network("ETH")
146
- .start_block(24000000)
147
- .end_block(24100000)
144
+ .block_range(21000000, 21010000)
148
145
  .sender("0x28c6c06298d514db089934071355e5743bf21d60")
149
- .as_dict()
150
- )
151
-
152
- # Or use aliases: from_address/to_address
153
- transfers = (
154
- client.erc20.transfers()
155
- .network("ETH")
156
- .start_block(24000000)
157
- .end_block(24100000)
158
- .token("USDC")
159
- .from_address("0x...")
160
- .to_address("0x...")
161
- .as_dict()
146
+ .as_df()
162
147
  )
163
148
  ```
164
149
 
@@ -166,22 +151,20 @@ transfers = (
166
151
 
167
152
  ```python
168
153
  # Get deposits
169
- deposits = (
154
+ df = (
170
155
  client.aave.deposits()
171
156
  .network("ETH")
172
- .start_block(24000000)
173
- .end_block(24100000)
174
- .as_dict()
157
+ .block_range(21000000, 21010000)
158
+ .as_df()
175
159
  )
176
160
 
177
161
  # Get liquidations for a specific user
178
- liquidations = (
162
+ df = (
179
163
  client.aave.liquidations()
180
164
  .network("ETH")
181
- .start_block(24000000)
182
- .end_block(24100000)
165
+ .block_range(21000000, 21010000)
183
166
  .user("0x...")
184
- .as_dict()
167
+ .as_df()
185
168
  )
186
169
  ```
187
170
 
@@ -189,24 +172,22 @@ liquidations = (
189
172
 
190
173
  ```python
191
174
  # Get swaps for WETH/USDC pool with 0.05% fee tier
192
- swaps = (
175
+ df = (
193
176
  client.uniswap.swaps("WETH", "USDC", 500)
194
177
  .network("ETH")
195
- .start_block(24000000)
196
- .end_block(24100000)
197
- .as_dict()
178
+ .block_range(21000000, 21010000)
179
+ .as_df()
198
180
  )
199
181
 
200
182
  # Or build with chain methods
201
- swaps = (
183
+ df = (
202
184
  client.uniswap.swaps()
203
185
  .symbol0("WETH")
204
186
  .symbol1("USDC")
205
187
  .fee(500)
206
188
  .network("ETH")
207
- .start_block(24000000)
208
- .end_block(24100000)
209
- .as_dict()
189
+ .block_range(21000000, 21010000)
190
+ .as_df()
210
191
  )
211
192
  ```
212
193
 
@@ -214,13 +195,12 @@ swaps = (
214
195
 
215
196
  ```python
216
197
  # Get ETH transfers >= 1 ETH
217
- transfers = (
198
+ df = (
218
199
  client.native_token.transfers()
219
200
  .network("ETH")
220
- .start_block(24000000)
221
- .end_block(24100000)
201
+ .block_range(21000000, 21010000)
222
202
  .min_amount(1.0)
223
- .as_dict()
203
+ .as_df()
224
204
  )
225
205
  ```
226
206
 
@@ -230,25 +210,21 @@ By default, responses omit metadata fields to reduce payload size. Use `.verbose
230
210
 
231
211
  ```python
232
212
  # Default: compact response (no tx_hash, tx_id, log_index, network, name)
233
- transfers = (
213
+ df = (
234
214
  client.erc20.transfers("USDT")
235
215
  .network("ETH")
236
- .start_block(24000000)
237
- .end_block(24100000)
238
- .as_dict()
216
+ .block_range(21000000, 21010000)
217
+ .as_df()
239
218
  )
240
- # Returns: [{"block_number": 24000050, "sender": "0x...", "receiver": "0x...", "amount": 1000.0, ...}]
241
219
 
242
220
  # Verbose: includes all metadata fields
243
- transfers = (
221
+ df = (
244
222
  client.erc20.transfers("USDT")
245
223
  .network("ETH")
246
- .start_block(24000000)
247
- .end_block(24100000)
224
+ .block_range(21000000, 21010000)
248
225
  .verbose()
249
- .as_dict()
226
+ .as_df()
250
227
  )
251
- # Returns: [{"name": "TransferEvent", "network": "ETH", "tx_id": "0x...", "tx_hash": "0x...", "log_index": 5, "block_number": 24000050, ...}]
252
228
  ```
253
229
 
254
230
  ### Return as DataFrame
@@ -258,8 +234,7 @@ transfers = (
258
234
  df = (
259
235
  client.erc20.transfers("USDT")
260
236
  .network("ETH")
261
- .start_block(24000000)
262
- .end_block(24100000)
237
+ .block_range(21000000, 21010000)
263
238
  .as_df()
264
239
  )
265
240
 
@@ -267,8 +242,7 @@ df = (
267
242
  df = (
268
243
  client.erc20.transfers("USDT")
269
244
  .network("ETH")
270
- .start_block(24000000)
271
- .end_block(24100000)
245
+ .block_range(21000000, 21010000)
272
246
  .as_df("polars")
273
247
  )
274
248
  ```
@@ -278,43 +252,49 @@ df = (
278
252
  Format is automatically determined by file extension:
279
253
 
280
254
  ```python
281
- # Save as CSV
255
+ # Save as Parquet (recommended for large datasets)
282
256
  (
283
257
  client.erc20.transfers("USDT")
284
258
  .network("ETH")
285
- .start_block(24000000)
286
- .end_block(24100000)
287
- .as_file("transfers.csv")
259
+ .block_range(21000000, 21100000)
260
+ .as_file("transfers.parquet")
288
261
  )
289
262
 
290
- # Save as Parquet
263
+ # Save as CSV
291
264
  (
292
265
  client.erc20.transfers("USDT")
293
266
  .network("ETH")
294
- .start_block(24000000)
295
- .end_block(24100000)
296
- .as_file("transfers.parquet")
267
+ .block_range(21000000, 21100000)
268
+ .as_file("transfers.csv")
297
269
  )
298
270
 
299
271
  # Save as JSON
300
272
  (
301
273
  client.erc20.transfers("USDT")
302
274
  .network("ETH")
303
- .start_block(24000000)
304
- .end_block(24100000)
275
+ .block_range(21000000, 21010000)
305
276
  .as_file("transfers.json")
306
277
  )
278
+ ```
307
279
 
308
- # Explicit format (when path has no extension)
309
- (
280
+ ### Return as Dictionary (JSON)
281
+
282
+ For small queries, you can get results as a list of dictionaries:
283
+
284
+ ```python
285
+ transfers = (
310
286
  client.erc20.transfers("USDT")
311
287
  .network("ETH")
312
- .start_block(24000000)
313
- .end_block(24100000)
314
- .as_file("transfers", format="csv")
288
+ .block_range(21000000, 21010000)
289
+ .as_dict()
315
290
  )
291
+
292
+ for transfer in transfers:
293
+ print(f"{transfer['sender']} -> {transfer['receiver']}: {transfer['amount']}")
316
294
  ```
317
295
 
296
+ > **Note:** `as_dict()` and `as_file("*.json")` use JSON format which has a **10,000 block limit**. For larger block ranges, use `as_df()` or `as_file()` with `.parquet` or `.csv` extensions, which support up to 1,000,000 blocks.
297
+
318
298
  ### Async Usage
319
299
 
320
300
  ```python
@@ -323,41 +303,17 @@ from defistream import AsyncDeFiStream
323
303
 
324
304
  async def main():
325
305
  async with AsyncDeFiStream() as client:
326
- transfers = await (
306
+ df = await (
327
307
  client.erc20.transfers("USDT")
328
308
  .network("ETH")
329
- .start_block(24000000)
330
- .end_block(24100000)
331
- .as_dict()
309
+ .block_range(21000000, 21010000)
310
+ .as_df()
332
311
  )
333
- print(f"Found {len(transfers)} transfers")
312
+ print(f"Found {len(df)} transfers")
334
313
 
335
314
  asyncio.run(main())
336
315
  ```
337
316
 
338
- ### Multiple Networks in Parallel
339
-
340
- ```python
341
- import asyncio
342
- from defistream import AsyncDeFiStream
343
-
344
- async def fetch_all_networks():
345
- async with AsyncDeFiStream() as client:
346
- networks = ["ETH", "ARB", "BASE", "OP"]
347
- tasks = [
348
- client.erc20.transfers("USDC")
349
- .network(net)
350
- .start_block(24000000)
351
- .end_block(24100000)
352
- .as_dict()
353
- for net in networks
354
- ]
355
- results = await asyncio.gather(*tasks)
356
- return dict(zip(networks, results))
357
-
358
- all_transfers = asyncio.run(fetch_all_networks())
359
- ```
360
-
361
317
  ## Configuration
362
318
 
363
319
  ### Environment Variables
@@ -402,12 +358,11 @@ from defistream.exceptions import (
402
358
  client = DeFiStream()
403
359
 
404
360
  try:
405
- transfers = (
361
+ df = (
406
362
  client.erc20.transfers("USDT")
407
363
  .network("ETH")
408
- .start_block(24000000)
409
- .end_block(24100000)
410
- .as_dict()
364
+ .block_range(21000000, 21010000)
365
+ .as_df()
411
366
  )
412
367
  except AuthenticationError:
413
368
  print("Invalid API key")
@@ -426,12 +381,11 @@ except DeFiStreamError as e:
426
381
  Access rate limit and quota information:
427
382
 
428
383
  ```python
429
- transfers = (
384
+ df = (
430
385
  client.erc20.transfers("USDT")
431
386
  .network("ETH")
432
- .start_block(24000000)
433
- .end_block(24100000)
434
- .as_dict()
387
+ .block_range(21000000, 21010000)
388
+ .as_df()
435
389
  )
436
390
 
437
391
  # Access response metadata
@@ -446,7 +400,7 @@ print(f"Request cost: {client.last_response.request_cost}")
446
400
 
447
401
  | Method | Description |
448
402
  |--------|-------------|
449
- | `.network(net)` | Set network (ETH, ARB, BASE, OP, etc.) |
403
+ | `.network(net)` | Set network (ETH, ARB, BASE, OP, POLYGON, etc.) |
450
404
  | `.start_block(n)` | Set starting block number |
451
405
  | `.end_block(n)` | Set ending block number |
452
406
  | `.block_range(start, end)` | Set both start and end blocks |
@@ -465,8 +419,6 @@ print(f"Request cost: {client.last_response.request_cost}")
465
419
  | `.to_address(addr)` | ERC20, Native | Alias for receiver |
466
420
  | `.min_amount(amt)` | ERC20, Native | Minimum transfer amount |
467
421
  | `.token(symbol)` | ERC20 | Token symbol (USDT, USDC, etc.) |
468
- | `.owner(addr)` | ERC20 Approvals, Lido | Filter by owner |
469
- | `.spender(addr)` | ERC20 Approvals | Filter by spender |
470
422
  | `.user(addr)` | AAVE | Filter by user |
471
423
  | `.reserve(addr)` | AAVE | Filter by reserve |
472
424
  | `.liquidator(addr)` | AAVE Liquidations | Filter by liquidator |
@@ -479,11 +431,11 @@ print(f"Request cost: {client.last_response.request_cost}")
479
431
 
480
432
  | Method | Description |
481
433
  |--------|-------------|
482
- | `.as_dict()` | Execute and return list of dicts (JSON) |
483
434
  | `.as_df()` | Execute and return pandas DataFrame |
484
435
  | `.as_df("polars")` | Execute and return polars DataFrame |
485
436
  | `.as_file(path)` | Execute and save to file (format from extension) |
486
437
  | `.as_file(path, format="csv")` | Execute and save with explicit format |
438
+ | `.as_dict()` | Execute and return list of dicts (JSON, 10K block limit) |
487
439
 
488
440
  ## License
489
441
 
@@ -1,11 +1,11 @@
1
- defistream/__init__.py,sha256=nXlmtbfyy4VrbZ8PRFzUW49R6DukTRZIxeeph_9k6UY,1827
1
+ defistream/__init__.py,sha256=h2xO5tLBCKGkCzw0DTG6g6aDSBZs2qd4oaKnCRLlJR8,1680
2
2
  defistream/client.py,sha256=Ku8ouDbM6Mx4lVmqvBwNvNt-h2FkvqauPMSjKyPkjU4,12717
3
3
  defistream/exceptions.py,sha256=_GxZQ18_YvXFtmNHeddWV8fHPIllHgFeP7fP0CmHF1k,1492
4
4
  defistream/models.py,sha256=JiG4IUq19HIANz9MHQCkaE6onGNyNzXcbdJmosrHsw0,3812
5
- defistream/protocols.py,sha256=b9zX0RUaw9mwZA-rPCPfpRisN5X-mdwmXSoTPYS-ius,11811
5
+ defistream/protocols.py,sha256=5_bYd46lDy-mK6LZ8sTGW0Z2IVH4g0cQ5rBbbOXsw0U,15368
6
6
  defistream/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  defistream/query.py,sha256=73vu8uXBdiFqGKoU0nDHDQ8emLnt1HVJMmvrl--Hzmg,17791
8
- defistream-1.0.0.dist-info/METADATA,sha256=m6_u2yhrLNNHnm8HthaDx0pYpGtENY-CO7bz-qQeh94,12079
9
- defistream-1.0.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
10
- defistream-1.0.0.dist-info/licenses/LICENSE,sha256=72DWAof8dMePfFQmfaswClW5d-sE6k7p-7VpuSKLmU4,1067
11
- defistream-1.0.0.dist-info/RECORD,,
8
+ defistream-1.0.1.dist-info/METADATA,sha256=2yl5LrW4c3sEHzORotGKqmn5FG50oicXUCgttApTn2M,10947
9
+ defistream-1.0.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
10
+ defistream-1.0.1.dist-info/licenses/LICENSE,sha256=72DWAof8dMePfFQmfaswClW5d-sE6k7p-7VpuSKLmU4,1067
11
+ defistream-1.0.1.dist-info/RECORD,,