Skip to content

Commit

Permalink
Added payment info function for fee estimation #45
Browse files Browse the repository at this point in the history
  • Loading branch information
Arjan Zijderveld committed Nov 10, 2020
1 parent 36a6e1a commit 17b4efb
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
49 changes: 46 additions & 3 deletions substrateinterface/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1117,18 +1117,18 @@ def create_signed_extrinsic(self, call, keypair: Keypair, era=None, nonce=None,
raise TypeError("'call' must be of type Call")

# Retrieve nonce
if not nonce:
if nonce is None:
nonce = self.get_account_nonce(keypair.public_key) or 0

# Process era
if not era:
if era is None:
era = '00'
else:
if isinstance(era, dict) and 'current' not in era and 'phase' not in era:
# Retrieve current block id
era['current'] = self.get_block_number(self.get_chain_finalised_head())

if signature:
if signature is not None:

signature = signature.replace('0x', '')

Expand Down Expand Up @@ -1237,6 +1237,49 @@ def result_handler(result):

return response

def get_payment_info(self, call, keypair):
"""
Retrieves fee estimation via RPC for given extrinsic
Parameters
----------
call Call object to estimate fees for
keypair Keypair of the sender, does not have to include private key because no valid signature is required
Returns
-------
Dict with payment info
E.g. {'class': 'normal', 'partialFee': 151000000, 'weight': 217238000}
"""

# Check requirements
if not isinstance(call, GenericCall):
raise TypeError("'call' must be of type Call")

if not isinstance(keypair, Keypair):
raise TypeError("'keypair' must be of type Keypair")

# No valid signature is required for fee estimation
signature = '0x' + '00' * 64

# Create extrinsic
extrinsic = self.create_signed_extrinsic(
call=call,
keypair=keypair,
signature=signature
)

payment_info = self.rpc_request('payment_queryInfo', [str(extrinsic.data)])

# convert partialFee to int
if 'result' in payment_info:
payment_info['result']['partialFee'] = int(payment_info['result']['partialFee'])
return payment_info['result']
else:
raise SubstrateRequestException(payment_info['error']['message'])

def process_metadata_typestring(self, type_string):
"""
Process how given type_string is decoded with active runtime and type registry
Expand Down
19 changes: 19 additions & 0 deletions test/test_create_extrinsics.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,25 @@ def test_create_unsigned_extrinsic(self):
extrinsic = self.kusama_substrate.create_unsigned_extrinsic(call)
self.assertEqual(str(extrinsic.data), '0x280402000ba09cc0317501')

def test_payment_info(self):
keypair = Keypair(ss58_address="EaG2CRhJWPb7qmdcJvy3LiWdh26Jreu9Dx6R1rXxPmYXoDk")

call = self.kusama_substrate.compose_call(
call_module='Balances',
call_function='transfer',
call_params={
'dest': 'EaG2CRhJWPb7qmdcJvy3LiWdh26Jreu9Dx6R1rXxPmYXoDk',
'value': 2 * 10 ** 3
}
)
payment_info = self.kusama_substrate.get_payment_info(call=call, keypair=keypair)

self.assertIn('class', payment_info)
self.assertIn('partialFee', payment_info)
self.assertIn('weight', payment_info)

self.assertGreater(payment_info['partialFee'], 0)


if __name__ == '__main__':
unittest.main()

0 comments on commit 17b4efb

Please sign in to comment.