defi-state-querier 0.0.6__py3-none-any.whl → 0.0.9__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. defi_services/__init__.py +1 -1
  2. defi_services/abis/lending/morpho/__init__.py +0 -0
  3. defi_services/abis/lending/morpho/morpho_aave_v2_comptroller_abi.py +2301 -0
  4. defi_services/abis/lending/morpho/morpho_aave_v2_lens_abi.py +1208 -0
  5. defi_services/abis/lending/morpho/morpho_aave_v3_comptroller_abi.py +2994 -0
  6. defi_services/abis/lending/morpho/morpho_compound_comptroller_abi.py +2301 -0
  7. defi_services/abis/lending/morpho/morpho_compound_lens_abi.py +1402 -0
  8. defi_services/abis/lending/morpho/morpho_compound_reward_manager_abi.py +307 -0
  9. defi_services/abis/lending/radiant_v2/__init__.py +0 -0
  10. defi_services/abis/lending/radiant_v2/radiant_v2_incentive_abi.py +1016 -0
  11. defi_services/abis/lending/wepiggy/__init__.py +0 -0
  12. defi_services/abis/lending/wepiggy/wepiggy_distribution_abi.py +1047 -0
  13. defi_services/constants/chain_constant.py +1 -0
  14. defi_services/constants/entities/lending_constant.py +26 -0
  15. defi_services/constants/entities/lending_services.py +85 -0
  16. defi_services/constants/query_constant.py +1 -0
  17. defi_services/constants/token_constant.py +2 -0
  18. defi_services/jobs/processors/__init__.py +0 -0
  19. defi_services/jobs/processors/solana_state_processor.py +101 -0
  20. defi_services/jobs/{state_processor.py → processors/state_processor.py} +9 -4
  21. defi_services/jobs/processors/substrate_state_processor.py +97 -0
  22. defi_services/jobs/queriers/__init__.py +0 -0
  23. defi_services/jobs/queriers/solana_state_querier.py +83 -0
  24. defi_services/jobs/{state_querier.py → queriers/state_querier.py} +3 -2
  25. defi_services/jobs/queriers/substrate_state_querier.py +84 -0
  26. defi_services/services/lending/aave_v2_services.py +8 -7
  27. defi_services/services/lending/aave_v3_services.py +12 -9
  28. defi_services/services/lending/compound_service.py +29 -10
  29. defi_services/services/lending/cream_services.py +5 -4
  30. defi_services/services/lending/flux_services.py +34 -27
  31. defi_services/services/lending/geist_services.py +4 -3
  32. defi_services/services/lending/granary_v1_services.py +6 -7
  33. defi_services/services/lending/iron_bank_service.py +20 -13
  34. defi_services/services/lending/lending_info/aave_v2_services.py +2 -2
  35. defi_services/services/lending/lending_info/ethereum/morpho_aave_v2_eth.py +53 -0
  36. defi_services/services/lending/lending_info/ethereum/morpho_aave_v3_eth.py +51 -0
  37. defi_services/services/lending/lending_info/ethereum/morpho_compound_eth.py +44 -0
  38. defi_services/services/lending/lending_info/ethereum/wepiggy_eth.py +41 -0
  39. defi_services/services/lending/liqee_service.py +5 -26
  40. defi_services/services/lending/morpho_aave_v2_services.py +89 -0
  41. defi_services/services/lending/morpho_aave_v3_services.py +159 -0
  42. defi_services/services/lending/morpho_compound_services.py +233 -0
  43. defi_services/services/lending/onyx_service.py +32 -13
  44. defi_services/services/lending/radiant_v2_services.py +30 -3
  45. defi_services/services/lending/strike_service.py +29 -10
  46. defi_services/services/lending/trava_services.py +8 -7
  47. defi_services/services/lending/uwu_services.py +8 -7
  48. defi_services/services/lending/valas_services.py +6 -5
  49. defi_services/services/lending/venus_services.py +28 -8
  50. defi_services/services/lending/wepiggy_services.py +519 -0
  51. defi_services/services/nft_services.py +1 -1
  52. defi_services/services/solana_token_services.py +46 -0
  53. defi_services/services/substrate_token_services.py +70 -0
  54. defi_services/services/token_services.py +1 -3
  55. defi_services/utils/init_services.py +3 -3
  56. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/METADATA +3 -3
  57. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/RECORD +60 -32
  58. defi_services/constants/entities/lending.py +0 -97
  59. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/LICENSE +0 -0
  60. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/WHEEL +0 -0
  61. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  class Chain:
