From 10a6a74a173a625e6b837cd4fefe1739f8fd5761 Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 31 Jan 2024 16:39:09 +0100 Subject: [PATCH] Migrate BestOrders to mmrpc 2.0 (#110) * Migrate BestOrders to mmrpc 2.0 Leaving the BestOrder and BestOrders attributes unchanged to minimise the impact * Fix empty best orders list ARRR has no `address_data` as it is a `Shielded` address, so we cannot use address to filter ARRR top orders. --- lib/model/best_order.dart | 28 +++++++++++++++++------- lib/model/get_best_orders.dart | 17 +++++++++----- lib/model/swap_constructor_provider.dart | 9 +++++++- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/lib/model/best_order.dart b/lib/model/best_order.dart index a86593781..e0e7f74b7 100644 --- a/lib/model/best_order.dart +++ b/lib/model/best_order.dart @@ -12,11 +12,14 @@ class BestOrders { if (json['result'] == null) return bestOrders; final Market action = bestOrders.request.action; + final Map result = json['result']; + final Map resultOrders = + result['orders'] as Map; - json['result'].forEach((String ticker, dynamic items) { + resultOrders.forEach((String ticker, dynamic items) { bestOrders.result ??= {}; final List list = []; - for (dynamic item in items) { + for (final Map item in items) { item['action'] = action; item['other_coin'] = action == Market.SELL ? bestOrders.request.coin : ticker; @@ -45,15 +48,24 @@ class BestOrder { }); factory BestOrder.fromJson(Map json) { + final Map price = json['price']; + final Map address = json['address']; + + // base_ max and min volume are used, as the base and rel coins are swapped + // for buy and sell orders, so the max volume is always the max volume of + // the base coin. The web wallet has a similar implementation. + final Map maxVolume = json['base_max_volume']; + final Map minVolume = json['base_min_volume']; + return BestOrder( - price: fract2rat(json['price_fraction']) ?? Rational.parse(json['price']), - maxVolume: fract2rat(json['max_volume_fraction']) ?? - Rational.parse(json['maxvolume']), - minVolume: fract2rat(json['min_volume_fraction']) ?? - Rational.parse(json['min_volume']), + price: fract2rat(price['fraction']) ?? Rational.parse(price['decimal']), + maxVolume: fract2rat(maxVolume['fraction']) ?? + Rational.parse(maxVolume['decimal']), + minVolume: fract2rat(minVolume['fraction']) ?? + Rational.parse(minVolume['decimal']), coin: json['coin'], otherCoin: json['other_coin'], - address: json['address'], + address: address['address_data'], action: json['action'], ); } diff --git a/lib/model/get_best_orders.dart b/lib/model/get_best_orders.dart index 942c9d898..a19be2d4a 100644 --- a/lib/model/get_best_orders.dart +++ b/lib/model/get_best_orders.dart @@ -8,6 +8,7 @@ class GetBestOrders { GetBestOrders({ this.userpass, this.method = 'best_orders', + this.mmrpc = '2.0', this.coin, this.volume, this.action, @@ -15,6 +16,7 @@ class GetBestOrders { String userpass; String method; + String mmrpc; String coin; Rational volume; Market action; @@ -22,11 +24,14 @@ class GetBestOrders { Map toJson() => { 'method': method, 'userpass': userpass, - 'coin': coin, - 'volume': { - 'numer': volume.numerator.toString(), - 'denom': volume.denominator.toString(), - }, - 'action': action == Market.BUY ? 'buy' : 'sell', + 'mmrpc': mmrpc, + 'params': { + 'coin': coin, + 'action': action == Market.BUY ? 'buy' : 'sell', + 'request_by': { + 'type': 'volume', + 'value': volume.toDecimalString(), + } + } }; } diff --git a/lib/model/swap_constructor_provider.dart b/lib/model/swap_constructor_provider.dart index cb2471990..09662d35c 100644 --- a/lib/model/swap_constructor_provider.dart +++ b/lib/model/swap_constructor_provider.dart @@ -332,11 +332,18 @@ class ConstructorProvider extends ChangeNotifier { BestOrder getTickerTopOrder(List tickerOrdersList, Market type) { final List sorted = List.from(tickerOrdersList); + // This code appears to remove orders placed by the current wallet + // so that the user doesn't trade with themselves sorted.removeWhere((BestOrder order) { final String coin = order.action == Market.SELL ? order.coin : order.otherCoin; final CoinBalance coinBalance = coinsBloc.getBalanceByAbbr(coin); - if (coinBalance == null) return false; + + // ZHTLC address is null (Shielded), so we can't check it. + // This removes the protection against users taking their own maker orders + if (coinBalance == null || order.address == null) { + return false; + } return coinBalance.balance.address.toLowerCase() == order.address.toLowerCase(); });