Skip to content

Commit 19223ac

Browse files
committed
Metadata methods
1 parent 58e850f commit 19223ac

File tree

2 files changed

+245
-1
lines changed

2 files changed

+245
-1
lines changed

async_substrate_interface/async_substrate.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,41 @@ async def get_metadata_runtime_call_function(
12911291

12921292
return runtime_call_def_obj
12931293

1294+
async def get_metadata_runtime_call_function(
1295+
self, api: str, method: str
1296+
) -> GenericRuntimeCallDefinition:
1297+
"""
1298+
Get details of a runtime API call
1299+
1300+
Args:
1301+
api: Name of the runtime API e.g. 'TransactionPaymentApi'
1302+
method: Name of the method e.g. 'query_fee_details'
1303+
1304+
Returns:
1305+
GenericRuntimeCallDefinition
1306+
"""
1307+
await self.init_runtime(block_hash=block_hash)
1308+
1309+
try:
1310+
runtime_call_def = self.runtime_config.type_registry["runtime_api"][api][
1311+
"methods"
1312+
][method]
1313+
runtime_call_def["api"] = api
1314+
runtime_call_def["method"] = method
1315+
runtime_api_types = self.runtime_config.type_registry["runtime_api"][
1316+
api
1317+
].get("types", {})
1318+
except KeyError:
1319+
raise ValueError(f"Runtime API Call '{api}.{method}' not found in registry")
1320+
1321+
# Add runtime API types to registry
1322+
self.runtime_config.update_type_registry_types(runtime_api_types)
1323+
1324+
runtime_call_def_obj = await self.create_scale_object("RuntimeCallDefinition")
1325+
runtime_call_def_obj.encode(runtime_call_def)
1326+
1327+
return runtime_call_def_obj
1328+
12941329
async def _get_block_handler(
12951330
self,
12961331
block_hash: str,
@@ -1767,6 +1802,21 @@ def convert_event_data(data):
17671802
events.append(convert_event_data(item))
17681803
return events
17691804

1805+
async def get_metadata(self, block_hash=None):
1806+
"""
1807+
Returns `MetadataVersioned` object for given block_hash or chaintip if block_hash is omitted
1808+
1809+
1810+
Args:
1811+
block_hash
1812+
1813+
Returns:
1814+
MetadataVersioned
1815+
"""
1816+
runtime = await self.init_runtime(block_hash=block_hash)
1817+
1818+
return runtime.metadata
1819+
17701820
@a.lru_cache(maxsize=512)
17711821
async def get_parent_block_hash(self, block_hash):
17721822
return await self._get_parent_block_hash(block_hash)
@@ -2725,6 +2775,29 @@ async def get_account_next_index(self, account_address: str) -> int:
27252775
self._nonces[account_address] += 1
27262776
return self._nonces[account_address]
27272777

2778+
async def get_metadata_constants(self, block_hash=None) -> list[dict]:
2779+
"""
2780+
Retrieves a list of all constants in metadata active at given block_hash (or chaintip if block_hash is omitted)
2781+
2782+
Args:
2783+
block_hash: hash of the block
2784+
2785+
Returns:
2786+
list of constants
2787+
"""
2788+
2789+
runtime = await self.init_runtime(block_hash=block_hash)
2790+
2791+
constant_list = []
2792+
2793+
for module_idx, module in enumerate(self.metadata.pallets):
2794+
for constant in module.constants or []:
2795+
constant_list.append(
2796+
self.serialize_constant(constant, module, runtime.runtime_version)
2797+
)
2798+
2799+
return constant_list
2800+
27282801
async def get_metadata_constant(self, module_name, constant_name, block_hash=None):
27292802
"""
27302803
Retrieves the details of a constant for given module name, call function name and block_hash
@@ -3234,6 +3307,55 @@ async def get_metadata_call_function(
32343307
return call
32353308
return None
32363309

3310+
async def get_metadata_events(self, block_hash=None) -> list[dict]:
3311+
"""
3312+
Retrieves a list of all events in metadata active for given block_hash (or chaintip if block_hash is omitted)
3313+
3314+
Args:
3315+
block_hash
3316+
3317+
Returns:
3318+
list of module events
3319+
"""
3320+
3321+
runtime = await self.init_runtime(block_hash=block_hash)
3322+
3323+
event_list = []
3324+
3325+
for event_index, (module, event) in self.metadata.event_index.items():
3326+
event_list.append(
3327+
self.serialize_module_event(
3328+
module, event, runtime.runtime_version, event_index
3329+
)
3330+
)
3331+
3332+
return event_list
3333+
3334+
async def get_metadata_event(
3335+
self, module_name, event_name, block_hash=None
3336+
) -> Optional[Any]:
3337+
"""
3338+
Retrieves the details of an event for given module name, call function name and block_hash
3339+
(or chaintip if block_hash is omitted)
3340+
3341+
Args:
3342+
module_name: name of the module to call
3343+
event_name: name of the event
3344+
block_hash: hash of the block
3345+
3346+
Returns:
3347+
Metadata event
3348+
3349+
"""
3350+
3351+
runtime = await self.init_runtime(block_hash=block_hash)
3352+
3353+
for pallet in runtime.metadata.pallets:
3354+
if pallet.name == module_name and pallet.events:
3355+
for event in pallet.events:
3356+
if event.name == event_name:
3357+
return event
3358+
32373359
async def get_block_number(self, block_hash: Optional[str] = None) -> int:
32383360
"""Async version of `substrateinterface.base.get_block_number` method."""
32393361
response = await self.rpc_request("chain_getHeader", [block_hash])

async_substrate_interface/sync_substrate.py

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ def subscription_handler(storage_key, obj, subscription_id):
822822
823823
Args:
824824
storage_keys: StorageKey list of storage keys to subscribe to
825-
subscription_handler: coroutine function to handle value changes of subscription
825+
subscription_handler: function to handle value changes of subscription
826826
827827
"""
828828
self.init_runtime()
@@ -1040,6 +1040,41 @@ def get_metadata_runtime_call_function(
10401040

10411041
return runtime_call_def_obj
10421042

1043+
def get_metadata_runtime_call_function(
1044+
self, api: str, method: str
1045+
) -> GenericRuntimeCallDefinition:
1046+
"""
1047+
Get details of a runtime API call
1048+
1049+
Args:
1050+
api: Name of the runtime API e.g. 'TransactionPaymentApi'
1051+
method: Name of the method e.g. 'query_fee_details'
1052+
1053+
Returns:
1054+
GenericRuntimeCallDefinition
1055+
"""
1056+
self.init_runtime()
1057+
1058+
try:
1059+
runtime_call_def = self.runtime_config.type_registry["runtime_api"][api][
1060+
"methods"
1061+
][method]
1062+
runtime_call_def["api"] = api
1063+
runtime_call_def["method"] = method
1064+
runtime_api_types = self.runtime_config.type_registry["runtime_api"][
1065+
api
1066+
].get("types", {})
1067+
except KeyError:
1068+
raise ValueError(f"Runtime API Call '{api}.{method}' not found in registry")
1069+
1070+
# Add runtime API types to registry
1071+
self.runtime_config.update_type_registry_types(runtime_api_types)
1072+
1073+
runtime_call_def_obj = self.create_scale_object("RuntimeCallDefinition")
1074+
runtime_call_def_obj.encode(runtime_call_def)
1075+
1076+
return runtime_call_def_obj
1077+
10431078
def _get_block_handler(
10441079
self,
10451080
block_hash: str,
@@ -1510,6 +1545,21 @@ def convert_event_data(data):
15101545
events.append(convert_event_data(item))
15111546
return events
15121547

1548+
def get_metadata(self, block_hash=None):
1549+
"""
1550+
Returns `MetadataVersioned` object for given block_hash or chaintip if block_hash is omitted
1551+
1552+
1553+
Args:
1554+
block_hash
1555+
1556+
Returns:
1557+
MetadataVersioned
1558+
"""
1559+
runtime = self.init_runtime(block_hash=block_hash)
1560+
1561+
return runtime.metadata
1562+
15131563
@functools.lru_cache(maxsize=512)
15141564
def get_parent_block_hash(self, block_hash):
15151565
block_header = self.rpc_request("chain_getHeader", [block_hash])
@@ -2428,6 +2478,29 @@ def get_account_next_index(self, account_address: str) -> int:
24282478
nonce_obj = self.rpc_request("account_nextIndex", [account_address])
24292479
return nonce_obj["result"]
24302480

2481+
def get_metadata_constants(self, block_hash=None) -> list[dict]:
2482+
"""
2483+
Retrieves a list of all constants in metadata active at given block_hash (or chaintip if block_hash is omitted)
2484+
2485+
Args:
2486+
block_hash: hash of the block
2487+
2488+
Returns:
2489+
list of constants
2490+
"""
2491+
2492+
runtime = self.init_runtime(block_hash=block_hash)
2493+
2494+
constant_list = []
2495+
2496+
for module_idx, module in enumerate(self.metadata.pallets):
2497+
for constant in module.constants or []:
2498+
constant_list.append(
2499+
self.serialize_constant(constant, module, runtime.runtime_version)
2500+
)
2501+
2502+
return constant_list
2503+
24312504
def get_metadata_constant(self, module_name, constant_name, block_hash=None):
24322505
"""
24332506
Retrieves the details of a constant for given module name, call function name and block_hash
@@ -2926,6 +2999,55 @@ def get_metadata_call_function(
29262999
return call
29273000
return None
29283001

3002+
def get_metadata_events(self, block_hash=None) -> list[dict]:
3003+
"""
3004+
Retrieves a list of all events in metadata active for given block_hash (or chaintip if block_hash is omitted)
3005+
3006+
Args:
3007+
block_hash
3008+
3009+
Returns:
3010+
list of module events
3011+
"""
3012+
3013+
runtime = self.init_runtime(block_hash=block_hash)
3014+
3015+
event_list = []
3016+
3017+
for event_index, (module, event) in self.metadata.event_index.items():
3018+
event_list.append(
3019+
self.serialize_module_event(
3020+
module, event, runtime.runtime_version, event_index
3021+
)
3022+
)
3023+
3024+
return event_list
3025+
3026+
def get_metadata_event(
3027+
self, module_name, event_name, block_hash=None
3028+
) -> Optional[Any]:
3029+
"""
3030+
Retrieves the details of an event for given module name, call function name and block_hash
3031+
(or chaintip if block_hash is omitted)
3032+
3033+
Args:
3034+
module_name: name of the module to call
3035+
event_name: name of the event
3036+
block_hash: hash of the block
3037+
3038+
Returns:
3039+
Metadata event
3040+
3041+
"""
3042+
3043+
runtime = self.init_runtime(block_hash=block_hash)
3044+
3045+
for pallet in runtime.metadata.pallets:
3046+
if pallet.name == module_name and pallet.events:
3047+
for event in pallet.events:
3048+
if event.name == event_name:
3049+
return event
3050+
29293051
def get_block_number(self, block_hash: Optional[str] = None) -> int:
29303052
"""Async version of `substrateinterface.base.get_block_number` method."""
29313053
response = self.rpc_request("chain_getHeader", [block_hash])

0 commit comments

Comments
 (0)