From 4fa8e32400693aa3463fd16c3589b1c9d60cf594 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 7 Oct 2026 16:40:39 +0000 Subject: [PATCH] mmgen-remote: new `quote` command --- mmgen/data/version | 2 +- mmgen/proto/rune/rpc/remote.py | 9 +++++++++ mmgen/swap/util.py | 5 +++++ mmgen/tool/__init__.py | 4 ++++ mmgen/tx/new_swap.py | 4 ++-- test/cmdtest_d/remote.py | 4 ++++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/mmgen/data/version b/mmgen/data/version index c2011b31..1b1edcf4 100644 --- a/mmgen/data/version +++ b/mmgen/data/version @@ -1 +1 @@ -16.3.0dev13 +16.3.0dev14 diff --git a/mmgen/proto/rune/rpc/remote.py b/mmgen/proto/rune/rpc/remote.py index 462bc102..c3b3d65c 100644 --- a/mmgen/proto/rune/rpc/remote.py +++ b/mmgen/proto/rune/rpc/remote.py @@ -63,6 +63,7 @@ class THORChainRemoteRPCClient(RemoteRPCClient): 'inbound_addrs', 'acct_info', 'balance', + 'quote', 'tx_info')} def __init__(self, cfg, proto): @@ -138,6 +139,14 @@ class THORChainRemoteRPCClient(RemoteRPCClient): assert len(rune_res) == 1, f'{rune_res}: result length is not one!' return self.proto.coin_amt(int(rune_res[0]['amount']), from_unit='satoshi') + def quote(self, send_asset: str, recv_asset: str, amt: Decimal): + "get a swap quote for a given send asset, receive asset and amount" + from ....swap.util import init_swap_proto, get_swap_asset + from_asset = get_swap_asset(self.cfg, send_asset, direction='send') + to_asset = get_swap_asset(self.cfg, recv_asset, direction='recv') + send_amt = init_swap_proto(self.cfg, from_asset).coin_amt(str(amt)) + return self.get_quote(from_asset, to_asset, send_amt) + def get_quote(self, from_asset, to_asset, amt, *, amt_is_atomic=False): from ....swap.util import get_swap_proto_mod swap_cfg = get_swap_proto_mod(self.swap_proto).SwapCfg(self.cfg) diff --git a/mmgen/swap/util.py b/mmgen/swap/util.py index 37d7aea1..0106105f 100644 --- a/mmgen/swap/util.py +++ b/mmgen/swap/util.py @@ -26,3 +26,8 @@ def init_swap_proto(cfg, asset): asset.coin, tokensym = asset.tokensym, need_amt = True) + +def get_swap_asset(cfg, asset, *, direction='send'): + "given an asset symbol, and optionally direction, return a swap asset instance" + assert isinstance(asset, str), '‘asset’ must be a string' + return get_swap_proto_mod(cfg.swap_proto).SwapAsset(asset, direction) diff --git a/mmgen/tool/__init__.py b/mmgen/tool/__init__.py index bf10c226..73242a87 100644 --- a/mmgen/tool/__init__.py +++ b/mmgen/tool/__init__.py @@ -125,6 +125,10 @@ def process_args(cmd, cmd_args, cls): arg = False else: die(1, f'{arg!r}: invalid boolean value for keyword argument') + elif arg_type == 'Decimal': + from decimal import Decimal + Decimal(arg) # check without converting + return arg try: return __builtins__[arg_type](arg) diff --git a/mmgen/tx/new_swap.py b/mmgen/tx/new_swap.py index 9a997cc8..8071a02b 100644 --- a/mmgen/tx/new_swap.py +++ b/mmgen/tx/new_swap.py @@ -13,7 +13,7 @@ tx.new_swap: new swap transaction class from collections import namedtuple from ..amt import UniAmt -from ..swap.util import get_swap_proto_mod, init_swap_proto +from ..swap.util import get_swap_asset, init_swap_proto from .new import New @@ -22,7 +22,7 @@ def get_send_proto(cfg): arg = cfg._args.pop(0) except: cfg._usage() - return init_swap_proto(cfg, get_swap_proto_mod(cfg.swap_proto).SwapAsset(arg, 'send')) + return init_swap_proto(cfg, get_swap_asset(cfg, arg, direction='send')) class NewSwap(New): desc = 'swap transaction' diff --git a/test/cmdtest_d/remote.py b/test/cmdtest_d/remote.py index 96d0c8f7..c9760d17 100644 --- a/test/cmdtest_d/remote.py +++ b/test/cmdtest_d/remote.py @@ -34,6 +34,7 @@ class CmdTestRemote(CmdTestBase, CmdTestSwapMethods, CmdTestRuneMethods): ('actions_addr', 'getting actions for address'), ('actions_txid', 'getting actions for txid'), ('actions_addr_txid', 'getting actions for txid and addr'), + ('quote', 'getting a swap quote'), ('stop_thornode_servers','stopping the Thornode RPC and Midgard servers')) def __init__(self, cfg, trunner, cfgs, spawn): @@ -81,5 +82,8 @@ class CmdTestRemote(CmdTestBase, CmdTestSwapMethods, CmdTestRuneMethods): def actions_addr_txid(self): return self._rune_remote('actions', ['addr=thor1abcdefg', 'txid=deadbeef']) + def quote(self): + return self._rune_remote('quote', ['BTC', 'LTC', '1.2345']) + def stop_servers(self): self.stop_thornode_servers(['rpc','midgard'])