mmgen-swaptxcreate: new --list-assets option; related cleanups
This commit is contained in:
parent
a46c3bbbee
commit
67ef5d3987
6 changed files with 97 additions and 21 deletions
|
|
@ -22,7 +22,7 @@ mmgen-txcreate: Create a cryptocoin transaction with MMGen- and/or non-MMGen
|
|||
"""
|
||||
|
||||
from .cfg import gc, Config
|
||||
from .util import fmt_list, async_run
|
||||
from .util import Msg, fmt_list, async_run
|
||||
|
||||
target = gc.prog_name.split('-')[1].removesuffix('create')
|
||||
|
||||
|
|
@ -73,6 +73,7 @@ opts_data = {
|
|||
+ according to BIP 125)
|
||||
-s -s, --swap-proto Swap protocol to use (Default: {x_dfl},
|
||||
+ Choices: {x_all})
|
||||
-s -S, --list-assets List available swap assets
|
||||
-- -v, --verbose Produce more verbose output
|
||||
b- -V, --vsize-adj= f Adjust transaction's estimated vsize by factor 'f'
|
||||
-s -x, --proxy=P Fetch the swap quote via SOCKS5 proxy ‘P’ (host:port)
|
||||
|
|
@ -104,6 +105,13 @@ opts_data = {
|
|||
|
||||
cfg = Config(opts_data=opts_data)
|
||||
|
||||
if cfg.list_assets:
|
||||
import sys
|
||||
from .tx.new_swap import get_swap_proto_mod
|
||||
sp = get_swap_proto_mod(cfg.swap_proto)
|
||||
Msg('AVAILABLE SWAP ASSETS:\n' + sp.SwapAsset('BTC', 'send').fmt_assets_data(indent=' '))
|
||||
sys.exit(0)
|
||||
|
||||
if not (cfg.info or cfg.contract_data) and len(cfg._args) < {'tx': 1, 'swaptx': 2}[target]:
|
||||
cfg._usage()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,19 +18,56 @@ from ..util import die
|
|||
|
||||
class SwapAsset:
|
||||
|
||||
_ad = namedtuple('swap_asset_data', ['desc', 'name', 'full_name', 'abbr'])
|
||||
_ad = namedtuple('swap_asset_data', ['desc', 'name', 'full_name', 'abbr', 'tested'])
|
||||
assets_data = {}
|
||||
send = ()
|
||||
recv = ()
|
||||
evm_contracts = {}
|
||||
unsupported = ()
|
||||
blacklisted = {}
|
||||
evm_chains = ()
|
||||
|
||||
def fmt_assets_data(self, indent=''):
|
||||
|
||||
def gen_good():
|
||||
fs = '%s{:10} {:23} {:9} {}' % indent
|
||||
yield fs.format('ASSET', 'DESCRIPTION', 'STATUS', 'CONTRACT ADDRESS')
|
||||
for k, v in self.assets_data.items():
|
||||
if not k in self.blacklisted:
|
||||
if k in self.send or k in self.recv:
|
||||
yield fs.format(
|
||||
k,
|
||||
v.desc,
|
||||
'tested' if v.tested else 'untested',
|
||||
self.evm_contracts.get(k,'-'))
|
||||
|
||||
def gen_bad():
|
||||
if self.blacklisted:
|
||||
fs = '%s{:10} {:23} {}' % indent
|
||||
yield '\n\nBlacklisted assets:'
|
||||
yield fs.format('ASSET', 'DESCRIPTION', 'REASON')
|
||||
for k, v in self.blacklisted.items():
|
||||
yield fs.format(k, self.assets_data[k].desc, v)
|
||||
|
||||
return '\n'.join(gen_good()) + '\n'.join(gen_bad())
|
||||
|
||||
@classmethod
|
||||
def get_full_name(self, s):
|
||||
for d in self.assets_data.values():
|
||||
def get_full_name(cls, s):
|
||||
for d in cls.assets_data.values():
|
||||
if s in (d.abbr, d.full_name):
|
||||
return d.full_name or f'{d.name}.{d.name}'
|
||||
die('SwapAssetError', f'{s!r}: unrecognized asset name or abbreviation')
|
||||
|
||||
@property
|
||||
def tested(self):
|
||||
return [k for k, v in self.assets_data.items() if v.tested]
|
||||
|
||||
@property
|
||||
def send(self):
|
||||
return set(self.assets_data) - set(self.unsupported) - set(self.blacklisted)
|
||||
|
||||
@property
|
||||
def recv(self):
|
||||
return set(self.assets_data) - set(self.unsupported) - set(self.blacklisted)
|
||||
|
||||
@property
|
||||
def chain(self):
|
||||
return self.data.full_name.split('.', 1)[0] if self.data.full_name else self.name
|
||||
|
|
|
|||
|
|
@ -18,14 +18,18 @@ class THORChainSwapAsset(SwapAsset):
|
|||
|
||||
_ad = SwapAsset._ad
|
||||
assets_data = {
|
||||
'BTC': _ad('Bitcoin', 'BTC', None, 'b'),
|
||||
'LTC': _ad('Litecoin', 'LTC', None, 'l'),
|
||||
'BCH': _ad('Bitcoin Cash', 'BCH', None, 'c'),
|
||||
'ETH': _ad('Ethereum', 'ETH', None, 'e'),
|
||||
'DOGE': _ad('Dogecoin', 'DOGE', None, 'd'),
|
||||
'RUNE': _ad('Rune (THORChain)', 'RUNE', 'THOR.RUNE', 'r'),
|
||||
'BTC': _ad('Bitcoin', 'BTC', None, 'b', True),
|
||||
'LTC': _ad('Litecoin', 'LTC', None, 'l', True),
|
||||
'BCH': _ad('Bitcoin Cash', 'BCH', None, 'c', True),
|
||||
'ETH': _ad('Ethereum', 'ETH', None, 'e', True),
|
||||
'DOGE': _ad('Dogecoin', 'DOGE', None, 'd', False),
|
||||
'RUNE': _ad('Rune (THORChain)', 'RUNE', 'THOR.RUNE', 'r', False),
|
||||
}
|
||||
|
||||
send = ('BTC', 'LTC', 'BCH', 'ETH')
|
||||
recv = ('BTC', 'LTC', 'BCH', 'ETH')
|
||||
evm_contracts = {}
|
||||
|
||||
unsupported = ('DOGE', 'RUNE')
|
||||
|
||||
blacklisted = {}
|
||||
|
||||
evm_chains = ('ETH', 'AVAX', 'BSC', 'BASE')
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class NewSwap(New):
|
|||
arg = get_arg()
|
||||
|
||||
# arg 3: chg_spec (change address spec)
|
||||
if args.send_amt and not (self.proto.is_evm or arg in sp.SwapAsset.recv): # is change arg
|
||||
if args.send_amt and not (self.proto.is_evm or arg in sa.recv): # is change arg
|
||||
nonlocal chg_output
|
||||
chg_output = await self.get_chg_output(arg, addrfiles)
|
||||
arg = get_arg()
|
||||
|
|
@ -124,12 +124,21 @@ class NewSwap(New):
|
|||
self.cfg._usage()
|
||||
|
||||
sp = self.swap_proto_mod
|
||||
sa = sp.SwapAsset('BTC', 'send')
|
||||
args_in = list(cmd_args)
|
||||
args = CmdlineArgs()
|
||||
chg_output = None
|
||||
|
||||
await parse()
|
||||
|
||||
for a in (self.send_asset, self.recv_asset):
|
||||
if a.name not in sa.tested:
|
||||
from ..util import msg, ymsg
|
||||
from ..term import get_char
|
||||
ymsg(f'Warning: {a.direction} asset {a.name} is untested by the MMGen Project')
|
||||
get_char('Press any key to continue: ')
|
||||
msg('')
|
||||
|
||||
if args.send_amt and not (chg_output or self.proto.is_evm):
|
||||
chg_output = await self.get_chg_output(None, addrfiles)
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@ class CmdTestSwap(CmdTestSwapMethods, CmdTestRegtest, CmdTestAutosignThreaded):
|
|||
need_daemon = True
|
||||
|
||||
cmd_group_in = (
|
||||
('list_assets', 'listing swap assets'),
|
||||
('subgroup.init_data', []),
|
||||
('subgroup.data', ['init_data']),
|
||||
('subgroup.init_swap', []),
|
||||
|
|
@ -416,6 +417,14 @@ class CmdTestSwap(CmdTestSwapMethods, CmdTestRegtest, CmdTestAutosignThreaded):
|
|||
def sid(self):
|
||||
return self._user_sid('bob')
|
||||
|
||||
def list_assets(self):
|
||||
t = self.spawn('mmgen-swaptxcreate', ['--list-assets'])
|
||||
t.expect('AVAILABLE')
|
||||
t.expect('ETH.MM1')
|
||||
t.expect('Blacklisted')
|
||||
t.expect('ETH.JUNK')
|
||||
return t
|
||||
|
||||
def walletcreate_bob(self):
|
||||
dest = Path(self.tr.data_dir, 'regtest', 'bob')
|
||||
dest.mkdir(exist_ok=True)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,21 @@ from .asset_orig import *
|
|||
class overlay_fake_THORChainSwapAsset:
|
||||
|
||||
assets_data = {
|
||||
'ETH.MM1': THORChainSwapAsset._ad('MM1 Token (ETH)', None, 'ETH.MM1', None),
|
||||
'ETH.USDT': THORChainSwapAsset._ad('Tether (ETH)', None, 'ETH.USDT', None)
|
||||
'ETH.USDT': THORChainSwapAsset._ad('Tether (ETH)', None, 'ETH.USDT', None, True),
|
||||
'ETH.MM1': THORChainSwapAsset._ad('MM1 Token (ETH)', None, 'ETH.MM1', None, True),
|
||||
'ETH.JUNK': THORChainSwapAsset._ad('Junk Token (ETH)', None, 'ETH.JUNK', None, True),
|
||||
'ETH.NONE': THORChainSwapAsset._ad('Unavailable Token (ETH)', None, 'ETH.NONE', None, True)
|
||||
}
|
||||
evm_contracts = {
|
||||
'ETH.MM1': 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
|
||||
}
|
||||
unsupported = ('ETH.NONE',)
|
||||
|
||||
blacklisted = {
|
||||
'ETH.JUNK': 'Because it’s junk',
|
||||
}
|
||||
send = ('ETH.MM1',)
|
||||
recv = ('ETH.MM1', 'ETH.USDT')
|
||||
|
||||
THORChainSwapAsset.assets_data |= overlay_fake_THORChainSwapAsset.assets_data
|
||||
THORChainSwapAsset.send += overlay_fake_THORChainSwapAsset.send
|
||||
THORChainSwapAsset.recv += overlay_fake_THORChainSwapAsset.recv
|
||||
THORChainSwapAsset.unsupported += overlay_fake_THORChainSwapAsset.unsupported
|
||||
THORChainSwapAsset.blacklisted.update(overlay_fake_THORChainSwapAsset.blacklisted)
|
||||
THORChainSwapAsset.evm_contracts.update(overlay_fake_THORChainSwapAsset.evm_contracts)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue