defi-state-querier 0.0.6__py3-none-any.whl → 0.0.9__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.
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}