tx.new_swap, tx.base, ThornodeRPCServer: minor fixes and cleanups

This commit is contained in:
The MMGen Project 2026-10-12 10:04:48 +00:00
commit 226995cfc7
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
4 changed files with 45 additions and 35 deletions

View file

@ -117,7 +117,7 @@ class Base(MMGenObject):
class OutputList(MMGenTxIOList):
desc = 'transaction outputs'
def __init__(self, *, cfg, proto, twctl=None, **kwargs):
def __init__(self, *, cfg, proto, twctl=None, target=None, automount=None):
self.cfg = cfg
self.inputs = self.InputList(self)
self.outputs = self.OutputList(self)
@ -126,6 +126,14 @@ class Base(MMGenObject):
self.twctl = twctl
self.is_token = 'Token' in self.name
@property
def data_desc(self):
def gen():
if self.is_swap:
yield 'swap'
yield 'transaction data'
return ' '.join(gen())
@property
def coin(self):
return self.proto.coin
@ -246,20 +254,19 @@ class Base(MMGenObject):
else: # backwards-compatibility workaround
from ..swap.asset import SwapAsset
x = '[unknown]'
return SwapAsset._ad(x, x, x, x, x)
return SwapAsset._ad(x, x, x, x, x, x)
def check_swap_network(self):
rpc = self.swap_proto_rpc
data = rpc.inbound_addrs()
for asset in (self.send_asset, self.recv_asset):
if asset.name == 'RUNE':
continue
for key, state in (
('global_trading_paused', 'paused'),
('chain_trading_paused', f'paused for asset {asset.name}'),
('halted', f'halted for asset {asset.name}')):
if rpc.data_for_coin(data, asset.coin)[key]:
die(2, f'Trading is {state} on the {self.swap_proto_mod.name} network')
if asset.name != 'RUNE':
for key, state in (
('global_trading_paused', 'paused'),
('chain_trading_paused', f'paused for asset {asset.name}'),
('halted', f'halted for asset {asset.name}')):
if rpc.data_for_coin(data, asset.coin)[key]:
die(2, f'Trading is {state} on the {self.swap_proto_mod.name} network')
# token methods:
@property

View file