2
+ solana = "solana"
2
3
  bsc = "0x38"
3
4
  ethereum = "0x1"
4
5
  fantom = "0xfa"
@@ -0,0 +1,26 @@
1
+ class Lending:
2
+ # service
3
+ aave_v2 = "aave-v2"
4
+ aave_v3 = "aave-v3"
5
+ radiant_v2 = "radiant-v2"
6
+ compound = "compound"
7
+ flux = "flux-finance"
8
+ iron_bank = "iron-bank"
9
+ trava = "trava-finance"
10
+ valas = "valas-finance"
11
+ geist = "geist-finance"
12
+ cream = "cream-lending"
13
+ venus = "venus"
14
+ liqee = "liqee"
15
+ strike = "strike"
16
+ uwu = "uwu-lend"
17
+ onyx = "onyx-protocol"
18
+ granary = "granary-finance"
19
+ wepiggy = "wepiggy"
20
+ morpho_compound = 'morpho-compound'
21
+ morpho_aave_v2 = 'morpho-aave'
22
+ morpho_aave_v3 = 'morpho-aavev3'
23
+ all = [strike, aave_v2, aave_v3, radiant_v2, compound, flux, onyx, granary,
24
+ iron_bank, trava, valas, geist, cream, venus, liqee, strike, uwu, wepiggy,
25
+ morpho_compound, morpho_aave_v2, morpho_aave_v3
26
+ ]
@@ -0,0 +1,85 @@
1
+ from defi_services.constants.chain_constant import Chain
2
+ from defi_services.constants.entities.lending_constant import Lending
3
+ from defi_services.services.lending.aave_v2_services import AaveV2StateService
4
+ from defi_services.services.lending.granary_v1_services import GranaryV1StateService
5
+ from defi_services.services.lending.morpho_aave_v2_services import MorphoAaveV2Services
6
+ from defi_services.services.lending.morpho_aave_v3_services import MorphoAaveV3Services
7
+ from defi_services.services.lending.morpho_compound_services import MorphoCompoundServices
8
+ from defi_services.services.lending.uwu_services import UwuStateService
9
+ from defi_services.services.lending.aave_v3_services import AaveV3StateService
10
+ from defi_services.services.lending.compound_service import CompoundStateService
11
+ from defi_services.services.lending.cream_services import CreamStateService
12
+ from defi_services.services.lending.geist_services import GeistStateService
13
+ from defi_services.services.lending.radiant_v2_services import RadiantStateService
14
+ from defi_services.services.lending.trava_services import TravaStateService
15
+ from defi_services.services.lending.valas_services import ValasStateService
16
+ from defi_services.services.lending.flux_services import FluxStateService
17
+ from defi_services.services.lending.iron_bank_service import IronBankStateService
18
+ from defi_services.services.lending.venus_services import VenusStateService
19
+ from defi_services.services.lending.liqee_service import LiqeeStateService
20
+ from defi_services.services.lending.strike_service import StrikeStateService
21
+ from defi_services.services.lending.onyx_service import OnyxStateService
22
+ from defi_services.services.lending.wepiggy_services import WepiggyStateService
23
+
24
+
25
+ class LendingServices:
26
+ # chain
27
+ ethereum = {
28
+ Lending.aave_v2: AaveV2StateService,
29
+ Lending.compound: CompoundStateService,
30
+ Lending.trava: TravaStateService,
31
+ Lending.flux: FluxStateService,
32
+ Lending.iron_bank: IronBankStateService,
33
+ Lending.uwu: UwuStateService,
34
+ Lending.aave_v3: AaveV3StateService,
35
+ Lending.liqee: LiqeeStateService,
36
+ Lending.strike: StrikeStateService,
37
+ Lending.onyx: OnyxStateService,
38
+ Lending.granary: GranaryV1StateService,
39
+ Lending.wepiggy: WepiggyStateService,
40
+ Lending.morpho_aave_v3: MorphoAaveV3Services,
41
+ Lending.morpho_aave_v2: MorphoAaveV2Services,
42
+ Lending.morpho_compound: MorphoCompoundServices
43
+ }
44
+ fantom = {
45
+ Lending.trava: TravaStateService,
46
+ Lending.geist: GeistStateService,
47
+ Lending.aave_v3: AaveV3StateService,
48
+ }
49
+
50
+ bsc = {
51
+ Lending.trava: TravaStateService,
52
+ Lending.valas: ValasStateService,
53
+ Lending.cream: CreamStateService,
54
+ Lending.venus: VenusStateService,
55
+ Lending.radiant_v2: RadiantStateService
56
+ }
57
+
58
+ avalanche = {
59
+ Lending.aave_v3: AaveV3StateService,
60
+ Lending.aave_v2: AaveV2StateService
61
+ }
62
+
63
+ polygon = {
64
+ Lending.aave_v2: AaveV2StateService,
65
+ Lending.aave_v3: AaveV3StateService
66
+ }
67
+
68
+ optimism = {
69
+ Lending.aave_v3: AaveV3StateService
70
+ }
71
+
72
+ arbitrum = {
73
+ Lending.radiant_v2: RadiantStateService,
74
+ Lending.aave_v3: AaveV3StateService
75
+ }
76
+ # mapping
77
+ mapping = {
78
+ Chain.ethereum: ethereum,
79
+ Chain.fantom: fantom,
80
+ Chain.bsc: bsc,
81
+ Chain.avalanche: avalanche,
82
+ Chain.polygon: polygon,
83
+ Chain.arbitrum: arbitrum,
84
+ Chain.optimism: optimism
85
+ }
@@ -4,6 +4,7 @@ class Query:
4
4
  function = "function"
