From ac8295bca49011118a380554cb39f6afbceffa37 Mon Sep 17 00:00:00 2001 From: Ruben Date: Wed, 22 Apr 2026 18:36:12 +0400 Subject: [PATCH] Add rate field to GetQuoteResponse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exposes the dest/source conversion rate on the quote response so clients can surface it alongside the receive amount, matching the existing Layerswap quote payload shape. Rate comes from the route's IRateProvider and is truncated to 6 decimals (matching Layerswap's Constants.UsdPrecision). Single-leg paths reduce the Layerswap multiplicative path aggregate to the provider's rate directly. Intentionally not part of the signing payload — it's informational and derivable from the already-signed amount/receive-amount pair. Co-Authored-By: Claude Opus 4.7 (1M context) --- csharp/src/Infrastructure/Quote/QuoteService.cs | 1 + csharp/src/Shared.Models/Models/QuoteDto.cs | 6 ++++-- csharp/src/Shared.Proto/SolverProtoMapper.cs | 1 + protos/solver.proto | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/csharp/src/Infrastructure/Quote/QuoteService.cs b/csharp/src/Infrastructure/Quote/QuoteService.cs index 2ff6c2ed..173aa9c6 100644 --- a/csharp/src/Infrastructure/Quote/QuoteService.cs +++ b/csharp/src/Infrastructure/Quote/QuoteService.cs @@ -214,6 +214,7 @@ await CalculateTotalFeeAsync(route, amount, rewardAmountInDestNative: rewardAmou TotalServiceFee = totalServiceFee, TotalExpenseFee = totalExpenseFee, TotalRewardFee = totalRewardFee, + Rate = swapRate.Truncate(6), SourceSolverAddress = route.SourceWallet.Address, DestinationSolverAddress = route.DestinationWallet.Address, Route = route, diff --git a/csharp/src/Shared.Models/Models/QuoteDto.cs b/csharp/src/Shared.Models/Models/QuoteDto.cs index 70421889..9803ab8c 100644 --- a/csharp/src/Shared.Models/Models/QuoteDto.cs +++ b/csharp/src/Shared.Models/Models/QuoteDto.cs @@ -4,13 +4,15 @@ namespace Train.Solver.Shared.Models; public class QuoteDto { - public BigInteger TotalFee { get; set; } + public BigInteger TotalFee { get; set; } - public BigInteger TotalServiceFee { get; set; } + public BigInteger TotalServiceFee { get; set; } public BigInteger TotalExpenseFee { get; set; } public BigInteger TotalRewardFee { get; set; } public BigInteger ReceiveAmount { get; set; } + + public decimal Rate { get; set; } } \ No newline at end of file diff --git a/csharp/src/Shared.Proto/SolverProtoMapper.cs b/csharp/src/Shared.Proto/SolverProtoMapper.cs index ba90991e..f9f6de1e 100644 --- a/csharp/src/Shared.Proto/SolverProtoMapper.cs +++ b/csharp/src/Shared.Proto/SolverProtoMapper.cs @@ -53,6 +53,7 @@ public static class SolverProtoMapper TotalExpenseFee = quote.TotalExpenseFee.ToString(), TotalRewardFee = quote.TotalRewardFee.ToString(), Amount = quote.Amount.ToString(), + Rate = quote.Rate.ToString(System.Globalization.CultureInfo.InvariantCulture), }; #endregion diff --git a/protos/solver.proto b/protos/solver.proto index 6e05c34e..f2cf7179 100644 --- a/protos/solver.proto +++ b/protos/solver.proto @@ -69,6 +69,7 @@ message GetQuoteResponse { string total_expense_fee = 11; // BigInteger as string (source token units) string total_reward_fee = 12; // BigInteger as string (source token units) string amount = 13; // BigInteger as string (source amount — useful for reverse quotes) + string rate = 14; // decimal as invariant string — dest/source conversion rate, truncated to 6 decimals } message RewardInfo {