@ -49,7 +49,7 @@ class TxInfo:
def gen_view():
yield (self.txinfo_hdr_fs_short if terse else self.txinfo_hdr_fs).format(
hdr = cyan(('SWAP ' if tx.is_swap else '') + 'TRANSACTION DATA'),
hdr = cyan(tx.data_desc.upper()),
i = tx.txid.hl(),
a = tx.send_amt.hl(),
c = tx.dcoin,

View file

@ -29,18 +29,18 @@ def get_send_proto(cfg):
class NewSwap(New):
desc = 'swap transaction'
swap_quote_refresh_timeout = 30
_output = namedtuple('swap_output', ['coin', 'network', 'addr', 'mmid'])
def __init__(self, *, cfg, **kwargs):
self.is_swap = True
self.swap_proto = cfg.swap_proto
New.__init__(self, cfg=cfg, **kwargs)
self.is_swap = True
super().__init__(cfg=cfg, **kwargs)
def check_addr_is_wallet_addr(self, output, *, message):
if not output.mmid:
self._non_wallet_addr_confirm(message)
async def get_swap_output(self, proto, arg, addrfiles, desc):
ret = namedtuple('swap_output', ['coin', 'network', 'addr', 'mmid'])
if arg:
from ..addrdata import TwAddrData
pa = self.parse_cmdline_arg(
@ -50,12 +50,12 @@ class NewSwap(New):
await TwAddrData(self.cfg, proto))
if pa.addr:
await self.warn_addr_used(proto, pa, f'{desc} address')
return ret(proto.coin, proto.network, pa.addr, pa.mmid)
return self._output(proto.coin, proto.network, pa.addr, pa.mmid)
full_desc = f'{desc} address on the {proto.coin} {proto.network} network'
res = await self.get_autochg_addr(proto, arg, exclude=[], desc=full_desc)
self.confirm_autoselected_addr(res.twmmid, res.comment, full_desc)
return ret(proto.coin, proto.network, res.addr, res.twmmid)
return self._output(proto.coin, proto.network, res.addr, res.twmmid)
async def get_chg_output(self, arg, addrfiles):
chg_output = await self.get_swap_output(self.proto, arg, addrfiles, 'change')
@ -106,7 +106,8 @@ class NewSwap(New):
arg = get_arg()
# arg 4: recv_coin
self.swap_recv_asset_spec = arg # this goes into the transaction file
# this goes into the transaction file:
self.swap_recv_asset_spec = sp.SwapAsset(arg, 'recv').name # used by ‘recv_asset’ property
self.recv_proto = init_swap_proto(self.cfg, self.recv_asset)
# arg 5: recv_spec (receive address spec)
@ -179,12 +180,22 @@ class NewSwap(New):
return tuple(ret + [f'data:{memo}'])
async def display_quote_loop(self, qd, *, deduct_est_fee=False):
from ..term import get_char
while True:
await self.display_quote(qd, deduct_est_fee=deduct_est_fee)
ch = get_char('Press ‘r’ to refresh quote, any other key to continue: ')
msg('')
if ch not in 'Rr':
break
async def display_quote(self, qd, *, deduct_est_fee=False, skip_est_fee=False):
self.cfg._util.qmsg(f'Retrieving data from {qd.rpc.swap_api.host}...')
qd.get_quote(self.swap_cfg)
self.cfg._util.qmsg('OK')
self.swap_quote_refresh_time = time.time()
await self.set_gas(to_addr=qd.router if self.is_token else None)
if not skip_est_fee:
await self.set_gas(to_addr=qd.router if self.is_token else None)
msg(await qd.format_quote(deduct_est_fee=deduct_est_fee, skip_est_fee=skip_est_fee))
def update_vault_addr(self, qd, *, addr='inbound_address'):
@ -203,14 +214,8 @@ class NewSwap(New):
trade_limit = trade_limit)
async def update_vault_output(self, amt, *, deduct_est_fee=False):
from ..term import get_char
qd = self.swap_proto_mod.quote_client(self, amt)
while True:
await self.display_quote(qd, deduct_est_fee=deduct_est_fee)
ch = get_char('Press ‘r’ to refresh quote, any other key to continue: ')
msg('')
if ch not in 'Rr':
break
await self.display_quote_loop(qd, deduct_est_fee=deduct_est_fee)
self.swap_quote_expiry = qd.data['expiry']
self.update_vault_addr(qd)
self.update_data_output(qd.trade_limit)

View file

@ -44,10 +44,11 @@ class ThornodeRPCServer(ThornodeServer):
'thorchain': 28043387}]
memo_info = {
'reference': '13579',
'asset': 'LTC.LTC',
'memo': '=:c:qq6myf0qd6q5tln96ntl37hq0u7940w2xvs9jsuqv0:0/3/0',
'height': '12345678'}
'0c7454c0': { # 0c7454c06d3fc0e520d34283e6f491ce7afe5abb3f569bbdfea1732e04b716ec
'reference': '13579',
'asset': 'LTC.LTC',
'memo': '=:c:qq6myf0qd6q5tln96ntl37hq0u7940w2xvs9jsuqv0:0/3/0',
'height': '12345678'}}
inbounds_info = get_inbounds_info()
@ -102,13 +103,10 @@ class ThornodeRPCServer(ThornodeServer):
'codespace': ''}
def broadcast_tx_sync(m, length):
from mmgen.proto.rune.tx.protobuf import RuneTx
txhex = environ['wsgi.input'].read(length).decode().removeprefix('tx=0x').upper()
res = {'code': 0, 'codespace': '', 'data': '', 'log': ''}
if txhex.startswith('0A540A52'):
res.update({'hash': '14463C716CF08A814868DB779156BCD85A1DF8EE49E924900A74482E9DEE132D'})
elif txhex.startswith('0AC1010A'):
res.update({'hash': 'BD30B8FD9FC278A26E7A81ABB36C4709260DE64087EB578900BD23CEBF11D1A2'})
return res
tx = RuneTx.loads(bytes.fromhex(txhex))
return {'code': 0, 'codespace': '', 'data': '', 'log': '', 'hash': tx.txid}
def ping(m, length):
return self.ping_info