Skip to content

Commit 3445e5f

Browse files
authored
Merge pull request #223 from opentensor/feat/thewhaleking/add-metadata-call-function-retrieval
Adds metadata call functions retrieval
2 parents 308befe + 22c4da2 commit 3445e5f

File tree

4 files changed

+88
-6
lines changed

4 files changed

+88
-6
lines changed

async_substrate_interface/async_substrate.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,11 +1587,11 @@ async def retrieve_pending_extrinsics(self) -> list:
15871587
return extrinsics
15881588

15891589
async def get_metadata_storage_functions(
1590-
self, block_hash=None, runtime: Optional[Runtime] = None
1590+
self, block_hash: Optional[str] = None, runtime: Optional[Runtime] = None
15911591
) -> list:
15921592
"""
1593-
Retrieves a list of all storage functions in metadata active at given block_hash (or chaintip if block_hash is
1594-
omitted)
1593+
Retrieves a list of all storage functions in metadata active at given block_hash (or chaintip if
1594+
block_hash and runtime are omitted)
15951595
15961596
Args:
15971597
block_hash: hash of the blockchain block whose runtime to use
@@ -4079,6 +4079,41 @@ async def result_handler(message: dict, subscription_id) -> tuple[dict, bool]:
40794079

40804080
return result
40814081

4082+
async def get_metadata_call_functions(
4083+
self, block_hash: Optional[str] = None, runtime: Optional[Runtime] = None
4084+
):
4085+
"""
4086+
Retrieves calls functions for the metadata at the specified block_hash or runtime. If neither are specified,
4087+
the metadata at chaintip is used.
4088+
4089+
Args:
4090+
block_hash: block hash to retrieve metadata for, unused if supplying runtime
4091+
runtime: Runtime object containing the metadata you wish to parse
4092+
4093+
Returns:
4094+
dict mapping {pallet name: {call name: {param name: param definition}}}
4095+
e.g.
4096+
{
4097+
"Sudo":{
4098+
"sudo": {
4099+
"_docs": "Authenticates the sudo key and dispatches a function call with `Root` origin.",
4100+
"call": {
4101+
"name": "call",
4102+
"type": 227,
4103+
"typeName": "Box<<T as Config>::RuntimeCall>",
4104+
"index": 0,
4105+
"_docs": ""
4106+
}
4107+
},
4108+
...
4109+
},
4110+
...
4111+
}
4112+
"""
4113+
if runtime is None:
4114+
runtime = await self.init_runtime(block_hash=block_hash)
4115+
return self._get_metadata_call_functions(runtime)
4116+
40824117
async def get_metadata_call_function(
40834118
self,
40844119
module_name: str,

async_substrate_interface/sync_substrate.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3291,6 +3291,37 @@ def result_handler(message: dict, subscription_id) -> tuple[dict, bool]:
32913291

32923292
return result
32933293

3294+
def get_metadata_call_functions(self, block_hash: Optional[str] = None):
3295+
"""
3296+
Retrieves calls functions for the metadata at the specified block_hash. If not specified, the metadata at
3297+
chaintip is used.
3298+
3299+
Args:
3300+
block_hash: block hash to retrieve metadata for
3301+
3302+
Returns:
3303+
dict mapping {pallet name: {call name: {param name: param definition}}}
3304+
e.g.
3305+
{
3306+
"Sudo":{
3307+
"sudo": {
3308+
"_docs": "Authenticates the sudo key and dispatches a function call with `Root` origin.",
3309+
"call": {
3310+
"name": "call",
3311+
"type": 227,
3312+
"typeName": "Box<<T as Config>::RuntimeCall>",
3313+
"index": 0,
3314+
"_docs": ""
3315+
}
3316+
},
3317+
...
3318+
},
3319+
...
3320+
}
3321+
"""
3322+
runtime = self.init_runtime(block_hash=block_hash)
3323+
return self._get_metadata_call_functions(runtime)
3324+
32943325
def get_metadata_call_function(
32953326
self,
32963327
module_name: str,

async_substrate_interface/types.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,3 +1002,21 @@ def generate_multisig_account(
10021002
)
10031003

10041004
return multi_sig_account
1005+
1006+
@staticmethod
1007+
def _get_metadata_call_functions(runtime: Runtime):
1008+
"""
1009+
See subclass `get_metadata_call_functions` for documentation.
1010+
"""
1011+
data = {}
1012+
for pallet in runtime.metadata.pallets:
1013+
data[pallet.name] = {}
1014+
for call in pallet.calls:
1015+
data[pallet.name][call.name] = {}
1016+
data[pallet.name][call.name]["_docs"] = " ".join(call["docs"].value)
1017+
for idx, field in enumerate(call.value.get("fields", [])):
1018+
field["index"] = idx
1019+
field_docs = field["docs"]
1020+
field["_docs"] = " ".join(field_docs)
1021+
data[pallet.name][call.name][field["name"]] = field
1022+
return data

tests/e2e_tests/test_substrate_addons.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,7 @@ async def test_retry_async_substrate_runtime_call_with_keyword_args():
126126

127127
def test_retry_sync_substrate_runtime_call_with_keyword_args():
128128
"""Test that runtime_call works with keyword arguments (parameter name conflict fix)."""
129-
with RetrySyncSubstrate(
130-
LATENT_LITE_ENTRYPOINT, retry_forever=True
131-
) as substrate:
129+
with RetrySyncSubstrate(LATENT_LITE_ENTRYPOINT, retry_forever=True) as substrate:
132130
# This should not raise TypeError due to parameter name conflict
133131
# The 'method' kwarg should not conflict with _retry's parameter
134132
result = substrate.runtime_call(

0 commit comments

Comments
 (0)