online.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #!/usr/bin/env python3
  2. #
  3. # MMGen Wallet, a terminal-based cryptocurrency wallet
  4. # Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen-wallet
  9. # https://gitlab.com/mmgen/mmgen-wallet
  10. """
  11. proto.eth.tx.online: Ethereum online signed transaction class
  12. """
  13. from ....util import msg, die
  14. from ....color import yellow, green, orange
  15. from ....tx import online as TxBase
  16. from .. import erigon_sleep
  17. from .signed import Signed, TokenSigned
  18. class OnlineSigned(Signed, TxBase.OnlineSigned):
  19. async def test_sendable(self, txhex):
  20. raise NotImplementedError('transaction testing not implemented for Ethereum')
  21. async def send_checks(self):
  22. self.check_correct_chain()
  23. if not self.disable_fee_check and (self.fee > self.proto.max_tx_fee):
  24. die(2, 'Transaction fee ({}) greater than {} max_tx_fee ({} {})!'.format(
  25. self.fee,
  26. self.proto.name,
  27. self.proto.max_tx_fee,
  28. self.proto.coin))
  29. await self.status.display()
  30. async def send_with_node(self, txhex):
  31. try:
  32. ret = await self.rpc.call('eth_sendRawTransaction', '0x' + txhex)
  33. except Exception as e:
  34. msg(orange('\n'+str(e)))
  35. die(2, f'Send of MMGen transaction {self.txid} failed')
  36. await erigon_sleep(self)
  37. return ret.removeprefix('0x')
  38. async def post_network_send(self, coin_txid):
  39. res = await self.get_receipt(coin_txid)
  40. if not res:
  41. if self.cfg.wait:
  42. msg('{} {} {}'.format(
  43. yellow('Send of'),
  44. coin_txid.hl(),
  45. yellow('failed? (failed to get receipt)')))
  46. return False
  47. msg(f'Gas sent: {res.gas_sent.hl()}\n'
  48. f'Gas used: {res.gas_used.hl()}')
  49. if res.status == 0:
  50. if res.gas_used == res.gas_sent:
  51. msg(yellow('All gas was used!'))
  52. msg('{} {} {}'.format(
  53. yellow('Send of'),
  54. coin_txid.hl(),
  55. yellow('failed (status=0)')))
  56. return False
  57. msg(f'Status: {green(str(res.status))}')
  58. if res.contract_addr:
  59. msg('Contract address: {}'.format(res.contract_addr.hl(0)))
  60. return True
  61. class TokenOnlineSigned(TokenSigned, OnlineSigned):
  62. def parse_txfile_serialized_data(self):
  63. from ....addr import ContractAddr
  64. from ..contract import Token
  65. OnlineSigned.parse_txfile_serialized_data(self)
  66. o = self.txobj
  67. assert self.twctl.token == o['to']
  68. o['token_addr'] = ContractAddr(self.proto, o['to'])
  69. o['decimals'] = self.twctl.decimals
  70. t = Token(self.cfg, self.proto, o['token_addr'], decimals=o['decimals'])
  71. o['amt'] = t.transferdata2amt(o['data'])
  72. o['token_to'] = t.transferdata2sendaddr(o['data'])
  73. class Sent(TxBase.Sent, OnlineSigned):
  74. pass
  75. class TokenSent(TxBase.Sent, TokenOnlineSigned):
  76. pass
  77. class AutomountOnlineSigned(TxBase.AutomountOnlineSigned, OnlineSigned):
  78. pass
  79. class AutomountSent(TxBase.AutomountSent, AutomountOnlineSigned):
  80. pass
  81. class TokenAutomountOnlineSigned(TxBase.AutomountOnlineSigned, TokenOnlineSigned):
  82. pass
  83. class TokenAutomountSent(TxBase.AutomountSent, TokenAutomountOnlineSigned):
  84. pass