5
5
  params = "params"
6
6
  block_number = "block_number"
7
+ module = "module"
7
8
 
8
9
  # query types
9
10
  token_balance = 'token_balance'
@@ -10,7 +10,9 @@ class Token:
10
10
  wrapped_eth_optimism = "0x4200000000000000000000000000000000000006"
11
11
  wrapped_eth_arbitrum = "0x82af49447d8a07e3bd95bd0d56f35241523fbab1"
12
12
  wrapped_matic = '0x0000000000000000000000000000000000001010'
13
+ wrapped_sol = 'So11111111111111111111111111111111111111112'
13
14
  wrapped_token = {
15
+ Chain.solana: wrapped_sol,
14
16
  Chain.ethereum: wrapped_ethereum,
15
17
  Chain.bsc: wrapped_bsc,
16
18
  Chain.fantom: wrapped_ftm,
File without changes
@@ -0,0 +1,101 @@
1
+ import logging
2
+
3
+ from defi_services.constants.entities.lending_constant import Lending
4
+ from defi_services.constants.entities.lending_services import LendingServices
5
+ from defi_services.constants.query_constant import Query
6
+ from defi_services.database.mongodb import MongoDB
7
+ from defi_services.jobs.queriers.solana_state_querier import SolanaStateQuerier
8
+ from defi_services.services.solana_token_services import SolanaTokenServices
9
+
10
+ logger = logging.getLogger("SolanaStateProcessor")
11
+
12
+
13
+ class SolanaStateProcessor:
14
+ def __init__(self, provider_uri: str, chain_id: str, mongodb: MongoDB = None):
15
+ self.mongodb = mongodb
16
+ self.state_querier = SolanaStateQuerier(provider_uri)
17
+ self.chain_id = chain_id
18
+ self.token_service = SolanaTokenServices(self.state_querier, chain_id)
19
+ self.lending_services = LendingServices.mapping.get(chain_id)
20
+
21
+ def get_service_info(self):
22
+ info = self.token_service.get_service_info()
23
+ return info
24
+
25
+ def get_token_prices(self, tokens):
26
+ return self.mongodb.get_token_prices(tokens, self.chain_id)
27
+
28
+ def init_rpc_call_information(
29
+ self, wallet: str, query_id: str, entity_id: str, query_type: str):
30
+ queries = {}
31
+ tokens = []
32
+ rpc_calls = {}
33
+ if entity_id not in Lending.all and query_type in [Query.token_balance, Query.nft_balance]:
34
+ rpc_calls.update(self.token_service.get_function_info(wallet, entity_id))
35
+ tokens.append(entity_id)
36
+
37
+ queries[entity_id] = rpc_calls
38
+ tokens = list(set(tokens))
39
+ return {query_id: queries}, tokens
40
+
41
+ def execute_rpc_calls(self, queries: dict, batch_size: int = 100, max_workers: int = 8, ignore_error: bool = False):
42
+ rpc_calls = {}
43
+ for query, query_info in queries.items():
44
+ for entity, entity_value in query_info.items():
45
+ rpc_calls.update(entity_value)
46
+
47
+ decoded_data = self.state_querier.query_state_data(
48
+ rpc_calls, batch_size=batch_size, workers=max_workers, ignore_error=ignore_error)
49
+ result = {}
50
+ for query, query_info in queries.items():
51
+ query_data = {}
52
+ for entity, entity_value in query_info.items():
53
+ entity_data = {}
54
+ for key, value in entity_value.items():
55
+ entity_data[key] = decoded_data.get(key)
56
+ query_data[entity] = entity_data
57
+ result[query] = query_data
58
+
59
+ return result
60
+
61
+ def process_decoded_data(
62
+ self, query_id: str, query_type: str, wallet: str,
63
+ token_prices: dict, decoded_data: dict):
64
+ result = {
65
+ "query_id": query_id,
66
+ "query_type": query_type
67
+ }
68
+ query_value = decoded_data.get(query_id)
69
+ for entity, entity_value in query_value.items():
70
+ result["entity_id"] = entity
71
+ data = None
72
+ if entity not in Lending.all and query_type in [Query.nft_balance, Query.token_balance]:
73
+ data = self.token_service.get_data(wallet, entity, entity_value, token_prices)
74
+ result[query_type] = data
75
+
76
+ return result
77
+
78
+ def run(self, wallet: str, queries: list,
79
+ batch_size: int = 100, max_workers: int = 8, ignore_error=False):
80
+ all_rpc_calls, all_tokens = {}, []
81
+ for query in queries:
82
+ query_id = query.get("query_id")
83
+ entity_id = query.get("entity_id")
84
+ query_type = query.get("query_type")
85
+ rpc_calls, tokens = self.init_rpc_call_information(
86
+ wallet, query_id, entity_id, query_type)
87
+ all_rpc_calls.update(rpc_calls)
88
+ all_tokens += tokens
89
+ result = []
90
+ decoded_data = self.execute_rpc_calls(all_rpc_calls, batch_size, max_workers, ignore_error=ignore_error)
91
+ token_prices = {}
92
+ if self.mongodb:
93
+ token_prices = self.get_token_prices(all_tokens)
94
+ for query in queries:
95
+ query_id = query.get("query_id")
96
+ query_type = query.get("query_type")
97
+ processed_data = self.process_decoded_data(
98
+ query_id, query_type, wallet, token_prices, decoded_data)
99
+ result.append(processed_data)
100
+
101
+ return result
@@ -1,14 +1,18 @@
1
+ import logging
2
+
1
3
  from web3 import Web3
2
4
 
3
- from defi_services.constants.entities.lending import Lending
5
+ from defi_services.constants.entities.lending_services import LendingServices
4
6
  from defi_services.constants.query_constant import Query
5
7
  from defi_services.database.mongodb import MongoDB
6
- from defi_services.jobs.state_querier import StateQuerier
8
+ from defi_services.jobs.queriers.state_querier import StateQuerier
7
9
  from defi_services.services.nft_services import NFTServices
8
10
  from defi_services.services.protocol_services import ProtocolServices
9
11
  from defi_services.services.token_services import TokenServices
10
12
  from defi_services.utils.init_services import init_services
11
13
 
14
+ logger = logging.getLogger("StateProcessor")
15
+
12
16
 
13
17
  class StateProcessor:
14
18
  def __init__(self, provider_uri: str, chain_id: str, mongodb: MongoDB = None):
@@ -18,7 +22,7 @@ class StateProcessor:
18
22
  self.services = init_services(self.state_querier, chain_id)
19
23
  self.token_service = TokenServices(self.state_querier, chain_id)
20
24
  self.nft_service = NFTServices(self.state_querier, chain_id)
21
- self.lending_services = Lending.mapping.get(chain_id)
25
+ self.lending_services = LendingServices.mapping.get(chain_id)
22
26
 
23
27
  def get_service_info(self):
24
28
  info = self.nft_service.get_service_info()
@@ -113,7 +117,8 @@ class StateProcessor:
113
117
 
114
118
  return result
115
119
 
116
- def run(self, wallet: str, queries: list, block_number: int = 'latest', batch_size: int = 100, max_workers: int = 8, ignore_error=False):
120
+ def run(self, wallet: str, queries: list, block_number: int = 'latest',
121
+ batch_size: int = 100, max_workers: int = 8, ignore_error=False):
117
122
  all_rpc_calls, all_tokens = {}, []
118
123
  for query in queries:
119
124
  query_id = query.get("query_id")
@@ -0,0 +1,97 @@
1
+ import logging
2
+
3
+ from defi_services.constants.entities.lending_constant import Lending
4
+ from defi_services.constants.query_constant import Query
5
+ from defi_services.database.mongodb import MongoDB
6
+ from defi_services.jobs.queriers.substrate_state_querier import SubstrateStateQuerier
7
+ from defi_services.services.substrate_token_services import SubstrateTokenServices
8
+
9
+ logger = logging.getLogger("SubstrateStateProcessor")
10
+
11
+
12
+ class SubstrateStateProcessor:
13
+ def __init__(self, provider_uri: str, chain_id: str, mongodb: MongoDB = None):
14
+ self.mongodb = mongodb
15
+ self.state_querier = SubstrateStateQuerier(provider_uri)
16
+ self.chain_id = chain_id
17
+ self.token_service = SubstrateTokenServices(self.state_querier, chain_id)
18
+
19
+ def get_service_info(self):
20
+ info = self.token_service.get_service_info()
21
+ return info
22
+
23
+ def get_token_prices(self, tokens):
24
+ return self.mongodb.get_token_prices(tokens, self.chain_id)
25
+
26
+ def init_rpc_call_information(
27
+ self, wallet: str, query_id: str, entity_id: str, query_type: str, block_number: int = 'latest'):
28
+ queries = {}
29
+ tokens = []
30
+ rpc_calls = {}
31
+ if entity_id not in Lending.all and query_type in [Query.token_balance, Query.nft_balance]:
32
+ rpc_calls.update(self.token_service.get_function_info(wallet, entity_id, block_number))
33
+ tokens.append(entity_id)
34
+
35
+ queries[entity_id] = rpc_calls
36
+ tokens = list(set(tokens))
37
+ return {query_id: queries}, tokens
38
+
39
+ def execute_rpc_calls(self, queries: dict):
40
+ rpc_calls = {}
41
+ for query, query_info in queries.items():
42
+ for entity, entity_value in query_info.items():
43
+ rpc_calls.update(entity_value)
44
+
45
+ decoded_data = self.state_querier.query_state_data(rpc_calls)
46
+ result = {}
47
+ for query, query_info in queries.items():
48
+ query_data = {}
49
+ for entity, entity_value in query_info.items():
50
+ entity_data = {}
51
+ for key, value in entity_value.items():
52
+ entity_data[key] = decoded_data.get(key)
53
+ query_data[entity] = entity_data
54
+ result[query] = query_data
55
+
56
+ return result
57
+
58
+ def process_decoded_data(
59
+ self, query_id: str, query_type: str, wallet: str,
60
+ token_prices: dict, decoded_data: dict):
61
+ result = {
62
+ "query_id": query_id,
63
+ "query_type": query_type
64
+ }
65
+ query_value = decoded_data.get(query_id)
66
+ for entity, entity_value in query_value.items():
67
+ result["entity_id"] = entity
68
+ data = None
69
+ if entity not in Lending.all and query_type in [Query.nft_balance, Query.token_balance]:
70
+ data = self.token_service.get_data(wallet, entity, entity_value, token_prices)
71
+ result[query_type] = data
72
+
73
+ return result
74
+
75
+ def run(self, wallet: str, queries: list, block_number: int = 'latest'):
76
+ all_rpc_calls, all_tokens = {}, []
77
+ for query in queries:
78
+ query_id = query.get("query_id")
79
+ entity_id = query.get("entity_id")
80
+ query_type = query.get("query_type")
81
+ rpc_calls, tokens = self.init_rpc_call_information(
82
+ wallet, query_id, entity_id, query_type, block_number)
83
+ all_rpc_calls.update(rpc_calls)
84
+ all_tokens += tokens
85
+ result = []
86
+ decoded_data = self.execute_rpc_calls(all_rpc_calls)
87
+ token_prices = {}
88
+ if self.mongodb:
89
+ token_prices = self.get_token_prices(all_tokens)
90
+ for query in queries:
91
+ query_id = query.get("query_id")
92
+ query_type = query.get("query_type")
93
+ processed_data = self.process_decoded_data(
94
+ query_id, query_type, wallet, token_prices, decoded_data)
95
+ result.append(processed_data)
96
+
97
+ return result
File without changes
@@ -0,0 +1,83 @@
1
+ import logging
2
+
3
+ from query_state_lib.base.mappers.eth_json_rpc_mapper import EthJsonRpc
4
+ from query_state_lib.client.client_querier import ClientQuerier
5
+
6
+ from defi_services.constants.query_constant import Query
7
+
8
+ logger = logging.getLogger("SolanaStateQuerier")
9
+
10
+
11
+ class SolanaStateQuerier:
12
+ def __init__(self, provider_uri):
13
+ self.provider_uri = provider_uri
14
+ self.client_querier = ClientQuerier(provider_url=provider_uri)
15
+
16
+ @staticmethod
17
+ def get_function_info(fn_name: str, fn_paras: list = None):
18
+ if fn_paras is None:
19
+ fn_paras = []
20
+ data = {
21
+ "function": fn_name,
22
+ "params": fn_paras
23
+ }
24
+
25
+ return data
26
+
27
+ def query_state_data(self, queries: dict, batch_size: int = 100, workers: int = 5, ignore_error: bool = False):
28
+ """
29
+ Args:
30
+ queries: dict - defi state queries
31
+ - key: str - id of query
32
+ - value: dict - input of query
33
+ {
34
+ function: str - name of the function,
35
+ params: list - list parameters of function
36
+ }
37
+ batch_size: int - number of query in each batch queries
38
+ workers: int - maximum number of vCPU used in queries
39
+ ignore_error: bool - ignore error when decode result or not
40
+
41
+ Return:
42
+ + A dictionary result of queries
43
+ - key: str - id of query
44
+ - value: result of query
45
+ """
46
+ list_rpc_call, list_call_id = [], []
47
+ for key, value in queries.items():
48
+ fn_paras = value.get(Query.params)
49
+ fn_name = value.get(Query.function)
50
+ eth_call = self.add_rpc_call(fn_name=fn_name, fn_paras=fn_paras, call_id=key)
51
+ list_call_id.append(key)
52
+ list_rpc_call.append(eth_call)
53
+
54
+ response_data = self.client_querier.sent_batch_to_provider(list_rpc_call, batch_size, workers)
55
+ decoded_data = self.decode_response_data(response_data, list_call_id, ignore_error=ignore_error)
56
+ return decoded_data
57
+
58
+ @staticmethod
59
+ def add_rpc_call(fn_name: str, fn_paras: list = None, call_id: str = None):
60
+ solana_call = EthJsonRpc(method=fn_name, params=fn_paras, id=call_id)
61
+ return solana_call
62
+
63
+ @staticmethod
64
+ def decode_response_data(response_data: dict, list_call_id: list, ignore_error=False):
65
+ decoded_data = {}
66
+ for call_id in list_call_id:
67
+ try:
68
+ response_datum = response_data.get(call_id)
69
+ decoded_datum = response_datum.decode_result()
70
+ except Exception as e:
71
+ if not ignore_error:
72
+ logger.error(f"An exception when decode data from provider: {e}")
73
+ raise
74
+ else:
75
+ logger.error(f"[Ignored] An exception when decode data from provider: {e}")
76
+ continue
77
+ if isinstance(decoded_datum, int):
78
+ decoded_data[call_id] = decoded_datum
79
+ elif len(decoded_datum) == 1:
80
+ decoded_data[call_id] = decoded_datum[0]
81
+ else:
82
+ decoded_data[call_id] = decoded_datum
83
+ return decoded_data
@@ -10,7 +10,7 @@ from web3.middleware import geth_poa_middleware
10
10
  from defi_services.constants.query_constant import Query
11
11
  from defi_services.constants.token_constant import Token
12
12
 
13
- logger = logging.getLogger("StateService")
13
+ logger = logging.getLogger("StateQuerier")
14
14
 
15
15
 
16
16
  class StateQuerier:
@@ -94,8 +94,9 @@ class StateQuerier:
94
94
  decoded_data = self.decode_response_data(response_data, list_call_id, ignore_error=ignore_error)
95
95
  return decoded_data
96
96
 
97
+ @staticmethod
97
98
  def add_native_token_balance_rpc_call(
98
- self, fn_paras: str = None, call_id: str = None, block_number: int = "latest"):
99
+ fn_paras: str = None, call_id: str = None, block_number: int = "latest"):
99
100
  eth_call = GetBalance(Web3.toChecksumAddress(fn_paras), block_number, call_id)
