cryptointerface 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.
- cryptointerface/__init__.py +5 -0
- cryptointerface/dex.py +892 -0
- cryptointerface/flashloan.py +307 -0
- cryptointerface/periphery/config.py +46 -0
- cryptointerface/periphery/db.py +136 -0
- cryptointerface/periphery/dex_architecture.json +119 -0
- cryptointerface/periphery/dex_contracts.json +301 -0
- cryptointerface/periphery/dex_contracts.py +56 -0
- cryptointerface/periphery/enums.py +31 -0
- cryptointerface/periphery/mapping.py +118 -0
- cryptointerface/periphery/utils.py +6 -0
- cryptointerface/providers/endpoints.json +25 -0
- cryptointerface/providers/infura.py +36 -0
- cryptointerface/routes.py +90 -0
- cryptointerface/token.py +264 -0
- cryptointerface/wallet.py +28 -0
- cryptointerface-0.1.0.dist-info/METADATA +354 -0
- cryptointerface-0.1.0.dist-info/RECORD +19 -0
- cryptointerface-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
{
|
|
2
|
+
"uniswap_v2": {
|
|
3
|
+
"1": {
|
|
4
|
+
"factory": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
|
|
5
|
+
"router": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"
|
|
6
|
+
},
|
|
7
|
+
"10": {
|
|
8
|
+
"factory": "0x0c3c1c532F1e39EdF36BE9Fe0bE1410313E074Bf",
|
|
9
|
+
"router": "0x4a7b5da61326a6379179b40d00f57e5bbdc962c2"
|
|
10
|
+
},
|
|
11
|
+
"56": {
|
|
12
|
+
"factory": "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6",
|
|
13
|
+
"router": "0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24"
|
|
14
|
+
},
|
|
15
|
+
"137": {
|
|
16
|
+
"factory": "0x9e5A52f57b3038F1B8EeE45F28b3C1967e22799C",
|
|
17
|
+
"router": "0xedf6066a2b290c185783862c7f4776a2c8077ad1"
|
|
18
|
+
},
|
|
19
|
+
"8453": {
|
|
20
|
+
"factory": "0x8909dc15e40173ff4699343b6eb8132c65e18ec6",
|
|
21
|
+
"router": "0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24"
|
|
22
|
+
},
|
|
23
|
+
"42161": {
|
|
24
|
+
"factory": "0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9",
|
|
25
|
+
"router": "0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24"
|
|
26
|
+
},
|
|
27
|
+
"42220": {
|
|
28
|
+
"factory": "0x79a530c8e2fA8748B7B40dd3629C0520c2cCf03f",
|
|
29
|
+
"router": null
|
|
30
|
+
},
|
|
31
|
+
"43114": {
|
|
32
|
+
"factory": "0x9e5A52f57b3038F1B8EeE45F28b3C1967e22799C",
|
|
33
|
+
"router": "0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24"
|
|
34
|
+
},
|
|
35
|
+
"81457": {
|
|
36
|
+
"factory": "0x5C346464d33F90bABaf70dB6388507CC889C1070",
|
|
37
|
+
"router": "0xBB66Eb1c5e875933D44DAe661dbD80e5D9B03035"
|
|
38
|
+
},
|
|
39
|
+
"11155111": {
|
|
40
|
+
"factory": "0xF62c03E08ada871A0bEb309762E260a7a6a880E6",
|
|
41
|
+
"router": "0xeE567Fe1712Faf6149d80dA1E6934E354124CfE3"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"uniswap_v3": {
|
|
45
|
+
"1": {
|
|
46
|
+
"factory": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
47
|
+
"router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
48
|
+
"quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
|
|
49
|
+
"position_manager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
50
|
+
"migrator": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
|
|
51
|
+
},
|
|
52
|
+
"10": {
|
|
53
|
+
"factory": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
54
|
+
"router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
55
|
+
"quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
|
|
56
|
+
"position_manager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
57
|
+
"migrator": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
|
|
58
|
+
},
|
|
59
|
+
"30": {
|
|
60
|
+
"factory": "0xaF37EC98A00FD63689CF3060BF3B6784E00caD82",
|
|
61
|
+
"router": "0xFB7eF66a7e61224DD6FcD0D7d9C3be5C8B049b9f",
|
|
62
|
+
"quoter": "0xb5227F20f7c33A3f53E72E22f28bE7FAa01b7E6C",
|
|
63
|
+
"position_manager": "0x9d9386c042F194B460Ec424a1e57ACDE25f5C4b1",
|
|
64
|
+
"migrator": null
|
|
65
|
+
},
|
|
66
|
+
"56": {
|
|
67
|
+
"factory": "0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7",
|
|
68
|
+
"router": "0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",
|
|
69
|
+
"quoter": "0x78D78E420Da98ad378D7799bE8f4AF69033EB077",
|
|
70
|
+
"position_manager": "0x7b8A01B39D58278b5DE7e48c8449c9f4F5170613",
|
|
71
|
+
"migrator": "0x32681814957e0C13117ddc0c2aba232b5c9e760f"
|
|
72
|
+
},
|
|
73
|
+
"137": {
|
|
74
|
+
"factory": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
75
|
+
"router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
76
|
+
"quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
|
|
77
|
+
"position_manager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
78
|
+
"migrator": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
|
|
79
|
+
},
|
|
80
|
+
"8453": {
|
|
81
|
+
"factory": "0x33128a8fC17869897dcE68Ed026d694621f6FDfD",
|
|
82
|
+
"router": "0x2626664c2603336E57B271c5C0b26F421741e481",
|
|
83
|
+
"quoter": "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",
|
|
84
|
+
"position_manager": "0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1",
|
|
85
|
+
"migrator": "0x23cF10b1ee3AdfCA73B0eF17C07F7577e7ACd2d7"
|
|
86
|
+
},
|
|
87
|
+
"42161": {
|
|
88
|
+
"factory": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
89
|
+
"router": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
90
|
+
"quoter": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
|
|
91
|
+
"position_manager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
92
|
+
"migrator": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
|
|
93
|
+
},
|
|
94
|
+
"43114": {
|
|
95
|
+
"factory": "0x740b1c1de25031C31FF4fC9A62f554A55cdC1baD",
|
|
96
|
+
"router": "0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",
|
|
97
|
+
"quoter": "0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",
|
|
98
|
+
"position_manager": "0x655C406EBFa14EE2006250925e54ec43AD184f8B",
|
|
99
|
+
"migrator": "0x44f5f1f5E452ea8d29C890E8F6e893fC0f1f0f97"
|
|
100
|
+
},
|
|
101
|
+
"81457": {
|
|
102
|
+
"factory": "0x792edAdE80af5fC680d96a2eD80A44247D2Cf6Fd",
|
|
103
|
+
"router": "0x549FEB8c9bd4c12Ad2AB27022dA12492aC452B66",
|
|
104
|
+
"quoter": "0x6Cdcd65e03c1CEc3730AeeCd45bc140D57A25C77",
|
|
105
|
+
"position_manager": "0xB218e4f7cF0533d4696fDfC419A0023D33345F28",
|
|
106
|
+
"migrator": "0x15CA7043CD84C5D21Ae76Ba0A1A967d42c40ecE0"
|
|
107
|
+
},
|
|
108
|
+
"7777777": {
|
|
109
|
+
"factory": "0x7145F8aeef1f6510E92164038E1B6F8cB2c42Cbb",
|
|
110
|
+
"router": "0x7De04c96BE5159c3b5CeffC82aa176dc81281557",
|
|
111
|
+
"quoter": "0x11867e1b3348F3ce4FcC170BC5af3d23E07E64Df",
|
|
112
|
+
"position_manager": "0xbC91e8DfA3fF18De43853372A3d7dfe585137D78",
|
|
113
|
+
"migrator": null
|
|
114
|
+
},
|
|
115
|
+
"11155111": {
|
|
116
|
+
"factory": "0x0227628f3F023bb0B980b67D528571c95c6DaC1c",
|
|
117
|
+
"router": "0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E",
|
|
118
|
+
"quoter": "0xEd1f6473345F45b75833fd55D191EaA8F5C33CD4",
|
|
119
|
+
"position_manager": "0x1238536071E1c677A632429e3655c799b22cDA52",
|
|
120
|
+
"migrator": null
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"sushiswap_v2": {
|
|
124
|
+
"1": {
|
|
125
|
+
"factory": "0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac",
|
|
126
|
+
"router": "0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F"
|
|
127
|
+
},
|
|
128
|
+
"10": {
|
|
129
|
+
"factory": "0xFbc12984689e5f15626Bad03Ad60160Fe98B303C",
|
|
130
|
+
"router": "0xa132DAB612dB5cB9fC9Ac426A0Cc215A3423F9c9"
|
|
131
|
+
},
|
|
132
|
+
"56": {
|
|
133
|
+
"factory": "0xc35DADB65012eC5796536bD9864eD8773aBc74C4",
|
|
134
|
+
"router": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506"
|
|
135
|
+
},
|
|
136
|
+
"137": {
|
|
137
|
+
"factory": "0xc35DADB65012eC5796536bD9864eD8773aBc74C4",
|
|
138
|
+
"router": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506"
|
|
139
|
+
},
|
|
140
|
+
"8453": {
|
|
141
|
+
"factory": "0x71524B4f93c58fcbF659783284E38825f0622859",
|
|
142
|
+
"router": "0x6BDED42c6DA8FBf0d2bA55B2fa120C5e0c8D7891"
|
|
143
|
+
},
|
|
144
|
+
"42161": {
|
|
145
|
+
"factory": "0xc35DADB65012eC5796536bD9864eD8773aBc74C4",
|
|
146
|
+
"router": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506"
|
|
147
|
+
},
|
|
148
|
+
"43114": {
|
|
149
|
+
"factory": "0xc35DADB65012eC5796536bD9864eD8773aBc74C4",
|
|
150
|
+
"router": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506"
|
|
151
|
+
},
|
|
152
|
+
"11155111": {
|
|
153
|
+
"factory": "0x734583f62Bb6ACe3c9bA9bd5A53143CA2Ce8C55A",
|
|
154
|
+
"router": "0xeaBcE3E74EF41FB40024a21Cc2ee2F5dDc615791"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"sushiswap_v3": {
|
|
158
|
+
"1": {
|
|
159
|
+
"factory": "0xbACEB8eC6b9355Dfc0269C18bac9d6E2Bdc29C4F",
|
|
160
|
+
"router": "0x2c9a4Dc517f4Cb3E8dd1f4A78d0C6Fb793BC001",
|
|
161
|
+
"quoter": "0x64e8802FE490fa7cc61d3463958199161Bb608A7",
|
|
162
|
+
"position_manager": "0x2214A42d8e2A1d20635c2cb0664422c528B6A432"
|
|
163
|
+
},
|
|
164
|
+
"10": {
|
|
165
|
+
"factory": "0x9c6522117e2ed1fE5bdb72bb0eD5E3f2bdE7DBe0",
|
|
166
|
+
"router": "0xYourRouter",
|
|
167
|
+
"quoter": "0xYourQuoter",
|
|
168
|
+
"position_manager": "0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e"
|
|
169
|
+
},
|
|
170
|
+
"56": {
|
|
171
|
+
"factory": "0x126555aa41B33402279070107F2393494E74110",
|
|
172
|
+
"router": "0x0a6e511Fe663827b9cA7e2D2542b20B37fC217A6",
|
|
173
|
+
"quoter": "0xb1E835Dc2785b52265711e17fCCb0fd018226a6e",
|
|
174
|
+
"position_manager": "0xF70c086618dcf2b1A461311275e00D6B722ef914"
|
|
175
|
+
},
|
|
176
|
+
"137": {
|
|
177
|
+
"factory": "0x917933899c6a5F8E37F31E19f92CdBFF7e8FF0e2",
|
|
178
|
+
"router": "0x0a6e511Fe663827b9cA7e2D2542b20B37fC217A6",
|
|
179
|
+
"quoter": "0xb1E835Dc2785b52265711e17fCCb0fd018226a6e",
|
|
180
|
+
"position_manager": "0xb7402ee99F0A008e461098AC3A27F4957Df89a40"
|
|
181
|
+
},
|
|
182
|
+
"8453": {
|
|
183
|
+
"factory": "0xc35DADB65012eC5796536bD9864eD8773aBc74C4",
|
|
184
|
+
"router": "0x0a6e511Fe663827b9cA7e2D2542b20B37fC217A6",
|
|
185
|
+
"quoter": "0xb1E835Dc2785b52265711e17fCCb0fd018226a6e",
|
|
186
|
+
"position_manager": "0x80C7DD17B01855a6D2347444a0FCC36136a314de"
|
|
187
|
+
},
|
|
188
|
+
"42161": {
|
|
189
|
+
"factory": "0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e",
|
|
190
|
+
"router": "0x0a6e511Fe663827b9cA7e2D2542b20B37fC217A6",
|
|
191
|
+
"quoter": "0xb1E835Dc2785b52265711e17fCCb0fd018226a6e",
|
|
192
|
+
"position_manager": "0x717b7948AA264DeCf4D780aa6914482e5F46Da3e"
|
|
193
|
+
},
|
|
194
|
+
"43114": {
|
|
195
|
+
"factory": "0x3e603C14aF37EBdaD31709C4f848Fc6aD5BEc715",
|
|
196
|
+
"router": "0x0a6e511Fe663827b9cA7e2D2542b20B37fC217A6",
|
|
197
|
+
"quoter": "0xb1E835Dc2785b52265711e17fCCb0fd018226a6e",
|
|
198
|
+
"position_manager": "0x18350b048AB366ed601f5AF36a0E4a4F63EFbBEd"
|
|
199
|
+
},
|
|
200
|
+
"11155111": {
|
|
201
|
+
"factory": "0x1f2FCf1d036b375b384012e61D3AA33F8C256bbE",
|
|
202
|
+
"router": "0x93c31c9C729A249b2877F7699e178F4720407733",
|
|
203
|
+
"quoter": "0x039e87AB90205F9d87c5b40d4B28e2Be45dA4a20",
|
|
204
|
+
"position_manager": "0x6CE4e3489aA4Ae7B7CcE1719De0Ef7F1c94eDC02"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"pancakeswap_v2": {
|
|
208
|
+
"1": {
|
|
209
|
+
"factory": "0x1097053Fd2ea711dad45caCcc45EfF7548fCB362",
|
|
210
|
+
"router": "0xEfF92A263d31888d860bD50809A8D171709b7b1c"
|
|
211
|
+
},
|
|
212
|
+
"56": {
|
|
213
|
+
"factory": "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73",
|
|
214
|
+
"router": "0x10ED43C718714eb63d5aA57B78B54704E256024E"
|
|
215
|
+
},
|
|
216
|
+
"8453": {
|
|
217
|
+
"factory": "0x02a84c1b3BBD7401a5f7a18a8bE6a2A4bFC99cce",
|
|
218
|
+
"router": "0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb"
|
|
219
|
+
},
|
|
220
|
+
"42161": {
|
|
221
|
+
"factory": "0x02a84c1b3BBD7401a5f7a18a8bE6a2A4bFC99cce",
|
|
222
|
+
"router": "0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"pancakeswap_v3": {
|
|
226
|
+
"1": {
|
|
227
|
+
"factory": "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
228
|
+
"router": "0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",
|
|
229
|
+
"quoter": "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",
|
|
230
|
+
"position_manager": "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364"
|
|
231
|
+
},
|
|
232
|
+
"56": {
|
|
233
|
+
"factory": "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
234
|
+
"router": "0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",
|
|
235
|
+
"quoter": "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",
|
|
236
|
+
"position_manager": "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364"
|
|
237
|
+
},
|
|
238
|
+
"8453": {
|
|
239
|
+
"factory": "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
240
|
+
"router": "0x678Aa4bF4E210cf2166753e054d5b7c31cc7fa86",
|
|
241
|
+
"quoter": "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",
|
|
242
|
+
"position_manager": "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364"
|
|
243
|
+
},
|
|
244
|
+
"42161": {
|
|
245
|
+
"factory": "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
246
|
+
"router": "0x32226588378236Fd0c7c4053999F88aC0e5cAC77",
|
|
247
|
+
"quoter": "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",
|
|
248
|
+
"position_manager": "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364"
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
"quickswap_v2": {
|
|
252
|
+
"137": {
|
|
253
|
+
"factory": "0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32",
|
|
254
|
+
"router": "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"quickswap_v3": {
|
|
258
|
+
"137": {
|
|
259
|
+
"factory": "0x411b0fAcC3489691f28ad58c47006AF5E3Ab3A28",
|
|
260
|
+
"router": "0xf5b509bB0909a69B1c207E495f687a596C168E12",
|
|
261
|
+
"quoter": "0xa15F0D7377B2A0C0c10db057f641beD21028FC89",
|
|
262
|
+
"position_manager": "0x8eF88E4c7CfbbaC1C163f7eddd4B578792201de6"
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"camelot_v2": {
|
|
266
|
+
"42161": {
|
|
267
|
+
"factory": "0x6EcCab422D763aC031210895C81787E87B43A652",
|
|
268
|
+
"router": "0xc873fEcbd354f5A56E00E710B90EF4201db2448d"
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
"camelot_v3": {
|
|
272
|
+
"42161": {
|
|
273
|
+
"factory": "0x1a3c9B1d2F0529D97f2afC5136Cc23e58f1FD35d",
|
|
274
|
+
"router": "0x1F721E2E82F6676FCE4eA07A5958cF098D339e18",
|
|
275
|
+
"quoter": "0x0Fc73040b26E9bC8514fA028D998E73EB6D47088",
|
|
276
|
+
"position_manager": "0x00c7f3082833e796A5b3e4Bd59f6642FF44DCD15"
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
"traderjoe_v1": {
|
|
280
|
+
"43114": {
|
|
281
|
+
"factory": "0x9Ad6C38BE94206cA50bb0d90783181662f0Cfa10",
|
|
282
|
+
"router": "0x60aE616a2155Ee3d9A68541Ba4544862310933d4"
|
|
283
|
+
},
|
|
284
|
+
"42161": {
|
|
285
|
+
"factory": "0xaE4EC9901c3076D0DdBe76A520F9E90a6227aCB7",
|
|
286
|
+
"router": "0xbeE5c10Cf6E4F68f831E11C1D9E59B43560B3642"
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"aerodrome": {
|
|
290
|
+
"8453": {
|
|
291
|
+
"factory": "0x420DD381b31aEf6683db6B902084cB0FFECe40Da",
|
|
292
|
+
"router": "0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43"
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
"velodrome": {
|
|
296
|
+
"10": {
|
|
297
|
+
"factory": "0x25CbdDb98b35ab1FF77413456B31EC81A6B6B746",
|
|
298
|
+
"router": "0xa062aE8A9c5e11aaA026fc2670B0D65cCc8B2858"
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
_JSON_PATH = Path(__file__).parent / "dex_contracts.json"
|
|
5
|
+
_ARCH_PATH = Path(__file__).parent / "dex_architecture.json"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _load() -> dict:
|
|
9
|
+
with open(_JSON_PATH, "r") as f:
|
|
10
|
+
return json.load(f)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _load_architecture() -> dict:
|
|
14
|
+
with open(_ARCH_PATH, "r") as f:
|
|
15
|
+
return json.load(f)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_dex_architecture(dex_name: str) -> dict | None:
|
|
19
|
+
return _load_architecture().get(dex_name)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _save(data: dict) -> None:
|
|
23
|
+
with open(_JSON_PATH, "w") as f:
|
|
24
|
+
json.dump(data, f, indent=4)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_dex_contracts(dex: str, chain_id: int) -> dict[str, str] | None:
|
|
28
|
+
"""Return the contract addresses for a given DEX and chain ID, or None if unsupported."""
|
|
29
|
+
return _load().get(dex, {}).get(str(chain_id))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_supported_dexes() -> list[str]:
|
|
33
|
+
return list(_load().keys())
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_supported_chains(dex: str) -> list[int]:
|
|
37
|
+
return [int(k) for k in _load().get(dex, {}).keys()]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def add_dex_entry(dex: str, chain_id: int, contracts: dict[str, str | None]) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Add or update a chain entry for a DEX. Changes are written to dex_contracts.json.
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
add_dex_entry("sushiswap_v3", 1, {
|
|
46
|
+
"factory": "0xbACEB8eC6b9355Dfc0269C18bac9d6E2Bdc29C4F",
|
|
47
|
+
"router": "0x...",
|
|
48
|
+
"quoter": "0x...",
|
|
49
|
+
"position_manager": "0x...",
|
|
50
|
+
})
|
|
51
|
+
"""
|
|
52
|
+
data = _load()
|
|
53
|
+
if dex not in data:
|
|
54
|
+
data[dex] = {}
|
|
55
|
+
data[dex][str(chain_id)] = contracts
|
|
56
|
+
_save(data)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Network(Enum):
|
|
5
|
+
ETHEREUM = "1"
|
|
6
|
+
OPTIMISM = "10"
|
|
7
|
+
BSC = "56"
|
|
8
|
+
POLYGON = "137"
|
|
9
|
+
BASE = "8453"
|
|
10
|
+
ARBITRUM = "42161"
|
|
11
|
+
CELO = "42220"
|
|
12
|
+
AVALANCHE = "43114"
|
|
13
|
+
BLAST = "81457"
|
|
14
|
+
ZORA = "7777777"
|
|
15
|
+
SEPOLIA = "11155111"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Platform(Enum):
|
|
19
|
+
UNISWAP_V2 = "uniswap_v2"
|
|
20
|
+
UNISWAP_V3 = "uniswap_v3"
|
|
21
|
+
SUSHISWAP_V2 = "sushiswap_v2"
|
|
22
|
+
SUSHISWAP_V3 = "sushiswap_v3"
|
|
23
|
+
PANCAKESWAP_V2 = "pancakeswap_v2"
|
|
24
|
+
PANCAKESWAP_V3 = "pancakeswap_v3"
|
|
25
|
+
QUICKSWAP_V2 = "quickswap_v2"
|
|
26
|
+
QUICKSWAP_V3 = "quickswap_v3"
|
|
27
|
+
CAMELOT_V2 = "camelot_v2"
|
|
28
|
+
CAMELOT_V3 = "camelot_v3"
|
|
29
|
+
TRADERJOE_V1 = "traderjoe_v1"
|
|
30
|
+
AERODROME = "aerodrome"
|
|
31
|
+
VELODROME = "velodrome"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Maps CoinGecko platform/network slugs to EVM chain IDs.
|
|
2
|
+
# Non-EVM chains (Cosmos, Aptos, NEAR, Tron, etc.) are mapped to None.
|
|
3
|
+
COINGECKO_CHAIN_IDS: dict[str, int | None] = {
|
|
4
|
+
"ethereum": 1,
|
|
5
|
+
"arbitrum-one": 42161,
|
|
6
|
+
"arbitrum-nova": 42170,
|
|
7
|
+
"avalanche": 43114,
|
|
8
|
+
"binance-smart-chain": 56,
|
|
9
|
+
"polygon-pos": 137,
|
|
10
|
+
"polygon-zkevm": 1101,
|
|
11
|
+
"optimistic-ethereum": 10,
|
|
12
|
+
"base": 8453,
|
|
13
|
+
"blast": 81457,
|
|
14
|
+
"linea": 59144,
|
|
15
|
+
"mantle": 5000,
|
|
16
|
+
"zksync": 324,
|
|
17
|
+
"scroll": 534352,
|
|
18
|
+
"taiko": 167000,
|
|
19
|
+
"mode": 34443,
|
|
20
|
+
"zora-network": 7777777,
|
|
21
|
+
"metis-andromeda": 1088,
|
|
22
|
+
"fantom": 250,
|
|
23
|
+
"celo": 42220,
|
|
24
|
+
"moonbeam": 1284,
|
|
25
|
+
"moonriver": 1285,
|
|
26
|
+
"aurora": 1313161554,
|
|
27
|
+
"xdai": 100, # Gnosis Chain
|
|
28
|
+
"fuse": 122,
|
|
29
|
+
"cronos": 25,
|
|
30
|
+
"kava": 2222,
|
|
31
|
+
"conflux": 1030, # Conflux eSpace
|
|
32
|
+
"core": 1116,
|
|
33
|
+
"astar": 592,
|
|
34
|
+
"filecoin": 314,
|
|
35
|
+
"flare-network": 14,
|
|
36
|
+
"rootstock": 30,
|
|
37
|
+
"elastos": 20,
|
|
38
|
+
"telos": 40,
|
|
39
|
+
"meter": 82,
|
|
40
|
+
"tomochain": 88,
|
|
41
|
+
"kucoin-community-chain": 321,
|
|
42
|
+
"klay-token": 8217,
|
|
43
|
+
"theta": 361,
|
|
44
|
+
"velas": 106,
|
|
45
|
+
"energi": 39797,
|
|
46
|
+
"hedera-hashgraph": 295,
|
|
47
|
+
"xdc-network": 50,
|
|
48
|
+
"pulsechain": 369,
|
|
49
|
+
"ronin": 2020,
|
|
50
|
+
"x-layer": 196,
|
|
51
|
+
"manta-pacific": 169,
|
|
52
|
+
"lisk": 1135,
|
|
53
|
+
"mint": 185,
|
|
54
|
+
"sonic": 146,
|
|
55
|
+
"berachain": 80094,
|
|
56
|
+
"unichain": 130,
|
|
57
|
+
"soneium": 1868,
|
|
58
|
+
"swellchain": 1923,
|
|
59
|
+
"ink": 57073,
|
|
60
|
+
"abstract": 2741,
|
|
61
|
+
"world-chain": 480,
|
|
62
|
+
"zircuit": 48900,
|
|
63
|
+
"bob-network": 60808,
|
|
64
|
+
"morph-l2": 2818,
|
|
65
|
+
"hemi": 43111,
|
|
66
|
+
"funki": 33979,
|
|
67
|
+
"etherlink": 42793,
|
|
68
|
+
"sei-v2": 1329,
|
|
69
|
+
"apechain": 33139,
|
|
70
|
+
"degen": 666666666,
|
|
71
|
+
"iota-evm": 8822,
|
|
72
|
+
"peaq": 3338,
|
|
73
|
+
"flow-evm": 747,
|
|
74
|
+
"gravity-alpha": 1625,
|
|
75
|
+
"story": 1516,
|
|
76
|
+
"botanix": 3636,
|
|
77
|
+
"superseed": 5330,
|
|
78
|
+
"zero-network": 543210,
|
|
79
|
+
"milkomeda-cardano": 2001,
|
|
80
|
+
"pundi-aifx-omnilayer": 530,
|
|
81
|
+
"kardiachain": 24,
|
|
82
|
+
"cube": 1818,
|
|
83
|
+
"graphlinq-chain": 614,
|
|
84
|
+
"plume-network": 98866,
|
|
85
|
+
"nibiru": 6900,
|
|
86
|
+
"goat": 2345,
|
|
87
|
+
"plasma": 9745,
|
|
88
|
+
"0g": 16600,
|
|
89
|
+
"Superposition": 55244,
|
|
90
|
+
"monad": 143,
|
|
91
|
+
"megaeth": 6342,
|
|
92
|
+
"somnia": 50312,
|
|
93
|
+
"sepolia": 11155111,
|
|
94
|
+
# Non-EVM chains — no chain ID
|
|
95
|
+
"cosmos": None,
|
|
96
|
+
"aptos": None,
|
|
97
|
+
"near-protocol": None,
|
|
98
|
+
"tron": None,
|
|
99
|
+
"terra-2": None,
|
|
100
|
+
"massa": None,
|
|
101
|
+
"sora": None,
|
|
102
|
+
"solana": "solana:mainnet",
|
|
103
|
+
"glue": None,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_chain_id_by_name(network_name: str) -> int | None:
|
|
108
|
+
try:
|
|
109
|
+
return COINGECKO_CHAIN_IDS[network_name]
|
|
110
|
+
except KeyError:
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_network_name_by_chain_id(chain_id: int) -> str | None:
|
|
115
|
+
for name, cid in COINGECKO_CHAIN_IDS.items():
|
|
116
|
+
if cid == chain_id:
|
|
117
|
+
return name
|
|
118
|
+
return None
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"infura": {
|
|
3
|
+
"1": "https://mainnet.infura.io/v3/",
|
|
4
|
+
"10": "https://optimism-mainnet.infura.io/v3/",
|
|
5
|
+
"56": "https://bsc-mainnet.infura.io/v3/",
|
|
6
|
+
"130": "https://unichain-mainnet.infura.io/v3/",
|
|
7
|
+
"137": "https://polygon-mainnet.infura.io/v3/",
|
|
8
|
+
"143": "https://monad-mainnet.infura.io/v3/",
|
|
9
|
+
"204": "https://opbnb-mainnet.infura.io/v3/",
|
|
10
|
+
"324": "https://zksync-mainnet.infura.io/v3/",
|
|
11
|
+
"1329": "https://sei-mainnet.infura.io/v3/",
|
|
12
|
+
"1923": "https://swellchain-mainnet.infura.io/v3/",
|
|
13
|
+
"5000": "https://mantle-mainnet.infura.io/v3/",
|
|
14
|
+
"6342": "https://megaeth-mainnet.infura.io/v3/",
|
|
15
|
+
"8453": "https://base-mainnet.infura.io/v3/",
|
|
16
|
+
"42161": "https://arbitrum-mainnet.infura.io/v3/",
|
|
17
|
+
"42220": "https://celo-mainnet.infura.io/v3/",
|
|
18
|
+
"43111": "https://hemi-testnet.infura.io/v3/",
|
|
19
|
+
"43114": "https://avalanche-mainnet.infura.io/v3/",
|
|
20
|
+
"59144": "https://linea-mainnet.infura.io/v3/",
|
|
21
|
+
"81457": "https://blast-mainnet.infura.io/v3/",
|
|
22
|
+
"534352": "https://scroll-mainnet.infura.io/v3/",
|
|
23
|
+
"11155111": "https://sepolia.infura.io/v3/"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
PARENT = Path(__file__).parent
|
|
5
|
+
ENDPOINTS = PARENT / Path("endpoints.json")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Infura:
|
|
9
|
+
def __init__(self, api_key: str):
|
|
10
|
+
self.api_key = api_key
|
|
11
|
+
|
|
12
|
+
def get_url(self, chain_id: str) -> str:
|
|
13
|
+
return self._build_url(chain_id)
|
|
14
|
+
|
|
15
|
+
def _load_endpoints(self) -> dict:
|
|
16
|
+
with open(ENDPOINTS, "r") as file:
|
|
17
|
+
data = json.load(file)
|
|
18
|
+
return data
|
|
19
|
+
|
|
20
|
+
def add_endpoint(self, chain_id: int | str, endpoint: str) -> None:
|
|
21
|
+
data = self._load_endpoints()
|
|
22
|
+
data["infura"][str(chain_id)] = endpoint
|
|
23
|
+
with open(ENDPOINTS, "w") as file:
|
|
24
|
+
json.dump(data, file, indent=4)
|
|
25
|
+
|
|
26
|
+
def view_endpoints(self) -> list:
|
|
27
|
+
data = self._load_endpoints()
|
|
28
|
+
return data["infura"]
|
|
29
|
+
|
|
30
|
+
def _build_url(self, chain_id: str):
|
|
31
|
+
chain_id = str(chain_id)
|
|
32
|
+
data = self._load_endpoints()
|
|
33
|
+
try:
|
|
34
|
+
return data["infura"][chain_id] + self.api_key
|
|
35
|
+
except KeyError:
|
|
36
|
+
return None
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
2
|
+
from .dex import Dex
|
|
3
|
+
from .periphery.dex_contracts import get_dex_architecture
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _get_swap_fee_bps(dex_name: str, pool_fee_tier: int | None) -> int:
|
|
7
|
+
"""
|
|
8
|
+
Return the swap fee in basis points for a given DEX.
|
|
9
|
+
For V3 DEXes the fee is per-pool (stored in pools_v3.fee), so pool_fee_tier is used.
|
|
10
|
+
For V2 DEXes the fee is fixed and comes from dex_architecture.json.
|
|
11
|
+
Returns 0 if unknown.
|
|
12
|
+
"""
|
|
13
|
+
arch = get_dex_architecture(dex_name)
|
|
14
|
+
if arch is None:
|
|
15
|
+
return 0
|
|
16
|
+
if pool_fee_tier is not None:
|
|
17
|
+
# V3-style: fee tier is already in basis points (e.g. 500 = 0.05%, 3000 = 0.3%)
|
|
18
|
+
return pool_fee_tier // 100
|
|
19
|
+
return arch.get("swap_fee_bps") or 0
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_prices(
|
|
23
|
+
dex_mapping: dict[str, Dex], token_0_address: str, token_1_address: str
|
|
24
|
+
) -> dict[str, dict]:
|
|
25
|
+
"""
|
|
26
|
+
Fetch prices and pool addresses for a token pair across all DEXes in parallel.
|
|
27
|
+
Returns {dex_name: {"price": float | None, "pool": str | None, "fee_bps": int}}.
|
|
28
|
+
"""
|
|
29
|
+
def _fetch(dex_name: str, dex: Dex) -> tuple[str, dict]:
|
|
30
|
+
pool = dex.pool_address(token_0_address, token_1_address)
|
|
31
|
+
price = dex.get_price(token_0_address, token_1_address) if pool else None
|
|
32
|
+
|
|
33
|
+
# Retrieve cached fee tier for V3 pools (stored as 0 for algebra, actual tier for uniswap_v3)
|
|
34
|
+
fee_tier = None
|
|
35
|
+
if pool and dex.interface:
|
|
36
|
+
from .dex import _sort_tokens
|
|
37
|
+
t0, t1 = _sort_tokens(token_0_address, token_1_address)
|
|
38
|
+
cached = dex.interface.read_pool_v3(dex.name, dex.chain_id, t0, t1)
|
|
39
|
+
if not cached.is_empty():
|
|
40
|
+
fee_tier = int(cached["fee"][0])
|
|
41
|
+
|
|
42
|
+
fee_bps = _get_swap_fee_bps(dex_name, fee_tier)
|
|
43
|
+
return dex_name, {"price": price, "pool": pool, "fee_bps": fee_bps}
|
|
44
|
+
|
|
45
|
+
results = {}
|
|
46
|
+
with ThreadPoolExecutor() as executor:
|
|
47
|
+
futures = {
|
|
48
|
+
executor.submit(_fetch, name, dex): name
|
|
49
|
+
for name, dex in dex_mapping.items()
|
|
50
|
+
}
|
|
51
|
+
for future in as_completed(futures):
|
|
52
|
+
dex_name, data = future.result()
|
|
53
|
+
results[dex_name] = data
|
|
54
|
+
|
|
55
|
+
return results
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def arbitrage_route(
|
|
59
|
+
dex_mapping: dict[str, Dex], token_0_address: str, token_1_address: str
|
|
60
|
+
):
|
|
61
|
+
results = get_prices(dex_mapping, token_0_address, token_1_address)
|
|
62
|
+
available = {k: v for k, v in results.items() if v["price"] is not None}
|
|
63
|
+
|
|
64
|
+
if len(available) < 2:
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
buy_dex = min(available, key=lambda k: available[k]["price"])
|
|
68
|
+
sell_dex = max(available, key=lambda k: available[k]["price"])
|
|
69
|
+
|
|
70
|
+
buy_price = available[buy_dex]["price"]
|
|
71
|
+
sell_price = available[sell_dex]["price"]
|
|
72
|
+
|
|
73
|
+
spread_abs = sell_price - buy_price
|
|
74
|
+
spread_pct = (spread_abs / buy_price) * 100
|
|
75
|
+
|
|
76
|
+
# Cost to buy on buy_dex then sell on sell_dex (both legs as % of trade)
|
|
77
|
+
total_fee_pct = (available[buy_dex]["fee_bps"] + available[sell_dex]["fee_bps"]) / 100
|
|
78
|
+
net_spread_pct = spread_pct - total_fee_pct
|
|
79
|
+
is_profitable = net_spread_pct > 0
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
"buy": {"dex": buy_dex, "price": buy_price, "pool": available[buy_dex]["pool"], "fee_bps": available[buy_dex]["fee_bps"]},
|
|
83
|
+
"sell": {"dex": sell_dex, "price": sell_price, "pool": available[sell_dex]["pool"], "fee_bps": available[sell_dex]["fee_bps"]},
|
|
84
|
+
"spread_abs": round(spread_abs, 6),
|
|
85
|
+
"spread_pct": round(spread_pct, 4),
|
|
86
|
+
"total_fee_pct": round(total_fee_pct, 4),
|
|
87
|
+
"net_spread_pct": round(net_spread_pct, 4),
|
|
88
|
+
"profitable": is_profitable,
|
|
89
|
+
"all_prices": results,
|
|
90
|
+
}
|