1+ import asyncio
2+ import logging
3+
4+ from pyinjective .composer import Composer as ProtoMsgComposer
5+ from pyinjective .async_client import AsyncClient
6+ from pyinjective .transaction import Transaction
7+ from pyinjective .constant import Network
8+ from pyinjective .wallet import PrivateKey
9+
10+
11+ async def main () -> None :
12+ # select network: local, testnet, mainnet
13+ network = Network .testnet ()
14+ composer = ProtoMsgComposer (network = network .string ())
15+
16+ # initialize grpc client
17+ # set custom cookie location (optional) - defaults to current dir
18+ client = AsyncClient (network , insecure = False )
19+ await client .sync_timeout_height ()
20+
21+ # load account
22+ priv_key = PrivateKey .from_hex ("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3" )
23+ pub_key = priv_key .to_public_key ()
24+ address = pub_key .to_address ()
25+ account = await client .get_account (address .to_acc_bech32 ())
26+
27+ # prepare tx msg
28+ # NOTE: COIN MUST BE SORTED IN ALPHABETICAL ORDER BY DENOMS
29+ funds = [
30+ composer .Coin (amount = 69 , denom = 'factory/inj1hdvy6tl89llqy3ze8lv6mz5qh66sx9enn0jxg6/inj12ngevx045zpvacus9s6anr258gkwpmthnz80e9' ),
31+ composer .Coin (amount = 420 , denom = 'peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7' ),
32+ composer .Coin (amount = 1 , denom = 'peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5' ),
33+ ]
34+ msg = composer .MsgExecuteContract (
35+ sender = address .to_acc_bech32 (),
36+ contract = "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7" ,
37+ msg = '{"increment":{}}' ,
38+ funds = funds
39+ )
40+
41+ # build sim tx
42+ tx = (
43+ Transaction ()
44+ .with_messages (msg )
45+ .with_sequence (client .get_sequence ())
46+ .with_account_num (client .get_number ())
47+ .with_chain_id (network .chain_id )
48+ )
49+ sim_sign_doc = tx .get_sign_doc (pub_key )
50+ sim_sig = priv_key .sign (sim_sign_doc .SerializeToString ())
51+ sim_tx_raw_bytes = tx .get_tx_data (sim_sig , pub_key )
52+
53+ # simulate tx
54+ (sim_res , success ) = await client .simulate_tx (sim_tx_raw_bytes )
55+ if not success :
56+ print (sim_res )
57+ return
58+
59+ # build tx
60+ gas_price = 500000000
61+ gas_limit = sim_res .gas_info .gas_used + 20000 # add 20k for gas, fee computation
62+ gas_fee = '{:.18f}' .format ((gas_price * gas_limit ) / pow (10 , 18 )).rstrip ('0' )
63+ fee = [composer .Coin (
64+ amount = gas_price * gas_limit ,
65+ denom = network .fee_denom ,
66+ )]
67+ tx = tx .with_gas (gas_limit ).with_fee (fee ).with_memo ('' ).with_timeout_height (client .timeout_height )
68+ sign_doc = tx .get_sign_doc (pub_key )
69+ sig = priv_key .sign (sign_doc .SerializeToString ())
70+ tx_raw_bytes = tx .get_tx_data (sig , pub_key )
71+
72+ # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
73+ res = await client .send_tx_sync_mode (tx_raw_bytes )
74+ print (res )
75+ print ("gas wanted: {}" .format (gas_limit ))
76+ print ("gas fee: {} INJ" .format (gas_fee ))
77+
78+ if __name__ == "__main__" :
79+ logging .basicConfig (level = logging .INFO )
80+ asyncio .get_event_loop ().run_until_complete (main ())
0 commit comments