100
101
  return eth_call
101
102
 
@@ -0,0 +1,84 @@
1
+ import logging
2
+
3
+ from substrateinterface import SubstrateInterface
4
+ from defi_services.constants.query_constant import Query
5
+
6
+ logger = logging.getLogger("SubstrateStateQuerier")
7
+
8
+
9
+ class SubstrateStateQuerier:
10
+ def __init__(self, provider_uri):
11
+ self.provider_uri = provider_uri
12
+ self.client_querier = SubstrateInterface(provider_uri)
13
+
14
+ def get_client_querier(self):
15
+ return self.client_querier
16
+
17
+ @staticmethod
18
+ def get_function_info(module: str, fn_name: str, fn_paras: list = None, block_number: int = "latest"):
19
+ if fn_paras is None:
20
+ fn_paras = []
21
+ data = {
22
+ "module": module,
23
+ "function": fn_name,
24
+ "params": fn_paras,
25
+ "block_number": block_number
26
+ }
27
+
28
+ return data
29
+
30
+ def query_state_data(self, queries: dict):
31
+ """
32
+ Args:
33
+ queries: dict - defi state queries
34
+ - key: str - id of query
35
+ - value: dict - input of query
36
+ {
37
+ function: str - name of the function,
38
+ params: list - list parameters of function
39
+ }
40
+ ignore_error: bool - ignore error when decode result or not
41
+
42
+ Return:
43
+ + A dictionary result of queries
44
+ - key: str - id of query
45
+ - value: result of query
46
+ """
47
+ block_hash, rpc_call, list_call_id = {}, {}, []
48
+ for key, value in queries.items():
49
+ module = value.get(Query.module)
50
+ fn_paras = value.get(Query.params)
51
+ fn_name = value.get(Query.function)
52
+ block_number = value.get(Query.block_number)
53
+ if block_number not in rpc_call:
54
+ rpc_call[block_number] = []
55
+ if block_number != "latest" and block_number not in block_hash:
56
+ block_hash[block_number] = self.client_querier.get_block_hash(block_number)
57
+ eth_call = self.add_rpc_call(module=module, fn_name=fn_name, fn_paras=fn_paras)
58
+ list_call_id.append(key)
59
+ rpc_call[block_number].append(eth_call)
60
+ decoded_data = {}
61
+ for block_number, list_rpc_call in rpc_call.items():
62
+ if block_number != "latest":
63
+ response_data = self.client_querier.query_multi(list_rpc_call, block_hash.get(block_number))
64
+ else:
65
+ response_data = self.client_querier.query_multi(list_rpc_call)
66
+
67
+ decoded_data.update(self.decode_response_data(response_data, block_number))
68
+ return decoded_data
69
+
70
+ def add_rpc_call(self, module: str, fn_name: str, fn_paras: list = None):
71
+ call = self.client_querier.create_storage_key(module, fn_name, fn_paras)
72
+ return call
73
+
74
+ @staticmethod
75
+ def decode_response_data(response_data: list, block_number: int = "latest"):
76
+ decoded_data = {}
77
+ for data in response_data:
78
+ storage_key = data[0]
79
+ storage_value = data[1]
80
+ key = f"{storage_key.pallet}_{storage_key.storage_function}_{storage_key.params}_{block_number}".lower()
81
+ value = storage_value.value_serialized
82
+ decoded_data[key] = value
83
+
84
+ return decoded_data
@@ -8,10 +8,11 @@ from defi_services.abis.lending.aave_v2_and_forlks.oracle_abi import ORACLE_ABI
8
8
  from defi_services.abis.token.erc20_abi import ERC20_ABI
