Skip to content

Commit ce54ab2

Browse files
author
Kotsias, Panagiotis-Christos
committed
Refactored structure
1 parent f76b976 commit ce54ab2

File tree

9 files changed

+358
-0
lines changed

9 files changed

+358
-0
lines changed

‎etherscan/modules/__init__.py

Whitespace-only changes.

‎etherscan/modules/accounts.py

+265
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
from functools import reduce
2+
from typing import List
3+
4+
from etherscan.utils.datatypes import TxHash, WalletAddress
5+
from etherscan.enums.actions_enum import ActionsEnum as actions
6+
from etherscan.enums.fields_enum import FieldsEnum as fields
7+
from etherscan.enums.modules_enum import ModulesEnum as modules
8+
from etherscan.enums.tags_enum import TagsEnum as tags
9+
10+
11+
class Accounts:
12+
@staticmethod
13+
def get_eth_balance(wallet: WalletAddress) -> str:
14+
url = (
15+
f"{fields.MODULE}"
16+
f"{modules.ACCOUNT}"
17+
f"{fields.ACTION}"
18+
f"{actions.BALANCE}"
19+
f"{fields.ADDRESS}"
20+
f"{wallet}"
21+
f"{fields.TAG}"
22+
f"{tags.LATEST}"
23+
)
24+
return url
25+
# r = requests.get(url)
26+
# return conversions.to_ticker_unit(parser.get_result(r))
27+
28+
@staticmethod
29+
def get_eth_balance_multiple(wallets: List[WalletAddress]) -> str:
30+
# max 20 wallets
31+
wallet_list = reduce(lambda w1, w2: str(w1) + "," + str(w2), wallets)
32+
url = (
33+
f"{fields.MODULE}"
34+
f"{modules.ACCOUNT}"
35+
f"{fields.ACTION}"
36+
f"{actions.BALANCE_MULTI}"
37+
f"{fields.ADDRESS}"
38+
f"{wallet_list}"
39+
f"{fields.TAG}"
40+
f"{tags.LATEST}"
41+
)
42+
return url
43+
# r = requests.get(url)
44+
# return [conversions.to_ticker_unit(r["balance"]) for r in parser.get_result(r)]
45+
46+
@staticmethod
47+
def get_hist_eth_balance_by_block(wallet: WalletAddress, block: int) -> str:
48+
# throttled to 2 calls/sec
49+
# BUG: returns 'Error! Missing Or invalid Action name'
50+
url = (
51+
f"{fields.MODULE}"
52+
f"{modules.ACCOUNT}"
53+
f"{fields.ACTION}"
54+
f"{actions.BALANCE_HISTORY}"
55+
f"{fields.ADDRESS}"
56+
f"{wallet}"
57+
f"{fields.BLOCKNO}"
58+
f"{str(block)}"
59+
)
60+
return url
61+
62+
@staticmethod
63+
def get_normal_txs_by_address(
64+
wallet: WalletAddress,
65+
startblock: int = 0000,
66+
endblock: int = 99999999,
67+
sort: str = "asc",
68+
) -> str:
69+
# last 10,000 txs only
70+
url = (
71+
f"{fields.MODULE}"
72+
f"{modules.ACCOUNT}"
73+
f"{fields.ACTION}"
74+
f"{actions.TXLIST}"
75+
f"{fields.ADDRESS}"
76+
f"{wallet}"
77+
f"{fields.START_BLOCK}"
78+
f"{str(startblock)}"
79+
f"{fields.END_BLOCK}"
80+
f"{str(endblock)}"
81+
f"{fields.SORT}"
82+
f"{sort}"
83+
)
84+
return url
85+
86+
@staticmethod
87+
def get_normal_txs_by_address_paginated(
88+
wallet: WalletAddress,
89+
page: int,
90+
offset: int,
91+
startblock: int = 0000,
92+
endblock: int = 99999999,
93+
sort: str = "asc",
94+
) -> str:
95+
url = (
96+
f"{fields.MODULE}"
97+
f"{modules.ACCOUNT}"
98+
f"{fields.ACTION}"
99+
f"{actions.TXLIST}"
100+
f"{fields.ADDRESS}"
101+
f"{wallet}"
102+
f"{fields.START_BLOCK}"
103+
f"{str(startblock)}"
104+
f"{fields.END_BLOCK}"
105+
f"{str(endblock)}"
106+
f"{fields.SORT}"
107+
f"{sort}"
108+
f"{fields.PAGE}"
109+
f"{str(page)}"
110+
f"{fields.OFFSET}"
111+
f"{str(offset)}"
112+
)
113+
return url
114+
115+
@staticmethod
116+
def get_internal_txs_by_address(
117+
wallet: WalletAddress,
118+
startblock: int = 0000,
119+
endblock: int = 99999999,
120+
sort: str = "asc",
121+
) -> str:
122+
# last 10,000 txs only
123+
url = (
124+
f"{fields.MODULE}"
125+
f"{modules.ACCOUNT}"
126+
f"{fields.ACTION}"
127+
f"{actions.TXLIST_INTERNAL}"
128+
f"{fields.ADDRESS}"
129+
f"{wallet}"
130+
f"{fields.START_BLOCK}"
131+
f"{str(startblock)}"
132+
f"{fields.END_BLOCK}"
133+
f"{str(endblock)}"
134+
f"{fields.SORT}"
135+
f"{sort}"
136+
)
137+
return url
138+
139+
@staticmethod
140+
def get_internal_txs_by_address_paginated(
141+
wallet: WalletAddress,
142+
page: int,
143+
offset: int,
144+
startblock: int = 0000,
145+
endblock: int = 99999999,
146+
sort: str = "asc",
147+
) -> str:
148+
url = (
149+
f"{fields.MODULE}"
150+
f"{modules.ACCOUNT}"
151+
f"{fields.ACTION}"
152+
f"{actions.TXLIST_INTERNAL}"
153+
f"{fields.ADDRESS}"
154+
f"{wallet}"
155+
f"{fields.START_BLOCK}"
156+
f"{str(startblock)}"
157+
f"{fields.END_BLOCK}"
158+
f"{str(endblock)}"
159+
f"{fields.SORT}"
160+
f"{sort}"
161+
f"{fields.PAGE}"
162+
f"{str(page)}"
163+
f"{fields.OFFSET}"
164+
f"{str(offset)}"
165+
)
166+
return url
167+
168+
@staticmethod
169+
def get_internal_txs_by_txhash(txhash: TxHash) -> str:
170+
# last 10,000 txs only
171+
url = (
172+
f"{fields.MODULE}"
173+
f"{modules.ACCOUNT}"
174+
f"{fields.ACTION}"
175+
f"{actions.TXLIST_INTERNAL}"
176+
f"{fields.TXHASH}"
177+
f"{txhash}"
178+
)
179+
return url
180+
181+
@staticmethod
182+
def get_internal_txs_by_block_range_paginated(
183+
startblock: int, endblock: int, page: int, offset: int, sort: str = "asc",
184+
) -> str:
185+
# last 10,000 txs only
186+
# BUG: returns empty message
187+
url = (
188+
f"{fields.MODULE}"
189+
f"{modules.ACCOUNT}"
190+
f"{fields.ACTION}"
191+
f"{actions.TXLIST_INTERNAL}"
192+
f"{fields.START_BLOCK}"
193+
f"{str(startblock)}"
194+
f"{fields.END_BLOCK}"
195+
f"{str(endblock)}"
196+
f"{fields.SORT}"
197+
f"{sort}"
198+
f"{fields.PAGE}"
199+
f"{str(page)}"
200+
f"{fields.OFFSET}"
201+
f"{str(offset)}"
202+
)
203+
return url
204+
205+
@staticmethod
206+
def get_erc20_token_transfer_events_by_address(
207+
wallet: WalletAddress,
208+
startblock: int = 0,
209+
endblock: int = 999999999,
210+
sort: str = "asc",
211+
) -> str:
212+
# last 10,000 txs only
213+
url = (
214+
f"{fields.MODULE}"
215+
f"{modules.ACCOUNT}"
216+
f"{fields.ACTION}"
217+
f"{actions.TOKENTX}"
218+
f"{fields.ADDRESS}"
219+
f"{wallet}"
220+
f"{fields.START_BLOCK}"
221+
f"{str(startblock)}"
222+
f"{fields.END_BLOCK}"
223+
f"{str(endblock)}"
224+
f"{fields.SORT}"
225+
f"{sort}"
226+
)
227+
return url
228+
229+
@staticmethod
230+
def get_erc721_token_transfer_events_by_address(
231+
wallet: WalletAddress,
232+
startblock: int = 0,
233+
endblock: int = 999999999,
234+
sort: str = "asc",
235+
) -> str:
236+
# last 10,000 txs only
237+
url = (
238+
f"{fields.MODULE}"
239+
f"{modules.ACCOUNT}"
240+
f"{fields.ACTION}"
241+
f"{actions.TOKENNFTTX}"
242+
f"{fields.ADDRESS}"
243+
f"{wallet}"
244+
f"{fields.START_BLOCK}"
245+
f"{str(startblock)}"
246+
f"{fields.END_BLOCK}"
247+
f"{str(endblock)}"
248+
f"{fields.SORT}"
249+
f"{sort}"
250+
)
251+
return url
252+
253+
@staticmethod
254+
def get_mined_blocks_by_address(wallet: WalletAddress) -> str:
255+
url = (
256+
f"{fields.MODULE}"
257+
f"{modules.ACCOUNT}"
258+
f"{fields.ACTION}"
259+
f"{actions.GET_MINED_BLOCKS}"
260+
f"{fields.ADDRESS}"
261+
f"{wallet}"
262+
f"{fields.BLOCK_TYPE}"
263+
f"blocks"
264+
)
265+
return url

