feat(swap): rpc to find best swap with liquidity routing for ask#2362
feat(swap): rpc to find best swap with liquidity routing for ask#2362
Conversation
* dev: fix(derive_key_from_path): check length of current_key_material (#2356) chore(release): bump mm2 version to 2.4.0-beta (#2346) fix(tests): add additional testnet sepolia nodes to test code (#2358) fix(swaps): maintain legacy compatibility for negotiation messages (#2353) refactor(SwapOps): impl defaults for protocol specific swapops fns (#2354) feat(tpu-v2): provide swap protocol versioning (#2324) feat(wallet): add change mnemonic password rpc (#2317) fix(tpu-v2): fix tpu-v2 wait for payment spend and extract secret (#2261) feat(tendermint): unstaking/undelegation (#2330) fix(utxo-withdraw): get hw ctx only when `PrivKeyPolicy` is trezor (#2333) feat(event-streaming): API-driven subscription management (#2172) fix(hash-types): remove panic, enforce fixed-size arrays (#2279) fix(ARRR): store unconfirmed change output (#2276) feat(tendermint): staking/delegation (#2322) chore(deps): `timed-map` migration (#2247) fix(mem-leak): `running_swap` never shrinks (#2301) chore(dep-bump): libp2p (#2326) refactor(build script): rewrite the main build script (#2319)
mariocynicys
left a comment
There was a problem hiding this comment.
Thanks! esp for the excessive comments :)
this was a light review to grasp new thigns. nothing is blocking from my side.
will read the SoW for more context and review again next review week if this is still unmerged.
|
Regarding this: #2362 (comment) I suggest I use the 'Close' price in the next PR (which actually does swaps with LR) |
|
I improved functions and structs naming (well, at least I tried). PS. Some tests are failing but looks like it's QRC tests |
shamardy
left a comment
There was a problem hiding this comment.
Thanks for the fixes! The below comments can be done here or in next PRs.
| @@ -0,0 +1,299 @@ | |||
| //! RPC implementations for swaps with liquidity routing (LR) of EVM tokens | |||
There was a problem hiding this comment.
I suppose the RPCs in this file will be for all kind of tokens in the future not EVM only, maybe we should remove any mention of EVMs from the docs. Not a blocker for this PR though.
| /// Request to find best swap path with LR to fill an order from list. | ||
| #[derive(Debug, Deserialize)] | ||
| #[serde(deny_unknown_fields)] | ||
| pub struct LrFindBestQuoteRequest { | ||
| /// Base coin to fill an atomic swap maker order with possible liquidity routing from this coin over a coin/token in an ask/bid | ||
| pub user_base: Ticker, | ||
| /// List of maker atomic swap ask orders, to find best swap path with liquidity routing from user_base or user_rel coin | ||
| pub asks: Vec<AsksForCoin>, | ||
| /// List of maker atomic swap bid orders, to find best swap path with liquidity routing from user_base or user_rel coin | ||
| pub bids: Vec<BidsForCoin>, | ||
| /// Buy or sell volume (in coin units, i.e. with fraction) | ||
| pub volume: MmNumber, | ||
| /// Method buy or sell | ||
| /// TODO: use this field, now we support 'buy' only | ||
| pub method: String, | ||
| /// Rel coin to fill an atomic swap maker order with possible liquidity routing from this coin over a coin/token in an ask/bid | ||
| pub user_rel: Ticker, | ||
| } |
There was a problem hiding this comment.
Still very confusing, I suggested something like this
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct LrFindBestQuoteRequest {
/// The currency the user wants to acquire (e.g., "BTC").
pub target_coin: Ticker,
/// The amount of the `target_coin` the user wishes to buy.
pub target_amount: MmNumber,
/// The token the user holds and will use to pay for the trade.
/// If this token is not accepted by the best candidate order,
/// it will be swapped through a liquidity provider.
pub payment_token: Ticker,
/// A list of potential orders (asks) from the order book that are selling
/// the `target_coin`. The system will evaluate these to find the best trade route.
pub candidate_orders: Vec<RpcOrderbookEntryV2>,
}Do you have any objections to this?
There was a problem hiding this comment.
target_coin, payment_token is good, I like this.
Only this assumes the User would always be creating 'sell' orders (no 'buy'). It's easier for development,
but for ordinary atomic swaps we allow both sell and buy (although 'buy' is just an inversion of 'sell').
About this:
pub candidate_orders: Vec<RpcOrderbookEntryV2>,. The problem is that RpcOrderbookEntryV2 contains only one coin and another coin is returned as separate a base or rel property in the orderbook rpc response.
So I made it as a new AsksForCoin like in the orderbook rpc response.
(Not sure though we should send orders into the LR rpcs as they are on the orderbook, but this is how it's done now. I thought GUI would be selecting orders and send them to LR rpcs for adding liquidity routing steps)
There was a problem hiding this comment.
Only this assumes the User would always be creating 'sell' orders (no 'buy').
Why is that? target_coin and payment_token should work with either sell or buy
There was a problem hiding this comment.
Should we have these in lp_commands? I will allow it for now since we want this PR merged asap but I don't think this is the best place for it. IMHO, lp_commands should be for rpc methods (the wrappers) and the requests/responses/errors of these RPC methods only.
There was a problem hiding this comment.
Aha!
I have already moved this out of lp_command in the follow-up code to this PR. Will create a new PR with this in the next few days
|
@smk762 please note no docs are needed for this PR as the API may change in next PRs |
* dev: fix(eth): Correctly implement ETH max withdrawal logic (#2531) feat(use-clap-for-cli): use clap to parse CLI-Args #2215 (#2510) feat(orderbook): expirable maker orders (#2516) improvement(eth): drop parity support (#2527) chore(release): finalize changelog for v2.5.0-beta (#2524) chore(toolchain): upgrade toolchain to nightly 1.86.0 (#2444) feat(swap): rpc to find best swap with liquidity routing for ask (#2362) fix(kdf_walletconnect): apply explicit MmError mapping (#2514) fix(walletconnect): centralize connection and retry logic (#2508) fix(hw-wallet): avoid calling `get_enabled_address` in trezor-based coin init (#2504)
* refactor-gas-fee-policy: (30 commits) revert change in test_enable_custom_erc20 fix(test) disable get_swap_gas_fee_policy for tests (no platform coin in tests) revert tokio test and use block_on for eth docker test Refactor gas fee code: get max_eth_tx_type from platform coin, add gas fee adjust coin params, rename "set_swap_transaction_fee_policy" rpc to "set_swap_gas_fee_policy", force set_swap_gas_fee_policy to store policy in the platform coin fix(eth): Propagate structured EIP-1559 fee errors (GLEECBTC#2532) fix(eth): Correctly implement ETH max withdrawal logic (GLEECBTC#2531) feat(use-clap-for-cli): use clap to parse CLI-Args GLEECBTC#2215 (GLEECBTC#2510) feat(orderbook): expirable maker orders (GLEECBTC#2516) improvement(eth): drop parity support (GLEECBTC#2527) chore(release): finalize changelog for v2.5.0-beta (GLEECBTC#2524) chore(toolchain): upgrade toolchain to nightly 1.86.0 (GLEECBTC#2444) feat(swap): rpc to find best swap with liquidity routing for ask (GLEECBTC#2362) fix(kdf_walletconnect): apply explicit MmError mapping (GLEECBTC#2514) fix(walletconnect): centralize connection and retry logic (GLEECBTC#2508) fix(hw-wallet): avoid calling `get_enabled_address` in trezor-based coin init (GLEECBTC#2504) chore(core): replace hash_raw_entry with stable entry() API (GLEECBTC#2473) chore(core): adapt `MmError` and usages for compatibility with new rustc versions (GLEECBTC#2443) feat(wallet): add `delete_wallet` RPC (GLEECBTC#2497) chore(release): add changelog entries for v2.5.0-beta (GLEECBTC#2494) chore(release): bump kdf version to 2.5.0-beta (GLEECBTC#2492) ... # Conflicts: # mm2src/coins/eth.rs # mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs # mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs # mm2src/coins/eth/eth_utils.rs # mm2src/coins/eth/eth_withdraw.rs # mm2src/coins/eth/v2_activation.rs # mm2src/coins/lp_coins.rs # mm2src/coins/qrc20.rs # mm2src/coins/qrc20/swap.rs # mm2src/coins_activation/src/platform_coin_with_tokens.rs # mm2src/coins_activation/src/token.rs # mm2src/mm2_main/src/lp_swap/check_balance.rs # mm2src/mm2_main/src/lp_swap/maker_swap.rs # mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs # mm2src/mm2_main/src/rpc/lp_commands/ext_api/ext_api_types.rs # mm2src/mm2_main/src/rpc/lp_commands/mod.rs # mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs # mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs # mm2src/mm2_main/src/rpc/lp_commands/tokens.rs # mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs # mm2src/trading_api/src/one_inch_api/classic_swap_types.rs # mm2src/trading_api/src/one_inch_api/client.rs # mm2src/trading_api/src/one_inch_api/portfolio_types.rs
This introduces a new experimental RPC, `experimental::liquidity_routing::find_best_quote`, to find the most cost-effective swap path by aggregating atomic swaps with external liquidity routing via the 1inch API. The new endpoint allows users to execute token swaps even if they do not directly hold the tokens required by maker orders. It evaluates possible swap paths by combining external liquidity routing with atomic swaps to find the most price-effective route. Key changes include: - A new RPC endpoint `experimental::liquidity_routing::find_best_quote` for pathfinding. - Core logic in `mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs` to process orders and query the 1inch API. - Refactored the 1inch API client in `trading_api` to use a `UrlBuilder` for more robust URL construction and added support for the Portfolio API. - Extracted common Ethereum utility functions into a new `coins/eth/eth_utils.rs` module to improve code organization. - Updated `RpcOrderbookEntryV2` and `MmNumberMultiRepr` to be deserializable. Currently, this feature only supports filling `ask` orders with liquidity routing performed before the atomic swap.
Initial code for liquidity routing (LR) support for KDF.
The added RPC finds best (most price efficient) swap path from a list of provided ask orders, to fill them with a User token converting into orders' tokens with an interim LR-swap.
This PR covers only finding the best quote for one case (the ask order when 'rel' is token). Next steps are adding/fixing RPCs to get quotes for order types (bids) and RPCs to run swaps with LR.
TODO:
TODO to research: