main.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import argparse
  2. from terra_sdk.client.lcd import AsyncLCDClient
  3. import asyncio
  4. from terra_sdk.core.wasm import (
  5. MsgExecuteContract,
  6. )
  7. from terra_sdk.key.mnemonic import MnemonicKey
  8. import base64
  9. def add_default_args(parser):
  10. parser.add_argument('--rpc', required=True, help='Terra lcd address')
  11. parser.add_argument('--chain-id', dest="chain_id", required=True, help='Chain ID')
  12. parser.add_argument('--mnemonic', dest="mnemonic", required=True, help='Mnemonic of the wallet to be used')
  13. parser.add_argument('--contract', dest="contract", required=True, help='Address of the Wormhole contract')
  14. parser = argparse.ArgumentParser(prog='terra_cli')
  15. subparsers = parser.add_subparsers(help='sub-command help', dest="command")
  16. gov_parser = subparsers.add_parser('execute_governance', help='Execute a governance VAA')
  17. add_default_args(gov_parser)
  18. gov_parser.add_argument('vaa', help='Hex encoded VAA')
  19. post_parser = subparsers.add_parser('post_message', help='Publish a message over the wormhole')
  20. add_default_args(post_parser)
  21. post_parser.add_argument('nonce', help='Nonce of the message', type=int)
  22. post_parser.add_argument('message', help='Hex-encoded message')
  23. gas_prices = {
  24. "uluna": "0.15",
  25. "usdr": "0.1018",
  26. "uusd": "0.15",
  27. "ukrw": "178.05",
  28. "umnt": "431.6259",
  29. "ueur": "0.125",
  30. "ucny": "0.97",
  31. "ujpy": "16",
  32. "ugbp": "0.11",
  33. "uinr": "11",
  34. "ucad": "0.19",
  35. "uchf": "0.13",
  36. "uaud": "0.19",
  37. "usgd": "0.2",
  38. }
  39. async def sign_and_broadcast(sequence, deployer, terra, *msgs):
  40. tx = await deployer.create_and_sign_tx(
  41. msgs=msgs, fee_denoms=["ukrw", "uusd", "uluna"], sequence=sequence, gas_adjustment=1.4,
  42. )
  43. result = await terra.tx.broadcast(tx)
  44. sequence += 1
  45. if result.is_tx_error():
  46. raise RuntimeError(result.raw_log)
  47. return result
  48. class ContractQuerier:
  49. def __init__(self, address, terra):
  50. self.address = address
  51. self.terra = terra
  52. def __getattr__(self, item):
  53. async def result_fxn(**kwargs):
  54. return await self.terra.wasm.contract_query(self.address, {item: kwargs})
  55. return result_fxn
  56. class Contract:
  57. def __init__(self, address, deployer, terra, sequence):
  58. self.address = address
  59. self.deployer = deployer
  60. self.terra = terra
  61. self.sequence = sequence
  62. def __getattr__(self, item):
  63. async def result_fxn(coins=None, **kwargs):
  64. execute = MsgExecuteContract(
  65. self.deployer.key.acc_address, self.address, {item: kwargs}, coins=coins
  66. )
  67. return await sign_and_broadcast(self.sequence, self.deployer, self.terra, execute)
  68. return result_fxn
  69. @property
  70. def query(self):
  71. return ContractQuerier(self.address, self.terra)
  72. async def main():
  73. args = parser.parse_args()
  74. async with AsyncLCDClient(
  75. args.rpc, args.chain_id, gas_prices=gas_prices, loop=asyncio.get_event_loop()
  76. ) as terra:
  77. deployer = terra.wallet(MnemonicKey(
  78. mnemonic=args.mnemonic))
  79. sequence = await deployer.sequence()
  80. wormhole = Contract(args.contract, deployer, terra, sequence)
  81. res = dict()
  82. if args.command == "execute_governance":
  83. res = await wormhole.submit_v_a_a(vaa=base64.b64encode(bytes.fromhex(args.vaa)).decode("utf-8"))
  84. elif args.command == "post_message":
  85. state = await wormhole.query.get_state()
  86. fee = state["fee"]
  87. res = await wormhole.post_message(nonce=args.nonce,
  88. message=base64.b64encode(bytes.fromhex(args.message)).decode("utf-8"),
  89. coins={fee["denom"]: fee["amount"]})
  90. print(res.logs[0].events_by_type["from_contract"])
  91. if __name__ == "__main__":
  92. asyncio.get_event_loop().run_until_complete(main())