‎etherscan/modules/contracts.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Contracts:
2+
pass

‎etherscan/modules/tokens.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Tokens:
2+
pass

‎etherscan/modules/transactions.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Transactions:
2+
pass

‎etherscan/utils/__init__.py

Whitespace-only changes.

‎etherscan/utils/conversions.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from decimal import Decimal
2+
3+
4+
class Conversions:
5+
@staticmethod
6+
def to_ticker_unit(val: int, decimals: int = 18) -> Decimal:
7+
factor = Decimal("10") ** Decimal("-{}".format(decimals))
8+
return Decimal(val) * factor
9+
10+
@staticmethod
11+
def to_smallest_unit(val: int, decimals: int = 18) -> Decimal:
12+
factor = Decimal("10") ** Decimal("+{}".format(decimals))
13+
return Decimal(val) * factor

‎etherscan/utils/datatypes.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from etherscan.enums.messages_enum import MessagesEnum as msgs
2+
3+
_CONTRACT_LEN = 42
4+
_TX_LEN = 66
5+
_WALLET_LEN = 42
6+
7+
8+
class BaseAddress:
9+
def __init__(self):
10+
self._address = ""
11+
self._maxlen = 0
12+
13+
def _check_0x(self, address: str):
14+
if address[:2] != "0x":
15+
raise ValueError(msgs.INVALID_ADDRESS)
16+
return address
17+
18+
def _check_len(self, address: str):
19+
if len(address) != self._maxlen:
20+
raise ValueError(msgs.INVALID_ADDRESS)
21+
return address
22+
23+
def __repr__(self):
24+
return self._address
25+
26+
def __str__(self):
27+
return self._address
28+
29+
def __add__(self, val: str):
30+
return self._address + val
31+
32+
def __len__(self):
33+
return len(self._address)
34+
35+
36+
class ContractAddress(BaseAddress):
37+
def __init__(self, address: str):
38+
self._maxlen = _CONTRACT_LEN
39+
self._address = self._check_len(self._check_0x(address))
40+
41+
42+
class TxHash(BaseAddress):
43+
def __init__(self, address: str):
44+
self._maxlen = _TX_LEN
45+
self._address = self._check_len(self._check_0x(address))
46+
47+
48+
class WalletAddress(BaseAddress):
49+
def __init__(self, address: str):
50+
self._maxlen = _WALLET_LEN
51+
self._address = self._check_len(self._check_0x(address))
52+

‎etherscan/utils/parsing.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import requests
2+
3+
4+
class ResponseParser:
5+
@staticmethod
6+
def _get_content(response: requests.Response):
7+
return response.json()
8+
9+
@staticmethod
10+
def get_status(response: requests.Response):
11+
c = ResponseParser._get_content(response)
12+
return c["status"]
13+
14+
@staticmethod
15+
def get_message(response: requests.Response):
16+
c = ResponseParser._get_content(response)
17+
return c["message"]
18+
19+
@staticmethod
20+
def get_result(response: requests.Response):
21+
c = ResponseParser._get_content(response)
22+
return c["result"]

0 commit comments

Comments
 (0)