From 837583c5679d8716d50eb776447345d58568d640 Mon Sep 17 00:00:00 2001 From: LimpidCrypto <97235361+LimpidCrypto@users.noreply.github.com> Date: Tue, 21 Jun 2022 21:04:20 +0200 Subject: [PATCH] add subscribe_to_payment_paths --- poetry.lock | 6 +- xrpl_trading_bot/clients/__init__.py | 4 + xrpl_trading_bot/clients/main.py | 1 - xrpl_trading_bot/clients/methods.py | 75 ++++++++++++++++++- xrpl_trading_bot/globals/__init__.py | 7 +- xrpl_trading_bot/globals/variables.py | 1 + xrpl_trading_bot/main.py | 23 +++++- xrpl_trading_bot/test.py | 32 ++++++++ .../utils/order_book_changes_utils.py | 4 +- 9 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 xrpl_trading_bot/test.py diff --git a/poetry.lock b/poetry.lock index a7e6e0a..b4b4f8c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -561,7 +561,7 @@ python-versions = ">=3.7" [[package]] name = "xrpl-py" -version = "1.5.0" +version = "1.6.0" description = "A complete Python library for interacting with the XRP ledger" category = "main" optional = false @@ -918,8 +918,8 @@ websockets = [ {file = "websockets-10.3.tar.gz", hash = "sha256:fc06cc8073c8e87072138ba1e431300e2d408f054b27047d047b549455066ff4"}, ] xrpl-py = [ - {file = "xrpl-py-1.5.0.tar.gz", hash = "sha256:2ba56dd4c506d6069b53080e1710462459dbaed2697b0a81fc9e78a3ffcc6188"}, - {file = "xrpl_py-1.5.0-py3-none-any.whl", hash = "sha256:b3f8e5f1fa8277a296aa2e04860045f7fcf42917fed7d39d5548a87849c1f5b6"}, + {file = "xrpl-py-1.6.0.tar.gz", hash = "sha256:346ef998d7a4a4bceb861e722b9bf9f93d2c6ac7ef21ccad47120b990abc5ae5"}, + {file = "xrpl_py-1.6.0-py3-none-any.whl", hash = "sha256:08d3f1571f8b1a99a5fe142736d18eb775e70122e8af8eacfbfd34c6629bbd0e"}, ] zipp = [ {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"}, diff --git a/xrpl_trading_bot/clients/__init__.py b/xrpl_trading_bot/clients/__init__.py index ae7cf7d..59850a4 100644 --- a/xrpl_trading_bot/clients/__init__.py +++ b/xrpl_trading_bot/clients/__init__.py @@ -1,15 +1,19 @@ from xrpl_trading_bot.clients.main import xrp_request_async from xrpl_trading_bot.clients.methods import ( + build_path_finds, get_gateway_fees, subscribe_to_account_balances, subscribe_to_order_books, + subscribe_to_payment_paths, ) from xrpl_trading_bot.clients.websocket_uri import FullHistoryNodes, NonFullHistoryNodes __all__ = [ + "build_path_finds", "get_gateway_fees", "subscribe_to_account_balances", "subscribe_to_order_books", + "subscribe_to_payment_paths", "xrp_request_async", "FullHistoryNodes", "NonFullHistoryNodes", diff --git a/xrpl_trading_bot/clients/main.py b/xrpl_trading_bot/clients/main.py index 41aa572..796316a 100644 --- a/xrpl_trading_bot/clients/main.py +++ b/xrpl_trading_bot/clients/main.py @@ -34,5 +34,4 @@ async def xrp_request_async( async with AsyncWebsocketClient(url=uri) as client: requests_for_gather = [client.request(request) for request in requests] responses = await gather(*requests_for_gather) - return list(responses) diff --git a/xrpl_trading_bot/clients/methods.py b/xrpl_trading_bot/clients/methods.py index 49be1bc..df7be73 100644 --- a/xrpl_trading_bot/clients/methods.py +++ b/xrpl_trading_bot/clients/methods.py @@ -1,11 +1,20 @@ from asyncio import run from decimal import Decimal -from typing import Dict, List, cast +from typing import Dict, Generator, List, cast from websockets.exceptions import ConnectionClosedError from xrpl.clients import WebsocketClient -from xrpl.models import AccountInfo, AccountLines, IssuedCurrency, Response, Subscribe -from xrpl.models.requests.subscribe import SubscribeBook +from xrpl.models import ( + AccountInfo, + AccountLines, + IssuedCurrency, + IssuedCurrencyAmount, + PathFind, + PathFindSubcommand, + Response, + Subscribe, + SubscribeBook +) from xrpl.utils import drops_to_xrp from xrpl_trading_bot.clients.main import xrp_request_async @@ -177,6 +186,66 @@ def subscribe_to_order_books( return subscribe_books +def subscribe_to_payment_paths(path_finds: List[PathFind], all_payment_paths): + with WebsocketClient(FullHistoryNodes.XRPLF) as client: + for path_find in path_finds: + client.send(path_find) + for message in client: + result = message.get("result") + if result is not None: + destination_amount = result["destination_amount"] + alternatives = result["alternatives"] + else: + destination_amount = message["destination_amount"] + alternatives = message["alternatives"] + currency_id = ( + f"{destination_amount['currency']}.{destination_amount['issuer']}" + ) if isinstance(destination_amount, dict) else "XRP" + all_payment_paths[currency_id] = { + "value": destination_amount["value"] if ( + isinstance(destination_amount, dict) + ) else destination_amount, + "alternatives": alternatives, + } + + +def _chunk_path_finds( + path_finds: List[PathFind], +) -> Generator[List[PathFind], None, None]: + """Yield successive n-sized chunks from lst.""" + for i in range(0, len(path_finds), 5): + yield path_finds[i : i + 5] + + +def build_path_finds(wallet: XRPWallet) -> List[List[PathFind]]: + path_finds = [ + PathFind( + subcommand=PathFindSubcommand.CREATE, + source_account=wallet.classic_address, + destination_account=wallet.classic_address, + destination_amount="-1", + ), + ] + tokens = [ + currency for currency in wallet.balances.keys() if currency != "XRP" + ] + for token in tokens: + currency, issuer = token.split(".") + path_finds.append( + PathFind( + subcommand=PathFindSubcommand.CREATE, + source_account=wallet.classic_address, + destination_account=wallet.classic_address, + destination_amount=IssuedCurrencyAmount( + currency=currency, + issuer=issuer, + value=-1, + ), + ) + ) + return [list(pf) for pf in _chunk_path_finds(path_finds)] + + def get_gateway_fees(wallet: XRPWallet) -> Dict[str, Decimal]: balances = wallet.balances currencies = balances.keys() diff --git a/xrpl_trading_bot/globals/__init__.py b/xrpl_trading_bot/globals/__init__.py index 0b1878f..277bca9 100644 --- a/xrpl_trading_bot/globals/__init__.py +++ b/xrpl_trading_bot/globals/__init__.py @@ -1,8 +1,13 @@ from xrpl_trading_bot.globals.constants import WALLET -from xrpl_trading_bot.globals.variables import all_order_books, gateway_fees +from xrpl_trading_bot.globals.variables import ( + all_order_books, + gateway_fees, + all_payment_paths, +) __all__ = [ "all_order_books", + "all_payment_paths", "gateway_fees", "WALLET", ] diff --git a/xrpl_trading_bot/globals/variables.py b/xrpl_trading_bot/globals/variables.py index a5d00f9..9859b3d 100644 --- a/xrpl_trading_bot/globals/variables.py +++ b/xrpl_trading_bot/globals/variables.py @@ -7,3 +7,4 @@ all_order_books = OrderBooks() gateway_fees: Dict[str, Decimal] = {} +all_payment_paths = {} diff --git a/xrpl_trading_bot/main.py b/xrpl_trading_bot/main.py index 8cdbf39..1504d8c 100644 --- a/xrpl_trading_bot/main.py +++ b/xrpl_trading_bot/main.py @@ -10,8 +10,17 @@ subscribe_to_account_balances, subscribe_to_order_books, ) -from xrpl_trading_bot.clients.methods import get_gateway_fees -from xrpl_trading_bot.globals import WALLET, all_order_books, gateway_fees +from xrpl_trading_bot.clients.methods import ( + build_path_finds, + get_gateway_fees, + subscribe_to_payment_paths, +) +from xrpl_trading_bot.globals import ( + WALLET, + all_order_books, + gateway_fees, + all_payment_paths, +) from xrpl_trading_bot.order_books import build_subscription_books if __name__ == "__main__": @@ -21,6 +30,14 @@ ) balances_subscribtion.start() sleep(5) + path_finds = build_path_finds(wallet=WALLET) + + paths_threads = [ + Thread(target=subscribe_to_payment_paths, args=(chunk, all_payment_paths, )) + for chunk in path_finds + ] + for thread in paths_threads: + thread.start() gateway_fees.update(get_gateway_fees(wallet=WALLET)) subscribe_books = build_subscription_books(wallet=WALLET) subscribe_book_threads: List[Thread] = [ @@ -38,5 +55,7 @@ if num % 5 == 0: sleep(10) balances_subscribtion.join() + for thread in paths_threads: + thread.join() for thread in subscribe_book_threads: thread.join() diff --git a/xrpl_trading_bot/test.py b/xrpl_trading_bot/test.py new file mode 100644 index 0000000..3bc1088 --- /dev/null +++ b/xrpl_trading_bot/test.py @@ -0,0 +1,32 @@ +from threading import Thread +from xrpl.models import IssuedCurrencyAmount, PathFindSubcommand, PathFind +from xrpl.clients import WebsocketClient + + +def sub(): + with WebsocketClient("wss://xrplcluster.com/") as client: + req = PathFind( + subcommand=PathFindSubcommand.CREATE, + source_account="rPu2feBaViWGmWJhvaF5yLocTVD8FUxd2A", + destination_account="rPu2feBaViWGmWJhvaF5yLocTVD8FUxd2A", + destination_amount="-1" + ) + req2 = PathFind( + subcommand=PathFindSubcommand.CREATE, + source_account="rPu2feBaViWGmWJhvaF5yLocTVD8FUxd2A", + destination_account="rPu2feBaViWGmWJhvaF5yLocTVD8FUxd2A", + destination_amount=IssuedCurrencyAmount( + currency="USD", + issuer="rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + value=-1 + ) + ) + client.send(req) + client.send(req2) + for message in client: + print(message) + + +t = Thread(target=sub) +t.start() +t.join() diff --git a/xrpl_trading_bot/txn_parser/utils/order_book_changes_utils.py b/xrpl_trading_bot/txn_parser/utils/order_book_changes_utils.py index c756bd7..01404e4 100644 --- a/xrpl_trading_bot/txn_parser/utils/order_book_changes_utils.py +++ b/xrpl_trading_bot/txn_parser/utils/order_book_changes_utils.py @@ -558,9 +558,9 @@ def _derive_quality( quality = Decimal(taker_gets_value) / Decimal(taker_pays_value) if possible_currency_pair != pair: - return _format_quality("{:.12}".format(1 / quality)) + return _format_quality("{:.14}".format(1 / quality)) - return _format_quality("{:.12}".format(quality)) + return _format_quality("{:.14}".format(quality)) def _derive_unfunded_amounts(