9
9
  from defi_services.constants.chain_constant import Chain
10
10
  from defi_services.constants.db_constant import DBConst
11
+ from defi_services.constants.entities.lending_constant import Lending
11
12
  from defi_services.constants.query_constant import Query
12
13
  from defi_services.constants.time_constant import TimeConstants
13
14
  from defi_services.constants.token_constant import Token
14
- from defi_services.jobs.state_querier import StateQuerier
15
+ from defi_services.jobs.queriers.state_querier import StateQuerier
15
16
  from defi_services.services.lending.lending_info.avalanche.aave_v2_avalanche import AAVE_V2_AVALANCHE
16
17
  from defi_services.services.lending.lending_info.ethereum.aave_v2_eth import AAVE_V2_ETH
17
18
  from defi_services.services.lending.lending_info.polygon.aave_v2_polygon import AAVE_V2_POLYGON
@@ -30,7 +31,7 @@ class AaveInfo:
30
31
 
31
32
  class AaveV2StateService(ProtocolServices):
32
33
  def __init__(self, state_service: StateQuerier, chain_id: str = "0x1"):
33
- self.name = f"{chain_id}_aave-v2"
34
+ self.name = f"{chain_id}_{Lending.aave_v2}"
34
35
  self.chain_id = chain_id
35
36
  self.pool_info = AaveInfo.mapping.get(chain_id)
