cryptointerface 0.1.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 (35) hide show
  1. cryptointerface-0.1.0/.claude/.fuse_hidden000480fb000005da +12 -0
  2. cryptointerface-0.1.0/.claude/settings.local.json +15 -0
  3. cryptointerface-0.1.0/.gitignore +11 -0
  4. cryptointerface-0.1.0/.python-version +1 -0
  5. cryptointerface-0.1.0/PKG-INFO +354 -0
  6. cryptointerface-0.1.0/README.md +333 -0
  7. cryptointerface-0.1.0/cryptointerface/__init__.py +5 -0
  8. cryptointerface-0.1.0/cryptointerface/dex.py +892 -0
  9. cryptointerface-0.1.0/cryptointerface/flashloan.py +307 -0
  10. cryptointerface-0.1.0/cryptointerface/periphery/config.py +46 -0
  11. cryptointerface-0.1.0/cryptointerface/periphery/db.py +136 -0
  12. cryptointerface-0.1.0/cryptointerface/periphery/dex_architecture.json +119 -0
  13. cryptointerface-0.1.0/cryptointerface/periphery/dex_contracts.json +301 -0
  14. cryptointerface-0.1.0/cryptointerface/periphery/dex_contracts.py +56 -0
  15. cryptointerface-0.1.0/cryptointerface/periphery/enums.py +31 -0
  16. cryptointerface-0.1.0/cryptointerface/periphery/mapping.py +118 -0
  17. cryptointerface-0.1.0/cryptointerface/periphery/utils.py +6 -0
  18. cryptointerface-0.1.0/cryptointerface/providers/endpoints.json +25 -0
  19. cryptointerface-0.1.0/cryptointerface/providers/infura.py +36 -0
  20. cryptointerface-0.1.0/cryptointerface/routes.py +90 -0
  21. cryptointerface-0.1.0/cryptointerface/token.py +264 -0
  22. cryptointerface-0.1.0/cryptointerface/wallet.py +28 -0
  23. cryptointerface-0.1.0/helper.py +145 -0
  24. cryptointerface-0.1.0/main.py +50 -0
  25. cryptointerface-0.1.0/pools_v2.csv +2724 -0
  26. cryptointerface-0.1.0/pools_v3.csv +2724 -0
  27. cryptointerface-0.1.0/pyproject.toml +37 -0
  28. cryptointerface-0.1.0/requirements.txt +6 -0
  29. cryptointerface-0.1.0/test/conftest.py +27 -0
  30. cryptointerface-0.1.0/test/test_db.py +83 -0
  31. cryptointerface-0.1.0/test/test_dex.py +152 -0
  32. cryptointerface-0.1.0/test/test_token.py +145 -0
  33. cryptointerface-0.1.0/test/test_utils.py +32 -0
  34. cryptointerface-0.1.0/tokens.csv +2724 -0
  35. cryptointerface-0.1.0/uv.lock +1515 -0
@@ -0,0 +1,12 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python:*)",
5
+ "Bash(pip install:*)",
6
+ "Bash(uv run:*)",
7
+ "WebFetch(domain:chainlist.org)",
8
+ "WebFetch(domain:docs.metamask.io)",
9
+ "WebFetch(domain:raw.githubusercontent.com)"
10
+ ]
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python:*)",
5
+ "Bash(pip install:*)",
6
+ "Bash(uv run:*)",
7
+ "WebFetch(domain:chainlist.org)",
8
+ "WebFetch(domain:docs.metamask.io)",
9
+ "WebFetch(domain:raw.githubusercontent.com)",
10
+ "Bash(.venv/bin/python -c \"import web3\")",
11
+ "Bash(.venv/bin/python -m pytest test/test_dex.py -m \"not network\")",
12
+ "Bash(uv add:*)"
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,11 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ .env
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,354 @@
1
+ Metadata-Version: 2.4
2
+ Name: cryptointerface
3
+ Version: 0.1.0
4
+ Summary: Interface with cryptocurrency and DEX contracts. Store data locally for future use.
5
+ Project-URL: Source, https://github.com/William-Kruta/CryptoInterface
6
+ License: MIT
7
+ Keywords: aave,arbitrage,crypto,defi,dex,uniswap,web3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Topic :: Office/Business :: Financial
13
+ Requires-Python: >=3.12
14
+ Requires-Dist: duckdb>=1.5
15
+ Requires-Dist: polars>=1.0
16
+ Requires-Dist: pyarrow>=14.0
17
+ Requires-Dist: python-dotenv>=1.0
18
+ Requires-Dist: requests>=2.33
19
+ Requires-Dist: web3>=7.0
20
+ Description-Content-Type: text/markdown
21
+
22
+ # CryptoInterface
23
+
24
+ A Python library for interacting with EVM-compatible DEXes — price fetching, swapping.
25
+
26
+ I have provided some starter data to enter in your database.
27
+
28
+ To do this, just write this code:
29
+
30
+ ```
31
+ from cryptointerface.periphery.db import insert_tokens_csv_to_db, insert_pools_csv_to_db
32
+
33
+ insert_tokens_csv_to_db()
34
+ insert_pools_csv_to_db()
35
+ ```
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install cryptointerface
41
+ ```
42
+
43
+ Or with [uv](https://github.com/astral-sh/uv):
44
+
45
+ ```bash
46
+ uv add cryptointerface
47
+ ```
48
+
49
+ **Requirements:** Python 3.12+
50
+
51
+ ---
52
+
53
+ ## Quick Start
54
+
55
+ ```python
56
+ from cryptointerface import Dex, Token, Wallet, arbitrage_route
57
+ from cryptointerface.providers.infura import Infura
58
+ from cryptointerface.periphery.utils import to_wei, from_wei
59
+ from cryptointerface.periphery.enums import Network, Platform
60
+
61
+ infura = Infura(api_key="YOUR_INFURA_KEY")
62
+
63
+ # Look up a token
64
+ token = Token("WETH", chain_id=Network.ARBITRUM.value)
65
+ print(token.address, token.decimals)
66
+
67
+ # Fetch a price
68
+ dex = Dex("uniswap_v3", chain_id="42161", rpc_url=infura.get_url("42161"))
69
+ price = dex.get_price(weth_address, usdc_address)
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Core Modules
75
+
76
+ ### `Token` / `TokenInterface`
77
+
78
+ Resolves token metadata from a local DuckDB cache, downloading from CoinGecko on first use.
79
+
80
+ ```python
81
+ from cryptointerface import Token, TokenInterface
82
+
83
+ token = Token("USDC", chain_id="42161")
84
+ print(token.address) # checksummed address
85
+ print(token.decimals) # 6
86
+ print(token.info) # polars DataFrame
87
+
88
+ # Build an ERC-20 approve transaction (unsigned)
89
+ tx = token.approve(
90
+ spender_address="0xRouter...",
91
+ amount=to_wei(1000, decimals=6),
92
+ owner_address="0xYourWallet",
93
+ rpc_url="https://...",
94
+ )
95
+ ```
96
+
97
+ `TokenInterface` provides the lower-level DB methods (`get_token_info`, `get_token_address`, `get_token_decimals`, `batch_save`, `update_decimals`).
98
+
99
+ ---
100
+
101
+ ### `Dex` / `DexInterface`
102
+
103
+ Fetches pool addresses and prices, and builds swap transactions for all supported DEX protocols.
104
+
105
+ ```python
106
+ from cryptointerface import Dex
107
+
108
+ dex = Dex("uniswap_v3", chain_id="42161", rpc_url="https://...")
109
+
110
+ # Pool address (cached in DuckDB on first call)
111
+ pool = dex.pool_address(token_a_address, token_b_address)
112
+
113
+ # Spot price — token_a denominated in token_b
114
+ price = dex.get_price(token_a_address, token_b_address)
115
+
116
+ # Build an unsigned swap transaction
117
+ tx = dex.interface.swap(
118
+ token_in=token_a_address,
119
+ token_out=token_b_address,
120
+ amount_in=to_wei(1.0),
121
+ dex_name="uniswap_v3",
122
+ chain_id="42161",
123
+ sender="0xYourWallet",
124
+ )
125
+ ```
126
+
127
+ #### Supported DEXes
128
+
129
+ | Name | Protocol | Chains |
130
+ | ---------------- | --------------- | ---------------------------------------------------- |
131
+ | `uniswap_v2` | Uniswap V2 | Ethereum, Sepolia |
132
+ | `uniswap_v3` | Uniswap V3 | Ethereum, Arbitrum, Polygon, Optimism, Base, Sepolia |
133
+ | `sushiswap_v2` | Uniswap V2 fork | Ethereum, Arbitrum, Polygon, Sepolia |
134
+ | `sushiswap_v3` | Uniswap V3 fork | Ethereum, Arbitrum, Polygon, Sepolia |
135
+ | `pancakeswap_v2` | Uniswap V2 fork | BSC, Ethereum |
136
+ | `pancakeswap_v3` | Uniswap V3 fork | BSC, Ethereum |
137
+ | `quickswap_v2` | Uniswap V2 fork | Polygon |
138
+ | `quickswap_v3` | Algebra V3 | Polygon |
139
+ | `camelot_v2` | Uniswap V2 fork | Arbitrum |
140
+ | `camelot_v3` | Algebra V3 | Arbitrum |
141
+ | `traderjoe_v1` | Uniswap V2 fork | Avalanche, Arbitrum |
142
+ | `aerodrome` | Solidly V2 | Base |
143
+ | `velodrome` | Solidly V2 | Optimism |
144
+
145
+ #### Protocols
146
+
147
+ - **Uniswap V2** — `getPair` factory, fixed fee per DEX, `getReserves` pricing
148
+ - **Uniswap V3** — `getPool` factory, per-pool fee tiers, `sqrtPriceX96` pricing
149
+ - **Algebra V3** — `poolByPair` factory, dynamic fees, no fee argument (QuickSwap, Camelot V3)
150
+ - **Solidly V2** — `getPool(stable: bool)` factory, stable/volatile pools (Aerodrome, Velodrome)
151
+
152
+ #### `create_dex_mapping`
153
+
154
+ Build a multi-DEX dict for use with `get_prices` / `arbitrage_route`:
155
+
156
+ ```python
157
+ from cryptointerface.dex import create_dex_mapping
158
+
159
+ dex_mapping = create_dex_mapping(
160
+ dex_names=["uniswap_v3", "sushiswap_v3", "camelot_v3"],
161
+ chain_ids=["42161"],
162
+ infura_obj=infura,
163
+ )
164
+ ```
165
+
166
+ ---
167
+
168
+ ### `routes` — Prices & Arbitrage
169
+
170
+ ```python
171
+ from cryptointerface import get_prices, arbitrage_route
172
+
173
+ # Parallel price fetch across all DEXes
174
+ prices = get_prices(dex_mapping, token_a_address, token_b_address)
175
+ # {"uniswap_v3": {"price": 1823.4, "pool": "0x...", "fee_bps": 5}, ...}
176
+
177
+ # Arbitrage analysis
178
+ route = arbitrage_route(dex_mapping, token_a_address, token_b_address)
179
+ ```
180
+
181
+ `arbitrage_route` returns:
182
+
183
+ ```python
184
+ {
185
+ "buy": {"dex": "camelot_v3", "price": 1820.1, "pool": "0x...", "fee_bps": 5},
186
+ "sell": {"dex": "uniswap_v3", "price": 1825.8, "pool": "0x...", "fee_bps": 5},
187
+ "spread_abs": 5.7,
188
+ "spread_pct": 0.3132,
189
+ "total_fee_pct": 0.1, # both legs combined
190
+ "net_spread_pct": 0.2132, # spread after fees
191
+ "profitable": True,
192
+ "all_prices": {...},
193
+ }
194
+ ```
195
+
196
+ Fees are sourced from `dex_architecture.json` — V3 fee tiers use the matched pool tier; V2 uses the fixed DEX fee.
197
+
198
+ ---
199
+
200
+ ### `Wallet`
201
+
202
+ Signs and broadcasts unsigned transactions built by `Dex`, `Token`, or `AaveFlashLoan`.
203
+
204
+ ```python
205
+ from cryptointerface import Wallet
206
+
207
+ wallet = Wallet(private_key="0x...", rpc_url="https://...")
208
+
209
+ tx_hash = wallet.sign_and_send(tx) # auto-fills nonce, gas, gasPrice
210
+ receipt = wallet.wait(tx_hash) # blocks until mined
211
+ ```
212
+
213
+ ---
214
+
215
+ ### `AaveFlashLoan`
216
+
217
+ Builds Aave V3 flash loan transactions. Supported chains: Ethereum, Optimism, BSC, Polygon, Base, Arbitrum, Avalanche, Sepolia.
218
+
219
+ Flash loan fee: **0.09%** (9 bps).
220
+
221
+ ```python
222
+ from cryptointerface import AaveFlashLoan
223
+ from cryptointerface.periphery.utils import to_wei
224
+
225
+ fl = AaveFlashLoan(chain_id="42161", rpc_url="https://...")
226
+
227
+ # Single-asset flash loan (lower gas)
228
+ tx = fl.flash_loan_simple_tx(
229
+ receiver_contract="0xYourDeployedExecutor",
230
+ asset=usdc_address,
231
+ amount=to_wei(10_000, decimals=6),
232
+ sender=wallet.address,
233
+ )
234
+ tx_hash = wallet.sign_and_send(tx)
235
+
236
+ # Multi-asset flash loan
237
+ tx = fl.flash_loan_tx(
238
+ receiver_contract="0xYourDeployedExecutor",
239
+ assets=[weth_address, usdc_address],
240
+ amounts=[to_wei(5.0), to_wei(10_000, decimals=6)],
241
+ sender=wallet.address,
242
+ )
243
+
244
+ # Check profitability after the flash loan fee
245
+ result = AaveFlashLoan.net_profit(
246
+ amount=to_wei(10_000, decimals=6),
247
+ gross_profit_wei=to_wei(15, decimals=6),
248
+ token_decimals=6,
249
+ )
250
+ # {"fee_wei": 9000, "net_profit_wei": 6000, "net_profit_human": 0.006, "is_profitable": True}
251
+ ```
252
+
253
+ #### Solidity Executor Contract
254
+
255
+ The flash loan callback (`executeOperation`) must be implemented in Solidity. A full template is available as:
256
+
257
+ ```python
258
+ print(AaveFlashLoan.EXECUTOR_TEMPLATE)
259
+ ```
260
+
261
+ Deploy this contract once, paste your swap logic inside `executeOperation`, then pass its address as `receiver_contract`.
262
+
263
+ ---
264
+
265
+ ### `Infura`
266
+
267
+ RPC URL builder for Infura endpoints.
268
+
269
+ ```python
270
+ from cryptointerface.providers.infura import Infura
271
+
272
+ infura = Infura(api_key="YOUR_KEY")
273
+ rpc_url = infura.get_url("42161") # Arbitrum
274
+
275
+ # Add a custom endpoint
276
+ infura.add_endpoint(chain_id="10", endpoint="https://optimism-mainnet.infura.io/v3/")
277
+ ```
278
+
279
+ ---
280
+
281
+ ## Local Database (DuckDB)
282
+
283
+ Token and pool data is cached locally in a DuckDB file (`~/.cryptointerface/data.db` by default). All reads/writes are thread-safe via thread-local connections and a write lock.
284
+
285
+ ### Schema
286
+
287
+ **`tokens`** — `symbol`, `chain_id`, `address`, `decimals`
288
+
289
+ **`pools_v2`** — `dex`, `chain_id`, `token_0`, `token_1`, `address`
290
+
291
+ **`pools_v3`** — `dex`, `chain_id`, `token_0`, `token_1`, `fee`, `address`
292
+
293
+ ### CSV Import / Export
294
+
295
+ ```python
296
+ from cryptointerface.periphery.db import (
297
+ export_tokens_to_csv,
298
+ export_pools_to_csv,
299
+ insert_tokens_csv_to_db,
300
+ insert_pools_csv_to_db,
301
+ )
302
+
303
+ export_tokens_to_csv("tokens.csv")
304
+ export_pools_to_csv("pools_v2.csv", "pools_v3.csv")
305
+
306
+ insert_tokens_csv_to_db("tokens.csv")
307
+ insert_pools_csv_to_db("pools_v2.csv", "pools_v3.csv")
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Utilities
313
+
314
+ ```python
315
+ from cryptointerface.periphery.utils import to_wei, from_wei
316
+
317
+ to_wei(1.5, decimals=18) # 1500000000000000000
318
+ from_wei(1_000_000, decimals=6) # 1.0
319
+ ```
320
+
321
+ ### Enums
322
+
323
+ ```python
324
+ from cryptointerface.periphery.enums import Network, Platform
325
+
326
+ Network.ARBITRUM.value # "42161"
327
+ Platform.UNISWAP_V3.value # "uniswap_v3"
328
+ ```
329
+
330
+ **Networks:** `ETHEREUM`, `OPTIMISM`, `BSC`, `POLYGON`, `BASE`, `ARBITRUM`, `CELO`, `AVALANCHE`, `BLAST`, `ZORA`, `SEPOLIA`
331
+
332
+ **Platforms:** `UNISWAP_V2`, `UNISWAP_V3`, `SUSHISWAP_V2`, `SUSHISWAP_V3`, `PANCAKESWAP_V2`, `PANCAKESWAP_V3`, `QUICKSWAP_V2`, `QUICKSWAP_V3`, `CAMELOT_V2`, `CAMELOT_V3`, `TRADERJOE_V1`, `AERODROME`, `VELODROME`
333
+
334
+ ---
335
+
336
+ ## Running Tests
337
+
338
+ ```bash
339
+ uv run pytest
340
+ ```
341
+
342
+ Network tests (require a live RPC) are skipped by default unless `SEPOLIA_RPC_URL` is set in your environment.
343
+
344
+ ---
345
+
346
+ ## Dependencies
347
+
348
+ | Package | Purpose |
349
+ | --------------- | ---------------------------- |
350
+ | `web3` | EVM RPC interaction |
351
+ | `duckdb` | Local persistent storage |
352
+ | `polars` | DataFrame operations |
353
+ | `requests` | CoinGecko API calls |
354
+ | `python-dotenv` | Environment variable loading |