36
37
  self.lending_abi = LENDING_POOL_ABI
@@ -41,7 +42,7 @@ class AaveV2StateService(ProtocolServices):
41
42
  # BASIC FUNCTION
42
43
  def get_service_info(self):
43
44
  info = {
44
- "aave-v2": {
45
+ Lending.aave_v2: {
45
46
  "chain_id": self.chain_id,
46
47
  "type": "lending",
47
48
  "protocol_info": self.pool_info
@@ -153,7 +154,7 @@ class AaveV2StateService(ProtocolServices):
153
154
  "getAssetsPrices", list(reserves_info.keys()), block_number)
154
155
 
155
156
  for token_address, value in reserves_info.items():
156
- reserve_key = f"getReserveData_{token_address}_{block_number}".lower()
157
+ reserve_key = f"getReserveData_{self.name}_{token_address}_{block_number}".lower()
157
158
  atoken_assets_key = f"assets_{value['tToken']}_{block_number}".lower()
158
159
  debt_token_assets_key = f"assets_{value['dToken']}_{block_number}".lower()
159
160
  sdebt_token_assets_key = f"assets_{value['sdToken']}_{block_number}".lower()
@@ -253,7 +254,7 @@ class AaveV2StateService(ProtocolServices):
253
254
  ):
254
255
  reserves_data = {}
255
256
  for token in reserves_info:
256
- get_reserve_data_call_id = f'getReserveData_{token}_{block_number}'.lower()
257
+ get_reserve_data_call_id = f'getReserveData_{self.name}_{token}_{block_number}'.lower()
257
258
  reserves_data[token.lower()] = decoded_data.get(get_reserve_data_call_id)
258
259
 
259
260
  interest_rate, atokens, debt_tokens, sdebt_tokens, decimals, asset_data_tokens = {}, {}, {}, {}, {}, {}
@@ -415,7 +416,7 @@ class AaveV2StateService(ProtocolServices):
415
416
  for token, value in reserves_info.items():
416
417
  atoken, debt_token = Web3.toChecksumAddress(value['tToken']), Web3.toChecksumAddress(value['dToken'])
417
418
  tokens += [atoken, debt_token]
418
- key = f"getRewardsBalance_{wallet_address}_{block_number}".lower()
419
+ key = f"getRewardsBalance_{self.name}_{wallet_address}_{block_number}".lower()
419
420
  rpc_calls[key] = self.get_function_incentive_info(
420
421
  "getRewardsBalance", [tokens, wallet_address], block_number)
421
422
 
@@ -424,7 +425,7 @@ class AaveV2StateService(ProtocolServices):
424
425
  def calculate_all_rewards_balance(
425
426
  self, decoded_data: dict, wallet_address: str, block_number: int = "latest"):
426
427
  reward_token = self.pool_info['rewardToken']
427
- key = f"getRewardsBalance_{wallet_address}_{block_number}".lower()
428
+ key = f"getRewardsBalance_{self.name}_{wallet_address}_{block_number}".lower()
428
429
  rewards = decoded_data.get(key) / 10 ** 18
429
430
  result = {
430
431
  reward_token: {"amount": rewards}