From 50a689f262112f84c027912186b10e0917604147 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:00:18 +0800 Subject: [PATCH 01/24] feat: improve quote or rate discrimination --- .../getTradeQuote/getTradeQuote.test.ts | 4 +- .../getTradeQuote/getTradeQuote.ts | 5 ++- .../getTradeRate/getTradeRate.ts | 3 +- .../utils/fetchArbitrumBridgeSwap.ts | 4 +- .../swapperApi/getTradeQuote.ts | 3 ++ .../swapperApi/getTradeRate.ts | 2 +- .../getCowSwapTradeQuote.test.ts | 5 +++ .../getCowSwapTradeQuote.ts | 1 + .../getCowSwapTradeRate.ts | 4 +- .../swapperApi/getTradeQuote.ts | 1 + .../JupiterSwapper/swapperApi/getTradeRate.ts | 2 +- .../getTradeQuote/getTradeQuote.ts | 39 +++++++++++++------ .../LifiSwapper/getTradeRate/getTradeRate.ts | 9 +++-- .../getPortalsTradeQuote.ts | 1 + .../getPortalsTradeRate.tsx | 4 +- .../getThorTradeQuote/getTradeQuote.test.ts | 2 + .../getThorTradeRate/getTradeRate.ts | 5 ++- .../ThorchainSwapper/utils/getL1Rate.ts | 14 +++---- .../ThorchainSwapper/utils/getL1quote.ts | 3 ++ .../getZrxTradeQuote/getZrxTradeQuote.ts | 1 + .../getZrxTradeRate/getZrxTradeRate.ts | 3 +- .../utils/test-data/setupSwapQuote.ts | 1 + packages/swapper/src/types.ts | 29 +++++++------- packages/swapper/src/utils.ts | 6 +-- src/components/MultiHopTrade/helpers.ts | 11 +++++- .../useGetTradeQuotes/useGetTradeQuotes.tsx | 8 ++-- .../useGetTradeQuotes/useGetTradeRates.tsx | 14 ++++--- .../hooks/useInputOutputDifference.ts | 6 ++- src/components/MultiHopTrade/utils.ts | 10 ++++- .../helpers/getInputOutputRatioFromQuote.ts | 16 ++++++-- src/state/apis/swapper/helpers/testData.ts | 4 ++ .../swapper/helpers/validateTradeQuote.ts | 11 ++++-- src/state/apis/swapper/swapperApi.ts | 9 ----- src/state/apis/swapper/types.ts | 3 +- src/state/slices/tradeInputSlice/selectors.ts | 4 +- src/state/slices/tradeQuoteSlice/helpers.ts | 11 +++++- src/state/slices/tradeQuoteSlice/selectors.ts | 9 ++++- .../slices/tradeQuoteSlice/tradeQuoteSlice.ts | 4 +- src/state/slices/tradeQuoteSlice/types.ts | 4 +- 39 files changed, 182 insertions(+), 93 deletions(-) diff --git a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.test.ts b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.test.ts index 9a18025c5e1..94ce1ce4c65 100644 --- a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.test.ts +++ b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.test.ts @@ -3,7 +3,7 @@ import { ethAssetId, ethChainId } from '@shapeshiftoss/caip' import type { EvmChainAdapter } from '@shapeshiftoss/chain-adapters' import { describe, expect, it, vi } from 'vitest' -import type { GetEvmTradeQuoteInput, SwapperDeps } from '../../../types' +import type { GetEvmTradeQuoteInputBase, SwapperDeps } from '../../../types' import { SwapperName } from '../../../types' import { BTC, ETH, ETH_ARBITRUM, FOX_ARBITRUM, FOX_MAINNET } from '../../utils/test-data/assets' import { getTradeQuote } from './getTradeQuote' @@ -49,7 +49,7 @@ describe('getTradeQuote', () => { receiveAddress: '0xfauxmes', sellAmountIncludingProtocolFeesCryptoBaseUnit: '1000000000000000000', sendAddress: '0xfauxmes', - } as GetEvmTradeQuoteInput + } as GetEvmTradeQuoteInputBase it('returns a correct ETH deposit quote', async () => { const ethBridgerMock = { diff --git a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts index 309c464695a..c75677789a2 100644 --- a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts @@ -6,7 +6,7 @@ import { v4 as uuid } from 'uuid' import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants' import type { - GetEvmTradeQuoteInput, + GetEvmTradeQuoteInputBase, SingleHopTradeQuoteSteps, SwapErrorRight, SwapperDeps, @@ -40,7 +40,7 @@ export const getTradeQuoteWithWallet = async ( } export async function getTradeQuote( - input: GetEvmTradeQuoteInput, + input: GetEvmTradeQuoteInputBase, { assertGetEvmChainAdapter }: SwapperDeps, ): Promise> { const { @@ -84,6 +84,7 @@ export async function getTradeQuote( return Ok({ id: uuid(), + quoteOrRate: 'quote' as const, receiveAddress, affiliateBps: '0', potentialAffiliateBps: '0', diff --git a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeRate/getTradeRate.ts b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeRate/getTradeRate.ts index 5c11b6932a1..77cf880e851 100644 --- a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeRate/getTradeRate.ts +++ b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeRate/getTradeRate.ts @@ -66,8 +66,9 @@ export async function getTradeRate( return Ok({ id: uuid(), + quoteOrRate: 'rate' as const, accountNumber: undefined, - receiveAddress: undefined, + receiveAddress, affiliateBps: '0', potentialAffiliateBps: '0', rate, diff --git a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/utils/fetchArbitrumBridgeSwap.ts b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/utils/fetchArbitrumBridgeSwap.ts index 716eb6b8efd..5000dc50bc2 100644 --- a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/utils/fetchArbitrumBridgeSwap.ts +++ b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/utils/fetchArbitrumBridgeSwap.ts @@ -20,7 +20,7 @@ type FetchArbitrumBridgeSwapInput = { supportsEIP1559: boolean chainId: ChainId buyAsset: Asset - receiveAddress: T extends 'rate' ? undefined : string + receiveAddress: T extends 'rate' ? string | undefined : string sellAmountIncludingProtocolFeesCryptoBaseUnit: string sellAsset: Asset sendAddress: T extends 'rate' ? undefined : string @@ -32,7 +32,7 @@ type FetchArbitrumBridgePriceInput = { supportsEIP1559: false chainId: ChainId buyAsset: Asset - receiveAddress: undefined + receiveAddress: string | undefined sellAmountIncludingProtocolFeesCryptoBaseUnit: string sellAsset: Asset sendAddress: undefined diff --git a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts index 9f0dce9a907..5cd832f7c6b 100644 --- a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts +++ b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts @@ -50,6 +50,7 @@ export const _getTradeQuote = async ( receiveAddress, sellAmountIncludingProtocolFeesCryptoBaseUnit: sellAmount, affiliateBps: commissionBps, + quoteOrRate, } = input if (!isSupportedChainId(sellAsset.chainId)) { @@ -268,6 +269,7 @@ export const _getTradeQuote = async ( const boostTradeQuote: TradeQuote = { id: uuid(), + quoteOrRate, rate: boostRate, receiveAddress, potentialAffiliateBps: commissionBps, @@ -310,6 +312,7 @@ export const _getTradeQuote = async ( const tradeQuote: TradeQuote = { id: uuid(), + quoteOrRate, rate, receiveAddress, potentialAffiliateBps: commissionBps, diff --git a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts index 0add3599c5a..65a356661ff 100644 --- a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts +++ b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts @@ -16,5 +16,5 @@ export const getTradeRate = async ( deps: SwapperDeps, ): Promise> => { const rates = await _getTradeQuote(input as unknown as CommonTradeQuoteInput, deps) - return rates as Result + return rates as unknown as Result } diff --git a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts index efd61e07944..13c75aad70d 100644 --- a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts +++ b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts @@ -135,6 +135,7 @@ const expectedApiInputUsdcToEthArbitrum: CowSwapSellQuoteApiInput = { } const expectedTradeQuoteWethToFox: TradeQuote = { + quoteOrRate: 'quote', id: '123', receiveAddress: '0x0000000000000000000000000000000000000000', affiliateBps: '0', @@ -180,6 +181,7 @@ const expectedTradeQuoteWethToFox: TradeQuote = { } const expectedTradeQuoteFoxToEth: TradeQuote = { + quoteOrRate: 'quote', id: '123', receiveAddress: '0x0000000000000000000000000000000000000000', affiliateBps: '0', @@ -225,6 +227,7 @@ const expectedTradeQuoteFoxToEth: TradeQuote = { } const expectedTradeQuoteUsdcToXdai: TradeQuote = { + quoteOrRate: 'quote', id: '123', receiveAddress: '0x0000000000000000000000000000000000000000', affiliateBps: '0', @@ -270,6 +273,7 @@ const expectedTradeQuoteUsdcToXdai: TradeQuote = { } const expectedTradeQuoteUsdcToEthArbitrum: TradeQuote = { + quoteOrRate: 'quote', id: '123', receiveAddress: '0x0000000000000000000000000000000000000000', affiliateBps: '0', @@ -315,6 +319,7 @@ const expectedTradeQuoteUsdcToEthArbitrum: TradeQuote = { } const expectedTradeQuoteSmallAmountWethToFox: TradeQuote = { + quoteOrRate: 'quote', id: '123', receiveAddress: '0x0000000000000000000000000000000000000000', affiliateBps: '0', diff --git a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.ts b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.ts index 208d1a19c69..f1abe8e3891 100644 --- a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.ts +++ b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.ts @@ -147,6 +147,7 @@ async function _getCowSwapTradeQuote( const quote: TradeQuote = { id, + quoteOrRate: 'quote', receiveAddress, affiliateBps, potentialAffiliateBps, diff --git a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeRate/getCowSwapTradeRate.ts b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeRate/getCowSwapTradeRate.ts index 1a1443c58cf..bf8b2891026 100644 --- a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeRate/getCowSwapTradeRate.ts +++ b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeRate/getCowSwapTradeRate.ts @@ -142,8 +142,8 @@ async function _getCowSwapTradeRate( const quote: TradeRate = { id, - accountNumber, - receiveAddress: undefined, + quoteOrRate: 'rate', + receiveAddress, affiliateBps, potentialAffiliateBps, rate, diff --git a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts index 0865311c85c..0b4267a0a24 100644 --- a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts +++ b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts @@ -212,6 +212,7 @@ export const getTradeQuote = async ( const tradeQuote: TradeQuote = { id: uuid(), + quoteOrRate: 'quote', rate, potentialAffiliateBps: affiliateBps, affiliateBps, diff --git a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts index 677dc3dfacc..886ff7cc8cc 100644 --- a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts +++ b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts @@ -198,11 +198,11 @@ export const getTradeRate = async ( const tradeRate: TradeRate = { id: uuid(), + quoteOrRate: 'rate', rate: inputOutputRate, receiveAddress, potentialAffiliateBps: affiliateBps, affiliateBps, - accountNumber, slippageTolerancePercentageDecimal, steps: [ { diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index a74247ee3ac..a7e98aa2cb8 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -18,7 +18,9 @@ import type { GetEvmTradeQuoteInput, GetEvmTradeQuoteInputBase, MultiHopTradeQuoteSteps, + MultiHopTradeRateSteps, SingleHopTradeQuoteSteps, + SingleHopTradeRateSteps, SwapErrorRight, SwapperDeps, SwapSource, @@ -32,13 +34,17 @@ import { getLifiEvmAssetAddress } from '../utils/getLifiEvmAssetAddress/getLifiE import { getNetworkFeeCryptoBaseUnit } from '../utils/getNetworkFeeCryptoBaseUnit/getNetworkFeeCryptoBaseUnit' import { lifiTokenToAsset } from '../utils/lifiTokenToAsset/lifiTokenToAsset' import { transformLifiStepFeeData } from '../utils/transformLifiFeeData/transformLifiFeeData' -import type { LifiTradeQuote } from '../utils/types' +import type { LifiTradeQuote, LifiTradeRate } from '../utils/types' -export async function getTrade( - input: GetEvmTradeQuoteInput, - deps: SwapperDeps, - lifiChainMap: Map, -): Promise> { +export async function getTrade({ + input, + deps, + lifiChainMap, +}: { + input: GetEvmTradeQuoteInput + deps: SwapperDeps + lifiChainMap: Map +}): Promise> { const { sellAsset, buyAsset, @@ -49,6 +55,7 @@ export async function getTrade( supportsEIP1559, affiliateBps, potentialAffiliateBps, + quoteOrRate, } = input const slippageTolerancePercentageDecimal = @@ -229,7 +236,11 @@ export async function getTrade( estimatedExecutionTimeMs: 1000 * lifiStep.estimate.executionDuration, } }), - )) as SingleHopTradeQuoteSteps | MultiHopTradeQuoteSteps + )) as + | SingleHopTradeQuoteSteps + | MultiHopTradeQuoteSteps + | SingleHopTradeRateSteps + | MultiHopTradeRateSteps // The rate for the entire multi-hop swap const netRate = convertPrecision({ @@ -242,6 +253,7 @@ export async function getTrade( return { id: selectedLifiRoute.id, + quoteOrRate, // This isn't a mistake - with Li.Fi, we can never go with our full-on intent of rate vs. quotes. As soon as a wallet is connected, we get a *quote* // even though we're lying and saying this is a rate. With the "rate" containing a receiveAddress, a quote will *not* be fired at pre-sign time, which // ensures users aren't rugged with routes that aren't available anymore when going from input to confirm @@ -285,13 +297,18 @@ export async function getTrade( ) } - return Ok(promises.filter(isFulfilled).map(({ value }) => value)) + return Ok(promises.filter(isFulfilled).map(({ value }) => value)) as unknown as Result< + LifiTradeQuote[] | LifiTradeRate[], + SwapErrorRight + > } -// This isn't a mistake - With Li.Fi, we get the exact same thing back whether quote or rate, however, the input *is* different - export const getTradeQuote = ( input: GetEvmTradeQuoteInputBase, deps: SwapperDeps, lifiChainMap: Map, -): Promise> => getTrade(input, deps, lifiChainMap) +): Promise> => { + return getTrade({ input, deps, lifiChainMap }) as Promise< + Result + > +} diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts index 99bcdd2b592..8c9e7d3bd39 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts @@ -11,9 +11,10 @@ export const getTradeRate = async ( deps: SwapperDeps, lifiChainMap: Map, ): Promise> => { - const rate = (await getTrade(input, deps, lifiChainMap)) as Result< - LifiTradeRate[], - SwapErrorRight - > + const rate = (await getTrade({ + input, + deps, + lifiChainMap, + })) as unknown as Result return rate } diff --git a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts index 128ba731d28..b63ce8b061f 100644 --- a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts +++ b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts @@ -163,6 +163,7 @@ export async function getPortalsTradeQuote( const tradeQuote: TradeQuote = { id: orderId, + quoteOrRate: 'quote' as const, receiveAddress: input.receiveAddress, affiliateBps, potentialAffiliateBps, diff --git a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx index a5ea1c6db6b..2cf738ae52e 100644 --- a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx +++ b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx @@ -36,6 +36,7 @@ export async function getPortalsTradeRate( potentialAffiliateBps, chainId, sellAmountIncludingProtocolFeesCryptoBaseUnit, + receiveAddress, } = input const sellAssetChainId = sellAsset.chainId @@ -131,8 +132,9 @@ export async function getPortalsTradeRate( const tradeRate = { id: uuid(), + quoteOrRate: 'rate' as const, accountNumber, - receiveAddress: undefined, + receiveAddress, affiliateBps, potentialAffiliateBps, rate: inputOutputRate, diff --git a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.test.ts b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.test.ts index f9cb768c61a..4e292d7a63d 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.test.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.test.ts @@ -56,6 +56,7 @@ vi.mock('config', () => { const expectedQuoteResponse: Omit[] = [ { + quoteOrRate: 'quote', receiveAddress: '0xc770eefad204b5180df6a14ee197d99d808ee52d', affiliateBps: '0', potentialAffiliateBps: '0', @@ -95,6 +96,7 @@ const expectedQuoteResponse: Omit[] = [ ], }, { + quoteOrRate: 'quote', receiveAddress: '0xc770eefad204b5180df6a14ee197d99d808ee52d', affiliateBps: '0', potentialAffiliateBps: '0', diff --git a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts index 4f2faa3ad8e..2482208858c 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts @@ -2,7 +2,7 @@ import { assertUnreachable, bn } from '@shapeshiftoss/utils' import type { Result } from '@sniptt/monads' import { Err } from '@sniptt/monads' -import type { GetTradeRateInput, SwapErrorRight, SwapperDeps } from '../../../types' +import type { GetTradeRateInput, SwapErrorRight, SwapperDeps, TradeRate } from '../../../types' import { TradeQuoteError } from '../../../types' import { makeSwapErrorRight } from '../../../utils' import { buySupportedChainIds, sellSupportedChainIds } from '../constants' @@ -14,6 +14,9 @@ import { getTradeType, TradeType } from '../utils/longTailHelpers' import { assetIdToPoolAssetId } from '../utils/poolAssetHelpers/poolAssetHelpers' import { thorService } from '../utils/thorService' +export const isThorTradeRate = (quote: TradeRate | undefined): quote is ThorTradeRate => + !!quote && 'tradeType' in quote + export const getThorTradeRate = async ( input: GetTradeRateInput, deps: SwapperDeps, diff --git a/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts b/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts index 51765a5a33f..b0bfe7d47fe 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts @@ -100,7 +100,7 @@ export const getL1Rate = async ( sellAsset, buyAssetId: buyAsset.assetId, sellAmountCryptoBaseUnit, - receiveAddress: undefined, + receiveAddress, streaming: true, affiliateBps: requestedAffiliateBps, streamingInterval, @@ -252,9 +252,9 @@ export const getL1Rate = async ( return { id: uuid(), - accountNumber: undefined, + quoteOrRate: 'rate', memo, - receiveAddress: undefined, + receiveAddress, affiliateBps, potentialAffiliateBps, isStreaming, @@ -364,9 +364,9 @@ export const getL1Rate = async ( return { id: uuid(), - accountNumber: undefined, + quoteOrRate: 'rate', memo, - receiveAddress: undefined, + receiveAddress, affiliateBps, potentialAffiliateBps, isStreaming, @@ -444,9 +444,9 @@ export const getL1Rate = async ( return { id: uuid(), - accountNumber: undefined, + quoteOrRate: 'rate', memo, - receiveAddress: undefined, + receiveAddress, affiliateBps, potentialAffiliateBps, isStreaming, diff --git a/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1quote.ts b/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1quote.ts index 8d11be0e2b3..3b16832b3de 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1quote.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1quote.ts @@ -270,6 +270,7 @@ export const getL1Quote = async ( return { id: uuid(), + quoteOrRate: 'quote', memo, receiveAddress, affiliateBps, @@ -384,6 +385,7 @@ export const getL1Quote = async ( return { id: uuid(), + quoteOrRate: 'quote', memo, receiveAddress, affiliateBps, @@ -478,6 +480,7 @@ export const getL1Quote = async ( return { id: uuid(), + quoteOrRate: 'quote', memo, receiveAddress, affiliateBps, diff --git a/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.ts b/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.ts index 6ac720ebcb9..407d69ac32f 100644 --- a/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.ts +++ b/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.ts @@ -123,6 +123,7 @@ export async function getZrxTradeQuote( return Ok({ id: uuid(), + quoteOrRate: 'quote' as const, receiveAddress, potentialAffiliateBps, affiliateBps, diff --git a/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeRate/getZrxTradeRate.ts b/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeRate/getZrxTradeRate.ts index 7a86714b474..cb6b2780d23 100644 --- a/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeRate/getZrxTradeRate.ts +++ b/packages/swapper/src/swappers/ZrxSwapper/getZrxTradeRate/getZrxTradeRate.ts @@ -68,8 +68,9 @@ export async function getZrxTradeRate( return Ok({ id: uuid(), + quoteOrRate: 'rate' as const, accountNumber: undefined, - receiveAddress: undefined, + receiveAddress, potentialAffiliateBps, affiliateBps, // Slippage protection is always enabled for 0x api v2 unlike api v1 which was only supported on specific pairs. diff --git a/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts b/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts index 14e6e7e3cfc..548d848219b 100644 --- a/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts +++ b/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts @@ -11,6 +11,7 @@ export const setupQuote = () => { const buyAsset: Asset = { ...WETH } const tradeQuote: TradeQuote = { + quoteOrRate: 'quote', id: 'foobar', receiveAddress: '0x1234', affiliateBps: '0', diff --git a/packages/swapper/src/types.ts b/packages/swapper/src/types.ts index 5a482d44387..e5ce91b08c3 100644 --- a/packages/swapper/src/types.ts +++ b/packages/swapper/src/types.ts @@ -165,7 +165,7 @@ export type CommonTradeQuoteInput = CommonTradeInputBase & { type CommonTradeRateInput = CommonTradeInputBase & { sendAddress?: undefined - receiveAddress: undefined + receiveAddress: string | undefined accountNumber: undefined quoteOrRate: 'rate' } @@ -293,16 +293,15 @@ export type ExecutableTradeStep = Omit & { acco type TradeQuoteBase = { id: string rate: string // top-level rate for all steps (i.e. output amount / input amount) - receiveAddress: string | undefined // if receiveAddress is undefined, this is not a trade quote but a trade rate + receiveAddress: string | undefined // receiveAddress may be undefined without a wallet connected potentialAffiliateBps: string // even if the swapper does not support affiliateBps, we need to zero-them out or view-layer will be borked affiliateBps: string // even if the swapper does not support affiliateBps, we need to zero-them out or view-layer will be borked isStreaming?: boolean slippageTolerancePercentageDecimal: string | undefined // undefined if slippage limit is not provided or specified by the swapper isLongtail?: boolean + quoteOrRate: 'quote' | 'rate' } -type TradeRateBase = Omit & { receiveAddress: undefined } - // https://github.com/microsoft/TypeScript/pull/40002 type _TupleOf = R['length'] extends N ? R @@ -327,27 +326,31 @@ export type SupportedTradeQuoteStepIndex = 0 | 1 export type SingleHopTradeQuote = TradeQuoteBase & { steps: SingleHopTradeQuoteSteps } -export type MultiHopTradeQuote = TradeQuoteBase & { - steps: MultiHopTradeQuoteSteps -} - // Note: don't try to do TradeQuote = SingleHopTradeQuote | MultiHopTradeQuote here, which would be cleaner but you'll have type errors such as // "An interface can only extend an object type or intersection of object types with statically known members." export type TradeQuote = TradeQuoteBase & { steps: SingleHopTradeQuoteSteps | MultiHopTradeQuoteSteps +} & { + quoteOrRate: 'quote' + receiveAddress: string } -export type TradeRate = TradeRateBase & { +export type MultiHopTradeQuote = TradeQuote & { + steps: MultiHopTradeQuoteSteps +} + +export type MultiHopTradeRate = TradeRate & { + steps: MultiHopTradeRateSteps +} + +export type TradeRate = TradeQuoteBase & { steps: SingleHopTradeRateSteps | MultiHopTradeRateSteps } & { - receiveAddress: undefined - accountNumber: undefined + quoteOrRate: 'rate' } export type TradeQuoteOrRate = TradeQuote | TradeRate -export type ExecutableTradeQuote = TradeQuote & { receiveAddress: string } - export type FromOrXpub = { from: string; xpub?: never } | { from?: never; xpub: string } export type GetUnsignedTxArgs = { diff --git a/packages/swapper/src/utils.ts b/packages/swapper/src/utils.ts index f2cc3dd2449..931866d125d 100644 --- a/packages/swapper/src/utils.ts +++ b/packages/swapper/src/utils.ts @@ -17,7 +17,6 @@ import { fetchSafeTransactionInfo } from './safe-utils' import type { EvmTransactionExecutionProps, EvmTransactionRequest, - ExecutableTradeQuote, ExecutableTradeStep, SolanaTransactionExecutionProps, SupportedTradeQuoteStepIndex, @@ -26,6 +25,7 @@ import type { TradeQuote, TradeQuoteOrRate, TradeQuoteStep, + TradeRate, } from './types' import { TradeQuoteError } from './types' @@ -302,8 +302,8 @@ export const getInputOutputRate = ({ return bn(buyAmountCryptoHuman).div(sellAmountCryptoHuman).toFixed() } -export const isExecutableTradeQuote = (quote: TradeQuote): quote is ExecutableTradeQuote => - !!quote.receiveAddress +export const isExecutableTradeQuote = (quote: TradeQuote | TradeRate): quote is TradeQuote => + quote.quoteOrRate === 'quote' export const isToken = (assetId: AssetId) => { switch (fromAssetId(assetId).assetNamespace) { diff --git a/src/components/MultiHopTrade/helpers.ts b/src/components/MultiHopTrade/helpers.ts index 090a15c5aff..eb15103fc95 100644 --- a/src/components/MultiHopTrade/helpers.ts +++ b/src/components/MultiHopTrade/helpers.ts @@ -1,4 +1,6 @@ +import { isExecutableTradeQuote } from '@shapeshiftoss/swapper' import { isThorTradeQuote } from '@shapeshiftoss/swapper/dist/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote' +import { isThorTradeRate } from '@shapeshiftoss/swapper/dist/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate' import { getMaybeCompositeAssetSymbol } from 'lib/mixpanel/helpers' import type { ReduxState } from 'state/reducer' import { selectAssets, selectFeeAssetById } from 'state/slices/selectors' @@ -41,6 +43,13 @@ export const getMixpanelEventData = () => { const compositeBuyAsset = getMaybeCompositeAssetSymbol(buyAsset.assetId, assets) const compositeSellAsset = getMaybeCompositeAssetSymbol(sellAsset.assetId, assets) + const tradeType = (() => { + if (!activeQuote) return null + if (isExecutableTradeQuote(activeQuote)) + return isThorTradeQuote(activeQuote) ? activeQuote.tradeType : null + return isThorTradeRate(activeQuote) ? activeQuote.tradeType : null + })() + return { buyAsset: compositeBuyAsset, sellAsset: compositeSellAsset, @@ -55,6 +64,6 @@ export const getMixpanelEventData = () => { [compositeSellAsset]: sellAmountBeforeFeesCryptoPrecision, isStreaming: activeQuote?.isStreaming ?? false, isLongtail: activeQuote?.isLongtail ?? false, - tradeType: isThorTradeQuote(activeQuote) ? activeQuote?.tradeType : null, + tradeType, } } diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx index 15ed721319b..8a4f15022ac 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx @@ -1,7 +1,7 @@ import { skipToken as reduxSkipToken } from '@reduxjs/toolkit/query' import { fromAccountId } from '@shapeshiftoss/caip' import { isLedger } from '@shapeshiftoss/hdwallet-ledger' -import type { GetTradeQuoteInput, TradeQuote } from '@shapeshiftoss/swapper' +import type { GetTradeQuoteInput, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import { DEFAULT_GET_TRADE_QUOTE_POLLING_INTERVAL, isExecutableTradeQuote, @@ -89,7 +89,9 @@ const getMixPanelDataFromApiQuotes = ( const { assetId: buyAssetId, chainId: buyAssetChainId } = selectInputBuyAsset(state) const sellAmountUsd = selectInputSellAmountUsd(state) const quoteMeta: MixPanelQuoteMeta[] = quotes - .map(({ quote, errors, swapperName, inputOutputRatio }) => { + .map(({ quote: _quote, errors, swapperName, inputOutputRatio }) => { + const quote = _quote as TradeQuote + const differenceFromBestQuoteDecimalPercentage = (inputOutputRatio / bestInputOutputRatio - 1) * -1 return { @@ -131,7 +133,7 @@ export const useGetTradeQuotes = () => { const sortedTradeQuotes = useAppSelector(selectSortedTradeQuotes) const activeTrade = useAppSelector(selectActiveQuote) const activeTradeId = activeTrade?.id - const activeRateRef = useRef() + const activeRateRef = useRef() const activeTradeIdRef = useRef() const activeQuoteMeta = useAppSelector(selectActiveQuoteMetaOrDefault) const activeQuoteMetaRef = useRef<{ swapperName: SwapperName; identifier: string } | undefined>() diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx index 11d118b0344..5e45f5d0e2e 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx @@ -1,13 +1,13 @@ import { skipToken } from '@reduxjs/toolkit/dist/query' import { fromAccountId } from '@shapeshiftoss/caip' import { isLedger } from '@shapeshiftoss/hdwallet-ledger' -import type { GetTradeRateInput } from '@shapeshiftoss/swapper' +import type { GetTradeRateInput, TradeRate } from '@shapeshiftoss/swapper' import { DEFAULT_GET_TRADE_QUOTE_POLLING_INTERVAL, SwapperName, swappers, } from '@shapeshiftoss/swapper' -import { isThorTradeQuote } from '@shapeshiftoss/swapper/dist/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote' +import { isThorTradeRate } from '@shapeshiftoss/swapper/dist/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate' import { useQuery } from '@tanstack/react-query' import { useCallback, useEffect, useMemo } from 'react' import { useTradeReceiveAddress } from 'components/MultiHopTrade/components/TradeInput/hooks/useTradeReceiveAddress' @@ -74,7 +74,7 @@ type GetMixPanelDataFromApiQuotesReturn = { const votingPowerParams: { feeModel: ParameterModel } = { feeModel: 'SWAPPER' } const thorVotingPowerParams: { feeModel: ParameterModel } = { feeModel: 'THORSWAP' } -const getMixPanelDataFromApiQuotes = ( +const getMixPanelDataFromApiRates = ( quotes: Pick[], ): GetMixPanelDataFromApiQuotesReturn => { const bestInputOutputRatio = quotes[0]?.inputOutputRatio @@ -83,7 +83,9 @@ const getMixPanelDataFromApiQuotes = ( const { assetId: buyAssetId, chainId: buyAssetChainId } = selectInputBuyAsset(state) const sellAmountUsd = selectInputSellAmountUsd(state) const quoteMeta: MixPanelQuoteMeta[] = quotes - .map(({ quote, errors, swapperName, inputOutputRatio }) => { + .map(({ quote: _quote, errors, swapperName, inputOutputRatio }) => { + const quote = _quote as TradeRate + const differenceFromBestQuoteDecimalPercentage = (inputOutputRatio / bestInputOutputRatio - 1) * -1 return { @@ -92,7 +94,7 @@ const getMixPanelDataFromApiQuotes = ( quoteReceived: !!quote, isStreaming: quote?.isStreaming ?? false, isLongtail: quote?.isLongtail ?? false, - tradeType: isThorTradeQuote(quote) ? quote?.tradeType : null, + tradeType: isThorTradeRate(quote) ? quote?.tradeType : null, errors: errors.map(({ error }) => error), isActionable: !!quote && !errors.length, } @@ -299,7 +301,7 @@ export const useGetTradeRates = () => { useEffect(() => { if (isAnyTradeQuoteLoading) return if (mixpanel) { - const quoteData = getMixPanelDataFromApiQuotes(sortedTradeQuotes) + const quoteData = getMixPanelDataFromApiRates(sortedTradeQuotes) mixpanel.track(MixPanelEvent.QuotesReceived, quoteData) } }, [sortedTradeQuotes, mixpanel, isAnyTradeQuoteLoading]) diff --git a/src/components/MultiHopTrade/hooks/useInputOutputDifference.ts b/src/components/MultiHopTrade/hooks/useInputOutputDifference.ts index a4f4b18a090..bd0fe30e282 100644 --- a/src/components/MultiHopTrade/hooks/useInputOutputDifference.ts +++ b/src/components/MultiHopTrade/hooks/useInputOutputDifference.ts @@ -1,11 +1,13 @@ -import type { SupportedTradeQuoteStepIndex, TradeQuote } from '@shapeshiftoss/swapper' +import type { SupportedTradeQuoteStepIndex, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import { getHopByIndex } from '@shapeshiftoss/swapper' import { bn, bnOrZero, fromBaseUnit } from '@shapeshiftoss/utils' import { useMemo } from 'react' import { selectUsdRateByAssetId } from 'state/slices/selectors' import { useAppSelector } from 'state/store' -export const useInputOutputDifferenceDecimalPercentage = (tradeQuote: TradeQuote | undefined) => { +export const useInputOutputDifferenceDecimalPercentage = ( + tradeQuote: TradeQuote | TradeRate | undefined, +) => { const numSteps = tradeQuote?.steps.length ?? 0 const sellAsset = tradeQuote?.steps[0].sellAsset const buyAsset = tradeQuote?.steps[numSteps - 1].buyAsset diff --git a/src/components/MultiHopTrade/utils.ts b/src/components/MultiHopTrade/utils.ts index 7e47d5557b0..6b9f1f34e83 100644 --- a/src/components/MultiHopTrade/utils.ts +++ b/src/components/MultiHopTrade/utils.ts @@ -1,8 +1,16 @@ import type { ChainId } from '@shapeshiftoss/caip' -import type { MultiHopTradeQuote, TradeQuote } from '@shapeshiftoss/swapper' +import type { + MultiHopTradeQuote, + MultiHopTradeRate, + TradeQuote, + TradeRate, +} from '@shapeshiftoss/swapper' // All chains currently support Tx history, but that might not be the case as we support more chains export const chainSupportsTxHistory = (_chainId: ChainId): boolean => true export const isMultiHopTradeQuote = (quote: TradeQuote): quote is MultiHopTradeQuote => quote.steps.length > 1 + +export const isMultiHopTradeRate = (quote: TradeRate): quote is MultiHopTradeRate => + quote.steps.length > 1 diff --git a/src/state/apis/swapper/helpers/getInputOutputRatioFromQuote.ts b/src/state/apis/swapper/helpers/getInputOutputRatioFromQuote.ts index 2b0b74a2017..a6bfdb2a3bc 100644 --- a/src/state/apis/swapper/helpers/getInputOutputRatioFromQuote.ts +++ b/src/state/apis/swapper/helpers/getInputOutputRatioFromQuote.ts @@ -1,5 +1,10 @@ import type { AssetId } from '@shapeshiftoss/caip' -import type { SupportedTradeQuoteStepIndex, SwapperName, TradeQuote } from '@shapeshiftoss/swapper' +import type { + SupportedTradeQuoteStepIndex, + SwapperName, + TradeQuote, + TradeRate, +} from '@shapeshiftoss/swapper' import { getHopByIndex } from '@shapeshiftoss/swapper' import type { Asset } from '@shapeshiftoss/types' import type { BigNumber } from 'lib/bignumber/bignumber' @@ -31,7 +36,7 @@ const getHopTotalNetworkFeeFiatPrecisionWithGetFeeAssetRate = ( const getTotalNetworkFeeFiatPrecisionWithGetFeeAssetRate = ( state: ReduxState, - quote: TradeQuote, + quote: TradeQuote | TradeRate, getFeeAssetRate: (feeAssetId: AssetId) => string, ): BigNumber => quote.steps.reduce((acc, step) => { @@ -49,7 +54,10 @@ const getTotalNetworkFeeFiatPrecisionWithGetFeeAssetRate = ( * @param quote The trade quote * @returns The total network fee across all hops in USD precision */ -const _getTotalNetworkFeeUsdPrecision = (state: ReduxState, quote: TradeQuote): BigNumber => { +const _getTotalNetworkFeeUsdPrecision = ( + state: ReduxState, + quote: TradeQuote | TradeRate, +): BigNumber => { const marketDataUsd = selectMarketDataUsd(state) const getFeeAssetUsdRate = (feeAssetId: AssetId) => { @@ -91,7 +99,7 @@ export const getInputOutputRatioFromQuote = ({ quote, }: { state: ReduxState - quote: TradeQuote + quote: TradeQuote | TradeRate swapperName: SwapperName }): number => { // A quote always has a first step diff --git a/src/state/apis/swapper/helpers/testData.ts b/src/state/apis/swapper/helpers/testData.ts index 4fd2116ec40..ce45ec672b7 100644 --- a/src/state/apis/swapper/helpers/testData.ts +++ b/src/state/apis/swapper/helpers/testData.ts @@ -4,6 +4,7 @@ import { SwapperName } from '@shapeshiftoss/swapper' export const lifiQuote: TradeQuote = { id: '0x5ba393814e096f79f4316615b82462eaaee2cf4e1c935d35624a6390bc932b83', rate: '51.34579860391078801712', + quoteOrRate: 'quote', affiliateBps: '0', potentialAffiliateBps: '0', receiveAddress: '0x31b5c4ab7d020de87901c736535aeb4769806947', @@ -54,6 +55,7 @@ export const lifiQuote: TradeQuote = { export const thorQuote: TradeQuote = { id: 'f4636745-bf07-4799-9efb-c056691b652f', + quoteOrRate: 'quote', rate: '39.23942597524024759752', receiveAddress: '0x31b5c4ab7d020de87901c736535aeb4769806947', affiliateBps: '30', @@ -138,6 +140,7 @@ export const thorQuote: TradeQuote = { export const cowQuote: TradeQuote = { id: '220858750', + quoteOrRate: 'quote', rate: '51.86127422365727736757', affiliateBps: '0', potentialAffiliateBps: '0', @@ -206,6 +209,7 @@ export const cowQuote: TradeQuote = { export const zrxQuote: TradeQuote = { id: 'dfb5f2e6-9cb9-4865-9ef5-6b54d203affa', + quoteOrRate: 'quote', rate: '51.603817692372651273', affiliateBps: '0', potentialAffiliateBps: '0', diff --git a/src/state/apis/swapper/helpers/validateTradeQuote.ts b/src/state/apis/swapper/helpers/validateTradeQuote.ts index 482a8d145ca..4253e3e5f24 100644 --- a/src/state/apis/swapper/helpers/validateTradeQuote.ts +++ b/src/state/apis/swapper/helpers/validateTradeQuote.ts @@ -1,14 +1,15 @@ import type { AssetId } from '@shapeshiftoss/caip' -import type { ProtocolFee, SwapErrorRight, TradeQuote } from '@shapeshiftoss/swapper' +import type { ProtocolFee, SwapErrorRight, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import { getHopByIndex, + isExecutableTradeQuote, SwapperName, TradeQuoteError as SwapperTradeQuoteError, } from '@shapeshiftoss/swapper' import type { ThorTradeQuote } from '@shapeshiftoss/swapper/dist/swappers/ThorchainSwapper/types' import type { KnownChainIds } from '@shapeshiftoss/types' import { getChainShortName } from 'components/MultiHopTrade/components/MultiHopTradeConfirm/utils/getChainShortName' -import { isMultiHopTradeQuote } from 'components/MultiHopTrade/utils' +import { isMultiHopTradeQuote, isMultiHopTradeRate } from 'components/MultiHopTrade/utils' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { fromBaseUnit } from 'lib/math' import { assertGetChainAdapter, assertUnreachable, isTruthy } from 'lib/utils' @@ -47,7 +48,7 @@ export const validateTradeQuote = ( quoteOrRate, }: { swapperName: SwapperName - quote: TradeQuote | undefined + quote: TradeQuote | TradeRate | undefined error: SwapErrorRight | undefined isTradingActiveOnSellPool: boolean isTradingActiveOnBuyPool: boolean @@ -124,7 +125,9 @@ export const validateTradeQuote = ( const firstHop = getHopByIndex(quote, 0)! const secondHop = getHopByIndex(quote, 1) - const isMultiHopTrade = isMultiHopTradeQuote(quote) + const isMultiHopTrade = isExecutableTradeQuote(quote) + ? isMultiHopTradeQuote(quote) + : isMultiHopTradeRate(quote) const lastHop = (isMultiHopTrade ? secondHop : firstHop)! const walletConnectedChainIds = selectWalletConnectedChainIds(state) diff --git a/src/state/apis/swapper/swapperApi.ts b/src/state/apis/swapper/swapperApi.ts index 4ba2c5a219a..0a145472cf4 100644 --- a/src/state/apis/swapper/swapperApi.ts +++ b/src/state/apis/swapper/swapperApi.ts @@ -91,15 +91,6 @@ export const swapperApi = createApi({ return getTradeRates( { ...tradeQuoteInput, - // Receive address should always be undefined for trade *rates*, however, we *do* pass it to check for cross-account support - // so we have to ensure it is gone by the time we call getTradeRates - receiveAddress: - // Ok, we may have lied just before. Li.Fi is the odd one, and we don't want to fetch a final quote for it. - // The reason is Li.Fi routes are very fragile and from one request to the other, it's more likely than not a tool may not be returned anymore, resulting in early null returns - // in swapper, i.e a totally broken state. - // By keeping the receiveAddress in all the way through, and returning it in LIFI's `getTradeRate()`, the rate becomes an effective quote, and the - // `shouldFetchTradeQuote = isExecutableTradeQuote(activeTrade)` never becomes true, meaning we keep the rate as a quote. - swapperName === SwapperName.LIFI ? tradeQuoteInput.receiveAddress : undefined, affiliateBps, } as GetTradeRateInput, swapperName, diff --git a/src/state/apis/swapper/types.ts b/src/state/apis/swapper/types.ts index d9f5166ff3b..3809a18d0dd 100644 --- a/src/state/apis/swapper/types.ts +++ b/src/state/apis/swapper/types.ts @@ -3,6 +3,7 @@ import type { SwapperName, TradeQuote, TradeQuoteError as SwapperTradeQuoteError, + TradeRate, } from '@shapeshiftoss/swapper' import type { InterpolationOptions } from 'node-polyglot' @@ -44,7 +45,7 @@ export type ErrorWithMeta = { error: T; meta?: InterpolationOptions } export type ApiQuote = { id: string - quote: TradeQuote | undefined + quote: TradeQuote | TradeRate | undefined swapperName: SwapperName inputOutputRatio: number errors: ErrorWithMeta[] diff --git a/src/state/slices/tradeInputSlice/selectors.ts b/src/state/slices/tradeInputSlice/selectors.ts index d1225229a9e..2f48f6b6a05 100644 --- a/src/state/slices/tradeInputSlice/selectors.ts +++ b/src/state/slices/tradeInputSlice/selectors.ts @@ -1,5 +1,5 @@ import { createSelector } from '@reduxjs/toolkit' -import type { SwapperName, TradeQuote } from '@shapeshiftoss/swapper' +import type { SwapperName, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import { isExecutableTradeStep } from '@shapeshiftoss/swapper' import type { Selector } from 'react-redux' import type { ApiQuote } from 'state/apis/swapper/types' @@ -83,7 +83,7 @@ const selectActiveSwapperApiResponse: Selector ) const selectConfirmedQuote: Selector = createDeepEqualOutputSelector(selectTradeQuoteSlice, tradeQuote => tradeQuote.confirmedQuote) -const selectActiveQuote: Selector = +const selectActiveQuote: Selector = createDeepEqualOutputSelector( selectActiveSwapperApiResponse, selectConfirmedQuote, diff --git a/src/state/slices/tradeQuoteSlice/helpers.ts b/src/state/slices/tradeQuoteSlice/helpers.ts index 9cf37663218..d2044cf9c0f 100644 --- a/src/state/slices/tradeQuoteSlice/helpers.ts +++ b/src/state/slices/tradeQuoteSlice/helpers.ts @@ -5,6 +5,7 @@ import type { SwapperName, TradeQuote, TradeQuoteStep, + TradeRate, } from '@shapeshiftoss/swapper' import { getHopByIndex } from '@shapeshiftoss/swapper' import type { Asset, MarketData, PartialRecord } from '@shapeshiftoss/types' @@ -78,7 +79,11 @@ export const getHopTotalProtocolFeesFiatPrecision = ( * @param quote The trade quote * @returns The total receive amount across all hops in crypto precision after protocol fees are deducted */ -export const getBuyAmountAfterFeesCryptoPrecision = ({ quote }: { quote: TradeQuote }) => { +export const getBuyAmountAfterFeesCryptoPrecision = ({ + quote, +}: { + quote: TradeQuote | TradeRate +}) => { const lastStepIndex = (quote.steps.length - 1) as SupportedTradeQuoteStepIndex const lastStep = getHopByIndex(quote, lastStepIndex) @@ -122,7 +127,9 @@ export const _reduceTotalProtocolFeeByAssetForStep = ( export const getTotalProtocolFeeByAssetForStep = (step: TradeQuoteStep) => _reduceTotalProtocolFeeByAssetForStep({}, step) -export const getTotalProtocolFeeByAsset = (quote: TradeQuote): Record => +export const getTotalProtocolFeeByAsset = ( + quote: TradeQuote | TradeRate, +): Record => quote.steps.reduce>( (acc, step) => _reduceTotalProtocolFeeByAssetForStep(acc, step), {}, diff --git a/src/state/slices/tradeQuoteSlice/selectors.ts b/src/state/slices/tradeQuoteSlice/selectors.ts index 4a937f4ffb4..93ba1cdad00 100644 --- a/src/state/slices/tradeQuoteSlice/selectors.ts +++ b/src/state/slices/tradeQuoteSlice/selectors.ts @@ -1,6 +1,11 @@ import { createSelector } from '@reduxjs/toolkit' import type { AssetId } from '@shapeshiftoss/caip' -import type { ProtocolFee, SupportedTradeQuoteStepIndex, TradeQuote } from '@shapeshiftoss/swapper' +import type { + ProtocolFee, + SupportedTradeQuoteStepIndex, + TradeQuote, + TradeRate, +} from '@shapeshiftoss/swapper' import { getDefaultSlippageDecimalPercentageForSwapper, getHopByIndex, @@ -232,7 +237,7 @@ export const selectActiveSwapperApiResponse: Selector = +export const selectActiveQuote: Selector = createDeepEqualOutputSelector( selectActiveSwapperApiResponse, selectConfirmedQuote, diff --git a/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts b/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts index d96e201f67d..b39492781f9 100644 --- a/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts +++ b/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts @@ -1,6 +1,6 @@ import type { PayloadAction } from '@reduxjs/toolkit' import { createSlice } from '@reduxjs/toolkit' -import type { SwapperName, TradeQuote } from '@shapeshiftoss/swapper' +import type { SwapperName, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import { orderBy, uniqBy } from 'lodash' import type { InterpolationOptions } from 'node-polyglot' import type { ApiQuote } from 'state/apis/swapper/types' @@ -52,7 +52,7 @@ export const tradeQuoteSlice = createSlice({ } } }, - setConfirmedQuote: (state, action: PayloadAction) => { + setConfirmedQuote: (state, action: PayloadAction) => { state.confirmedQuote = action.payload }, clearQuoteExecutionState: (state, action: PayloadAction) => { diff --git a/src/state/slices/tradeQuoteSlice/types.ts b/src/state/slices/tradeQuoteSlice/types.ts index 3394af02c2d..567ffd830ce 100644 --- a/src/state/slices/tradeQuoteSlice/types.ts +++ b/src/state/slices/tradeQuoteSlice/types.ts @@ -1,4 +1,4 @@ -import type { SwapperName, TradeQuote } from '@shapeshiftoss/swapper' +import type { SwapperName, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import type { PartialRecord } from '@shapeshiftoss/types' import type { InterpolationOptions } from 'node-polyglot' import type { ApiQuote } from 'state/apis/swapper/types' @@ -8,7 +8,7 @@ export type ActiveQuoteMeta = { swapperName: SwapperName; identifier: string } export type TradeQuoteSliceState = { activeStep: number | undefined // Make sure to actively check for undefined vs. falsy here. 0 is the first step, undefined means no active step yet activeQuoteMeta: ActiveQuoteMeta | undefined // the selected quote metadata used to find the active quote in the api responses - confirmedQuote: TradeQuote | undefined // the quote being executed + confirmedQuote: TradeQuote | TradeRate | undefined // the quote being executed tradeExecution: Record tradeQuotes: PartialRecord> // mapping from swapperName to quoteId to ApiQuote tradeQuoteDisplayCache: ApiQuote[] From 0058933f2c0443b224fab171ac95e2fbb24a4673 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:37:03 +0800 Subject: [PATCH 02/24] fix: types --- .../getTradeQuote/getTradeQuote.ts | 13 +++++++++---- .../MultiHopTradeConfirm/MultiHopTradeConfirm.tsx | 4 ++-- .../MultiHopTradeConfirm/components/Hop.tsx | 4 ++-- .../components/TradeInput/TradeInput.tsx | 6 +++--- .../TradeQuotes/components/TradeQuoteContent.tsx | 4 ++-- .../hooks/quoteValidation/usePriceImpact.tsx | 4 ++-- src/state/slices/tradeInputSlice/selectors.ts | 2 +- src/state/slices/tradeQuoteSlice/helpers.ts | 2 +- src/state/slices/tradeQuoteSlice/selectors.ts | 2 +- 9 files changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts index c75677789a2..76e03ee1752 100644 --- a/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.ts @@ -11,17 +11,22 @@ import type { SwapErrorRight, SwapperDeps, TradeQuote, + TradeRate, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' import { makeSwapErrorRight } from '../../../utils' -import type { ArbitrumBridgeTradeQuote, GetEvmTradeQuoteInputWithWallet } from '../types' +import type { + ArbitrumBridgeTradeQuote, + ArbitrumBridgeTradeRate, + GetEvmTradeQuoteInputWithWallet, +} from '../types' import type { FetchArbitrumBridgeQuoteInput } from '../utils/fetchArbitrumBridgeSwap' import { fetchArbitrumBridgeQuote } from '../utils/fetchArbitrumBridgeSwap' import { assertValidTrade } from '../utils/helpers' -export const isArbitrumBridgeTradeQuote = ( - quote: TradeQuote | undefined, -): quote is ArbitrumBridgeTradeQuote => !!quote && 'direction' in quote +export const isArbitrumBridgeTradeQuoteOrRate = ( + quote: TradeQuote | TradeRate | undefined, +): quote is ArbitrumBridgeTradeQuote | ArbitrumBridgeTradeRate => !!quote && 'direction' in quote export const getTradeQuoteWithWallet = async ( inputWithWallet: GetEvmTradeQuoteInputWithWallet, diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx index b0f0dcfba8a..60584bf2e9d 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx @@ -1,5 +1,5 @@ import { Card, CardBody, CardHeader, Heading, useDisclosure, usePrevious } from '@chakra-ui/react' -import { isArbitrumBridgeTradeQuote } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote' +import { isArbitrumBridgeTradeQuoteOrRate } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote' import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslate } from 'react-polyglot' import { useHistory } from 'react-router-dom' @@ -47,7 +47,7 @@ export const MultiHopTradeConfirm = memo(() => { const { isLoading } = useIsApprovalInitiallyNeeded() const isArbitrumBridgeWithdraw = useMemo(() => { - return isArbitrumBridgeTradeQuote(activeQuote) && activeQuote.direction === 'withdrawal' + return isArbitrumBridgeTradeQuoteOrRate(activeQuote) && activeQuote.direction === 'withdrawal' }, [activeQuote]) useEffect(() => { diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx index 52ea0135491..35892e5de91 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx @@ -17,7 +17,7 @@ import type { TradeQuote, TradeQuoteStep, } from '@shapeshiftoss/swapper' -import { isArbitrumBridgeTradeQuote } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote' +import { isArbitrumBridgeTradeQuoteOrRate } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote' import prettyMilliseconds from 'pretty-ms' import { useCallback, useMemo } from 'react' import { FaGasPump } from 'react-icons/fa' @@ -94,7 +94,7 @@ export const Hop = ({ const activeQuote = useAppSelector(selectActiveQuote) const isArbitrumBridgeWithdraw = useMemo(() => { - return isArbitrumBridgeTradeQuote(activeQuote) && activeQuote.direction === 'withdrawal' + return isArbitrumBridgeTradeQuoteOrRate(activeQuote) && activeQuote.direction === 'withdrawal' }, [activeQuote]) const hopExecutionMetadataFilter = useMemo(() => { diff --git a/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx b/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx index c4d0636ece0..97c7b0d219e 100644 --- a/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx +++ b/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx @@ -1,6 +1,6 @@ import type { ChainId } from '@shapeshiftoss/caip' import { isLedger } from '@shapeshiftoss/hdwallet-ledger' -import { isArbitrumBridgeTradeQuote } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote' +import { isArbitrumBridgeTradeQuoteOrRate } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote' import type { ThorTradeQuote } from '@shapeshiftoss/swapper/dist/swappers/ThorchainSwapper/types' import type { Asset } from '@shapeshiftoss/types' import { KnownChainIds } from '@shapeshiftoss/types' @@ -284,7 +284,7 @@ export const TradeInput = ({ isCompact, tradeInputRef, onChangeTab }: TradeInput const handleWarningAcknowledgementSubmit = useCallback(() => { if (activeQuote?.isStreaming && isEstimatedExecutionTimeOverThreshold) return setShouldShowStreamingAcknowledgement(true) - if (isArbitrumBridgeTradeQuote(activeQuote) && activeQuote.direction === 'withdrawal') + if (isArbitrumBridgeTradeQuoteOrRate(activeQuote) && activeQuote.direction === 'withdrawal') return setShouldShowArbitrumBridgeAcknowledgement(true) handleFormSubmit() }, [activeQuote, isEstimatedExecutionTimeOverThreshold, handleFormSubmit]) @@ -295,7 +295,7 @@ export const TradeInput = ({ isCompact, tradeInputRef, onChangeTab }: TradeInput if (isUnsafeQuote) return setShouldShowWarningAcknowledgement(true) if (activeQuote?.isStreaming && isEstimatedExecutionTimeOverThreshold) return setShouldShowStreamingAcknowledgement(true) - if (isArbitrumBridgeTradeQuote(activeQuote) && activeQuote.direction === 'withdrawal') + if (isArbitrumBridgeTradeQuoteOrRate(activeQuote) && activeQuote.direction === 'withdrawal') return setShouldShowArbitrumBridgeAcknowledgement(true) handleFormSubmit() diff --git a/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/components/TradeQuoteContent.tsx b/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/components/TradeQuoteContent.tsx index b0f46836595..b3709431c77 100644 --- a/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/components/TradeQuoteContent.tsx +++ b/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/components/TradeQuoteContent.tsx @@ -1,5 +1,5 @@ import { Box, CardBody, CardFooter, Flex, Skeleton, Tooltip } from '@chakra-ui/react' -import type { TradeQuote } from '@shapeshiftoss/swapper' +import type { TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import type { Asset } from '@shapeshiftoss/types' import prettyMilliseconds from 'pretty-ms' import { useMemo } from 'react' @@ -24,7 +24,7 @@ export type TradeQuoteContentProps = { networkFeeFiatUserCurrency: string | undefined totalEstimatedExecutionTimeMs: number | undefined slippage: JSX.Element | undefined - tradeQuote: TradeQuote | undefined + tradeQuote: TradeQuote | TradeRate | undefined } export const TradeQuoteContent = ({ diff --git a/src/components/MultiHopTrade/hooks/quoteValidation/usePriceImpact.tsx b/src/components/MultiHopTrade/hooks/quoteValidation/usePriceImpact.tsx index 419ffbe80a0..123ae7d2c1e 100644 --- a/src/components/MultiHopTrade/hooks/quoteValidation/usePriceImpact.tsx +++ b/src/components/MultiHopTrade/hooks/quoteValidation/usePriceImpact.tsx @@ -1,4 +1,4 @@ -import type { SupportedTradeQuoteStepIndex, TradeQuote } from '@shapeshiftoss/swapper' +import type { SupportedTradeQuoteStepIndex, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import { getHopByIndex } from '@shapeshiftoss/swapper' import { useMemo } from 'react' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -6,7 +6,7 @@ import { fromBaseUnit } from 'lib/math' import { selectUsdRateByAssetId } from 'state/slices/selectors' import { useAppSelector } from 'state/store' -export const usePriceImpact = (tradeQuote: TradeQuote | undefined) => { +export const usePriceImpact = (tradeQuote: TradeQuote | TradeRate | undefined) => { // Avoid using tradeInputSlice selectors here due to inaccurate values during debouncing. // Selectors update instantly, but quotes are refreshed post-request completion, leading to // discrepancies while fetching. diff --git a/src/state/slices/tradeInputSlice/selectors.ts b/src/state/slices/tradeInputSlice/selectors.ts index 2f48f6b6a05..ca17a93f116 100644 --- a/src/state/slices/tradeInputSlice/selectors.ts +++ b/src/state/slices/tradeInputSlice/selectors.ts @@ -81,7 +81,7 @@ const selectActiveSwapperApiResponse: Selector ] }, ) -const selectConfirmedQuote: Selector = +const selectConfirmedQuote: Selector = createDeepEqualOutputSelector(selectTradeQuoteSlice, tradeQuote => tradeQuote.confirmedQuote) const selectActiveQuote: Selector = createDeepEqualOutputSelector( diff --git a/src/state/slices/tradeQuoteSlice/helpers.ts b/src/state/slices/tradeQuoteSlice/helpers.ts index d2044cf9c0f..e72147091de 100644 --- a/src/state/slices/tradeQuoteSlice/helpers.ts +++ b/src/state/slices/tradeQuoteSlice/helpers.ts @@ -43,7 +43,7 @@ export const getHopTotalNetworkFeeUserCurrency = ( * @returns The total network fee across all hops in fiat precision */ export const getTotalNetworkFeeUserCurrencyPrecision = ( - quote: TradeQuote, + quote: TradeQuote | TradeRate, getFeeAsset: (assetId: AssetId) => Asset, getFeeAssetRate: (feeAssetId: AssetId) => string, ): BigNumber | undefined => { diff --git a/src/state/slices/tradeQuoteSlice/selectors.ts b/src/state/slices/tradeQuoteSlice/selectors.ts index 93ba1cdad00..a4573de3491 100644 --- a/src/state/slices/tradeQuoteSlice/selectors.ts +++ b/src/state/slices/tradeQuoteSlice/selectors.ts @@ -200,7 +200,7 @@ export const selectActiveStepOrDefault: Selector = createSel tradeQuote => tradeQuote.activeStep ?? 0, ) -const selectConfirmedQuote: Selector = +const selectConfirmedQuote: Selector = createDeepEqualOutputSelector(selectTradeQuoteSlice, tradeQuoteState => { return tradeQuoteState.confirmedQuote }) From a468c64e3fe41420354af1717748988332df4d5d Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:44:26 +0800 Subject: [PATCH 03/24] fix: tests --- packages/swapper/src/swappers/CowSwapper/CowSwapper.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/swapper/src/swappers/CowSwapper/CowSwapper.test.ts b/packages/swapper/src/swappers/CowSwapper/CowSwapper.test.ts index dae437b5784..a2322ed5cee 100644 --- a/packages/swapper/src/swappers/CowSwapper/CowSwapper.test.ts +++ b/packages/swapper/src/swappers/CowSwapper/CowSwapper.test.ts @@ -212,8 +212,9 @@ describe('cowApi', () => { verified: false, } - const tradeQuote = { + const tradeQuote: TradeQuote = { id: '474004127', + quoteOrRate: 'quote', receiveAddress: '0x90a48d5cf7343b08da12e067680b4c6dbfe551be', affiliateBps: '0', potentialAffiliateBps: '48', From 7fea22b23869de81b637b930077fce48e37a3883 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:00:30 +0800 Subject: [PATCH 04/24] fix: lifi --- .../LifiSwapper/getTradeQuote/getTradeQuote.ts | 3 --- packages/swapper/src/utils.ts | 10 ++++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index a7e98aa2cb8..cfe0b48f15d 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -254,9 +254,6 @@ export async function getTrade({ return { id: selectedLifiRoute.id, quoteOrRate, - // This isn't a mistake - with Li.Fi, we can never go with our full-on intent of rate vs. quotes. As soon as a wallet is connected, we get a *quote* - // even though we're lying and saying this is a rate. With the "rate" containing a receiveAddress, a quote will *not* be fired at pre-sign time, which - // ensures users aren't rugged with routes that aren't available anymore when going from input to confirm receiveAddress, affiliateBps, potentialAffiliateBps, diff --git a/packages/swapper/src/utils.ts b/packages/swapper/src/utils.ts index 931866d125d..aec00e513d4 100644 --- a/packages/swapper/src/utils.ts +++ b/packages/swapper/src/utils.ts @@ -21,13 +21,12 @@ import type { SolanaTransactionExecutionProps, SupportedTradeQuoteStepIndex, SwapErrorRight, - SwapperName, TradeQuote, TradeQuoteOrRate, TradeQuoteStep, TradeRate, } from './types' -import { TradeQuoteError } from './types' +import { SwapperName, TradeQuoteError } from './types' export const makeSwapErrorRight = ({ details, @@ -302,8 +301,11 @@ export const getInputOutputRate = ({ return bn(buyAmountCryptoHuman).div(sellAmountCryptoHuman).toFixed() } -export const isExecutableTradeQuote = (quote: TradeQuote | TradeRate): quote is TradeQuote => - quote.quoteOrRate === 'quote' +export const isExecutableTradeQuote = (quote: TradeQuote | TradeRate): quote is TradeQuote => { + if (quote.steps[0]!.source.includes(SwapperName.LIFI)) return !!quote.receiveAddress + + return quote.quoteOrRate === 'quote' +} export const isToken = (assetId: AssetId) => { switch (fromAssetId(assetId).assetNamespace) { From 18a28dd65b99848302d3cc395d3d1acc21137160 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:56:27 +0800 Subject: [PATCH 05/24] fix: merge --- .../getTradeQuote/getTradeQuote.ts | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index 7cfa61e847b..dc21a2b25da 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -18,9 +18,7 @@ import type { GetEvmTradeQuoteInput, GetEvmTradeQuoteInputBase, MultiHopTradeQuoteSteps, - MultiHopTradeRateSteps, SingleHopTradeQuoteSteps, - SingleHopTradeRateSteps, SwapErrorRight, SwapperDeps, SwapSource, @@ -36,23 +34,15 @@ import { lifiTokenToAsset } from '../utils/lifiTokenToAsset/lifiTokenToAsset' import { transformLifiStepFeeData } from '../utils/transformLifiFeeData/transformLifiFeeData' import type { LifiTradeQuote, LifiTradeRate } from '../utils/types' -<<<<<<< HEAD export async function getTrade({ input, deps, lifiChainMap, }: { - input: GetEvmTradeQuoteInput + input: GetEvmTradeQuoteInput & { lifiAllowedTools?: string[] | undefined } deps: SwapperDeps lifiChainMap: Map }): Promise> { -======= -export async function getTrade( - input: GetEvmTradeQuoteInput & { lifiAllowedTools?: string[] | undefined }, - deps: SwapperDeps, - lifiChainMap: Map, -): Promise> { ->>>>>>> origin/develop const { sellAsset, buyAsset, @@ -63,11 +53,8 @@ export async function getTrade( supportsEIP1559, affiliateBps, potentialAffiliateBps, -<<<<<<< HEAD - quoteOrRate, -======= lifiAllowedTools, ->>>>>>> origin/develop + quoteOrRate, } = input const slippageTolerancePercentageDecimal = @@ -252,11 +239,7 @@ export async function getTrade( estimatedExecutionTimeMs: 1000 * lifiStep.estimate.executionDuration, } }), - )) as - | SingleHopTradeQuoteSteps - | MultiHopTradeQuoteSteps - | SingleHopTradeRateSteps - | MultiHopTradeRateSteps + )) as SingleHopTradeQuoteSteps | MultiHopTradeQuoteSteps // The rate for the entire multi-hop swap const netRate = convertPrecision({ @@ -269,8 +252,8 @@ export async function getTrade( return { id: selectedLifiRoute.id, - quoteOrRate, receiveAddress, + quoteOrRate, lifiTools: selectedLifiRoute.steps.map(step => step.tool), affiliateBps, potentialAffiliateBps, From 44e030184791dddd82c0a17b674ed6d76361d058 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:21:05 +0800 Subject: [PATCH 06/24] feat: rm Li.Fi specific case --- packages/swapper/src/utils.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/swapper/src/utils.ts b/packages/swapper/src/utils.ts index aec00e513d4..931866d125d 100644 --- a/packages/swapper/src/utils.ts +++ b/packages/swapper/src/utils.ts @@ -21,12 +21,13 @@ import type { SolanaTransactionExecutionProps, SupportedTradeQuoteStepIndex, SwapErrorRight, + SwapperName, TradeQuote, TradeQuoteOrRate, TradeQuoteStep, TradeRate, } from './types' -import { SwapperName, TradeQuoteError } from './types' +import { TradeQuoteError } from './types' export const makeSwapErrorRight = ({ details, @@ -301,11 +302,8 @@ export const getInputOutputRate = ({ return bn(buyAmountCryptoHuman).div(sellAmountCryptoHuman).toFixed() } -export const isExecutableTradeQuote = (quote: TradeQuote | TradeRate): quote is TradeQuote => { - if (quote.steps[0]!.source.includes(SwapperName.LIFI)) return !!quote.receiveAddress - - return quote.quoteOrRate === 'quote' -} +export const isExecutableTradeQuote = (quote: TradeQuote | TradeRate): quote is TradeQuote => + quote.quoteOrRate === 'quote' export const isToken = (assetId: AssetId) => { switch (fromAssetId(assetId).assetNamespace) { From e52c6f7d6b57ad6df087f395bf45c8fedae14318 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:28:08 +0800 Subject: [PATCH 07/24] feat: better casting --- .../src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts | 2 +- .../src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index dc21a2b25da..35db1abab2d 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -294,7 +294,7 @@ export async function getTrade({ ) } - return Ok(promises.filter(isFulfilled).map(({ value }) => value)) as unknown as Result< + return Ok(promises.filter(isFulfilled).map(({ value }) => value)) as Result< LifiTradeQuote[] | LifiTradeRate[], SwapErrorRight > diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts index 8c9e7d3bd39..a4241f69e0e 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts @@ -15,6 +15,6 @@ export const getTradeRate = async ( input, deps, lifiChainMap, - })) as unknown as Result + })) as Result return rate } From 214784c534228d7742d9626a363c6f8b038a664f Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:44:57 +0800 Subject: [PATCH 08/24] feat: no casting better than casting --- .../swapperApi/getTradeQuote.ts | 13 +++++++++-- .../swapperApi/getTradeRate.ts | 13 +++++++++-- .../getTradeQuote/getTradeQuote.ts | 17 ++++++++++---- .../LifiSwapper/getTradeRate/getTradeRate.ts | 22 +++++++++++++++---- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts index 5cd832f7c6b..a3549235c92 100644 --- a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts +++ b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts @@ -16,6 +16,7 @@ import type { SwapErrorRight, SwapperDeps, TradeQuote, + TradeQuoteStep, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' import { @@ -365,6 +366,14 @@ export const getTradeQuote = async ( ) } - const quotes = await _getTradeQuote(input, deps) - return quotes + const quotesResult = await _getTradeQuote(input, deps) + return quotesResult.map(quotes => + quotes.map(quote => ({ + ...quote, + quoteOrRate: 'quote' as const, + steps: quote.steps.map(step => ({ ...step, accountNumber: undefined })) as + | [TradeQuoteStep] + | [TradeQuoteStep, TradeQuoteStep], + })), + ) } diff --git a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts index 65a356661ff..591d7dd7518 100644 --- a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts +++ b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeRate.ts @@ -6,6 +6,7 @@ import type { SwapErrorRight, SwapperDeps, TradeRate, + TradeRateStep, } from '../../../types' import { _getTradeQuote } from './getTradeQuote' @@ -15,6 +16,14 @@ export const getTradeRate = async ( input: GetTradeRateInput, deps: SwapperDeps, ): Promise> => { - const rates = await _getTradeQuote(input as unknown as CommonTradeQuoteInput, deps) - return rates as unknown as Result + const ratesResult = await _getTradeQuote(input as unknown as CommonTradeQuoteInput, deps) + return ratesResult.map(rates => + rates.map(rate => ({ + ...rate, + quoteOrRate: 'rate' as const, + steps: rate.steps.map(step => ({ ...step, accountNumber: undefined })) as + | [TradeRateStep] + | [TradeRateStep, TradeRateStep], + })), + ) } diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index 35db1abab2d..62a7c83ede9 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -22,6 +22,7 @@ import type { SwapErrorRight, SwapperDeps, SwapSource, + TradeQuoteStep, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' import { makeSwapErrorRight } from '../../../utils' @@ -300,12 +301,20 @@ export async function getTrade({ > } -export const getTradeQuote = ( +export const getTradeQuote = async ( input: GetEvmTradeQuoteInputBase & { lifiAllowedTools?: string[] | undefined }, deps: SwapperDeps, lifiChainMap: Map, ): Promise> => { - return getTrade({ input, deps, lifiChainMap }) as Promise< - Result - > + const quotesResult = await getTrade({ input, deps, lifiChainMap }) + return quotesResult.map(quotes => + quotes.map(quote => ({ + ...quote, + quoteOrRate: 'quote' as const, + receiveAddress: quote.receiveAddress!, + steps: quote.steps.map(step => ({ ...step, accountNumber: undefined })) as + | [TradeQuoteStep] + | [TradeQuoteStep, TradeQuoteStep], + })), + ) } diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts index a4241f69e0e..fd66f207f5c 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeRate/getTradeRate.ts @@ -2,7 +2,12 @@ import type { ChainKey } from '@lifi/sdk' import type { ChainId } from '@shapeshiftoss/caip' import type { Result } from '@sniptt/monads' -import type { GetEvmTradeRateInput, SwapErrorRight, SwapperDeps } from '../../../types' +import type { + GetEvmTradeRateInput, + SwapErrorRight, + SwapperDeps, + TradeRateStep, +} from '../../../types' import { getTrade } from '../getTradeQuote/getTradeQuote' import type { LifiTradeRate } from '../utils/types' @@ -11,10 +16,19 @@ export const getTradeRate = async ( deps: SwapperDeps, lifiChainMap: Map, ): Promise> => { - const rate = (await getTrade({ + const ratesResult = await getTrade({ input, deps, lifiChainMap, - })) as Result - return rate + }) + + return ratesResult.map(rates => + rates.map(rate => ({ + ...rate, + quoteOrRate: 'rate' as const, + steps: rate.steps.map(step => ({ ...step, accountNumber: undefined })) as + | [TradeRateStep] + | [TradeRateStep, TradeRateStep], + })), + ) } From fa3e16798c55097d1013076f84081346954d191c Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:00:48 +0800 Subject: [PATCH 09/24] feat: improve isThorTradeQuote / isThorTradeRate heuristics with one additional discriminator --- .../ThorchainSwapper/getThorTradeQuote/getTradeQuote.ts | 2 +- .../swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts | 2 +- packages/swapper/src/swappers/ThorchainSwapper/types.ts | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.ts index eb821692a9a..3a1ba3ae48e 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote.ts @@ -15,7 +15,7 @@ import { assetIdToPoolAssetId } from '../utils/poolAssetHelpers/poolAssetHelpers import { thorService } from '../utils/thorService' export const isThorTradeQuote = (quote: TradeQuote | undefined): quote is ThorTradeQuote => - !!quote && 'tradeType' in quote + !!quote && 'tradeType' in quote && 'vault' in quote export const getThorTradeQuote = async ( input: CommonTradeQuoteInput, diff --git a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts index 2482208858c..f2f025cb54a 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/getThorTradeRate/getTradeRate.ts @@ -15,7 +15,7 @@ import { assetIdToPoolAssetId } from '../utils/poolAssetHelpers/poolAssetHelpers import { thorService } from '../utils/thorService' export const isThorTradeRate = (quote: TradeRate | undefined): quote is ThorTradeRate => - !!quote && 'tradeType' in quote + !!quote && 'tradeType' in quote && 'vault' in quote export const getThorTradeRate = async ( input: GetTradeRateInput, diff --git a/packages/swapper/src/swappers/ThorchainSwapper/types.ts b/packages/swapper/src/swappers/ThorchainSwapper/types.ts index 59170e164c0..cc7d4296ae4 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/types.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/types.ts @@ -262,7 +262,6 @@ export type ThorEvmTradeQuote = TradeQuote & vault: string aggregator?: string data: string - tradeType: TradeType } & { receiveAddress: string } From 558a0166502e9214c0a8b54813b0135d403d5e56 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:39:53 +0800 Subject: [PATCH 10/24] feat: remove TradeQuoteOrRate type --- packages/swapper/src/types.ts | 2 -- packages/swapper/src/utils.ts | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/swapper/src/types.ts b/packages/swapper/src/types.ts index 878ec376cf2..9c7426ad601 100644 --- a/packages/swapper/src/types.ts +++ b/packages/swapper/src/types.ts @@ -361,8 +361,6 @@ export type TradeRate = TradeQuoteBase & { quoteOrRate: 'rate' } -export type TradeQuoteOrRate = TradeQuote | TradeRate - export type FromOrXpub = { from: string; xpub?: never } | { from?: never; xpub: string } export type GetUnsignedTxArgs = { diff --git a/packages/swapper/src/utils.ts b/packages/swapper/src/utils.ts index 931866d125d..0a0ea9af91d 100644 --- a/packages/swapper/src/utils.ts +++ b/packages/swapper/src/utils.ts @@ -23,7 +23,6 @@ import type { SwapErrorRight, SwapperName, TradeQuote, - TradeQuoteOrRate, TradeQuoteStep, TradeRate, } from './types' @@ -155,7 +154,7 @@ export const makeSwapperAxiosServiceMonadic = (service: AxiosInstance, _swapperN }) export const getHopByIndex = ( - quote: TradeQuoteOrRate | undefined, + quote: TradeQuote | TradeRate | undefined, index: SupportedTradeQuoteStepIndex, ) => { if (quote === undefined) return undefined From bcd115106bac686c3e2422cc6cd45d825e4fc641 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Fri, 13 Dec 2024 00:05:25 +0800 Subject: [PATCH 11/24] fix: trade quotes cannot return undefined accountNumber --- .../src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts | 4 +--- .../src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts index 601b5f877de..95a3bbf360f 100644 --- a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts +++ b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts @@ -171,9 +171,7 @@ export const getTradeQuote = async ( ...quote, quoteOrRate: 'quote' as const, receiveAddress: receiveAddress!, - steps: quote.steps.map(step => ({ ...step, accountNumber: undefined })) as - | [TradeQuoteStep] - | [TradeQuoteStep, TradeQuoteStep], + steps: quote.steps.map(step => step) as [TradeQuoteStep] | [TradeQuoteStep, TradeQuoteStep], })), ) } diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index 62a7c83ede9..411e22cb8e6 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -312,9 +312,7 @@ export const getTradeQuote = async ( ...quote, quoteOrRate: 'quote' as const, receiveAddress: quote.receiveAddress!, - steps: quote.steps.map(step => ({ ...step, accountNumber: undefined })) as - | [TradeQuoteStep] - | [TradeQuoteStep, TradeQuoteStep], + steps: quote.steps.map(step => step) as [TradeQuoteStep] | [TradeQuoteStep, TradeQuoteStep], })), ) } From f6aa61540f1fb809fb601771f8e8e970ef1eacde Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:00:29 +0800 Subject: [PATCH 12/24] feat: monkey patch --- .../src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index 411e22cb8e6..73a8e6f391a 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -144,7 +144,11 @@ export async function getTrade({ if (routesResponse.isErr()) return Err(routesResponse.unwrapErr()) - const { routes } = routesResponse.unwrap() + const { routes: _routes } = routesResponse.unwrap() + + // Monkey patch to always end up in the "unstable route not found the second time around" scenario, revert me before opening me, + // and link this commit to reviewers to revert before testing this PR + let routes = quoteOrRate === 'quote' ? [] : _routes if (routes.length === 0) { return Err( From 3dc0c954db234e9d8c4322dac9c8fc2d5c6f4c7c Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:23:54 +0800 Subject: [PATCH 13/24] feat: pass down originalRate --- .../LifiSwapper/getTradeQuote/getTradeQuote.ts | 10 +++++----- packages/swapper/src/types.ts | 2 +- .../hooks/useGetTradeQuotes/getTradeQuoteInput.ts | 8 ++++---- .../hooks/useGetTradeQuotes/useGetTradeQuotes.tsx | 2 +- src/components/MultiHopTrade/types.ts | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index 73a8e6f391a..a2a6dd87dd1 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -40,7 +40,7 @@ export async function getTrade({ deps, lifiChainMap, }: { - input: GetEvmTradeQuoteInput & { lifiAllowedTools?: string[] | undefined } + input: GetEvmTradeQuoteInput deps: SwapperDeps lifiChainMap: Map }): Promise> { @@ -54,7 +54,7 @@ export async function getTrade({ supportsEIP1559, affiliateBps, potentialAffiliateBps, - lifiAllowedTools, + originalRate, quoteOrRate, } = input @@ -104,8 +104,8 @@ export async function getTrade({ // reverts, partial swaps, wrong received tokens (due to out-of-gas mid-trade), etc. For now, // these bridges are disabled. bridges: { deny: ['stargate', 'stargateV2', 'stargateV2Bus', 'amarok', 'arbitrum'] }, - ...(lifiAllowedTools && { - exchanges: { allow: lifiAllowedTools }, + ...(originalRate && { + exchanges: { allow: (originalRate as LifiTradeRate).lifiTools }, }), allowSwitchChain: true, fee: affiliateBpsDecimalPercentage.isZero() @@ -306,7 +306,7 @@ export async function getTrade({ } export const getTradeQuote = async ( - input: GetEvmTradeQuoteInputBase & { lifiAllowedTools?: string[] | undefined }, + input: GetEvmTradeQuoteInputBase, deps: SwapperDeps, lifiChainMap: Map, ): Promise> => { diff --git a/packages/swapper/src/types.ts b/packages/swapper/src/types.ts index 9c7426ad601..0e578a0dab9 100644 --- a/packages/swapper/src/types.ts +++ b/packages/swapper/src/types.ts @@ -157,7 +157,7 @@ type CommonTradeInputBase = { potentialAffiliateBps: string affiliateBps: string allowMultiHop: boolean - lifiAllowedTools?: string[] | undefined + originalRate?: TradeRate slippageTolerancePercentageDecimal?: string } diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput.ts b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput.ts index 49113591382..c0794b22df4 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput.ts +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput.ts @@ -1,7 +1,7 @@ import { CHAIN_NAMESPACE, fromChainId } from '@shapeshiftoss/caip' import type { HDWallet } from '@shapeshiftoss/hdwallet-core' import { supportsETH } from '@shapeshiftoss/hdwallet-core' -import type { GetTradeQuoteInput } from '@shapeshiftoss/swapper' +import type { GetTradeQuoteInput, TradeRate } from '@shapeshiftoss/swapper' import type { Asset, CosmosSdkChainId, EvmChainId, UtxoChainId } from '@shapeshiftoss/types' import { UtxoAccountType } from '@shapeshiftoss/types' import type { TradeQuoteInputCommonArgs } from 'components/MultiHopTrade/types' @@ -19,7 +19,7 @@ export type GetTradeQuoteInputArgs = { slippageTolerancePercentageDecimal?: string sellAmountBeforeFeesCryptoPrecision: string allowMultiHop: boolean - lifiAllowedTools?: string[] + originalRate?: TradeRate // Potential affiliate bps - may be waved out either entirely or partially with FOX discounts potentialAffiliateBps: string // Actual affiliate bps - if the FOX discounts is off, this will be the same as *affiliateBps* @@ -43,7 +43,7 @@ export const getTradeQuoteInput = async ({ receiveAddress, sellAmountBeforeFeesCryptoPrecision, allowMultiHop, - lifiAllowedTools, + originalRate, affiliateBps, potentialAffiliateBps, slippageTolerancePercentageDecimal, @@ -61,7 +61,7 @@ export const getTradeQuoteInput = async ({ affiliateBps: affiliateBps ?? '0', potentialAffiliateBps: potentialAffiliateBps ?? '0', allowMultiHop, - lifiAllowedTools, + originalRate, slippageTolerancePercentageDecimal, quoteOrRate, } diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx index fce9e1f7772..b1afaca9b1b 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx @@ -277,7 +277,7 @@ export const useGetTradeQuotes = () => { sellAccountType: sellAccountMetadata?.accountType, buyAsset, wallet: wallet ?? undefined, - lifiAllowedTools: (activeRateRef?.current as LifiTradeRate)?.lifiTools, + originalRate: activeRateRef?.current as LifiTradeRate, quoteOrRate: 'quote', receiveAddress, sellAmountBeforeFeesCryptoPrecision: sellAmountCryptoPrecision, diff --git a/src/components/MultiHopTrade/types.ts b/src/components/MultiHopTrade/types.ts index b7517e8aabf..9bf4b88f853 100644 --- a/src/components/MultiHopTrade/types.ts +++ b/src/components/MultiHopTrade/types.ts @@ -32,7 +32,7 @@ export type TradeQuoteInputCommonArgs = Pick< | 'allowMultiHop' | 'slippageTolerancePercentageDecimal' | 'quoteOrRate' - | 'lifiAllowedTools' + | 'originalRate' > export enum TradeInputTab { From 4f32b8934af4e624d8ac984c6cc149a53fd0b61f Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:33:17 +0800 Subject: [PATCH 14/24] feat: make it work --- .../LifiSwapper/getTradeQuote/getTradeQuote.ts | 15 +++++++++++---- packages/swapper/src/types.ts | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index a2a6dd87dd1..afb4bb3f5d9 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -54,7 +54,6 @@ export async function getTrade({ supportsEIP1559, affiliateBps, potentialAffiliateBps, - originalRate, quoteOrRate, } = input @@ -104,9 +103,10 @@ export async function getTrade({ // reverts, partial swaps, wrong received tokens (due to out-of-gas mid-trade), etc. For now, // these bridges are disabled. bridges: { deny: ['stargate', 'stargateV2', 'stargateV2Bus', 'amarok', 'arbitrum'] }, - ...(originalRate && { - exchanges: { allow: (originalRate as LifiTradeRate).lifiTools }, - }), + ...(quoteOrRate === 'quote' && + (input.originalRate as LifiTradeRate).lifiTools && { + exchanges: { allow: (input.originalRate as LifiTradeRate).lifiTools }, + }), allowSwitchChain: true, fee: affiliateBpsDecimalPercentage.isZero() ? undefined @@ -151,6 +151,13 @@ export async function getTrade({ let routes = quoteOrRate === 'quote' ? [] : _routes if (routes.length === 0) { + if (quoteOrRate === 'quote') + return Ok([ + { + ...input.originalRate, + quoteOrRate: 'quote', + } as LifiTradeQuote, + ]) return Err( makeSwapErrorRight({ message: 'no route found', diff --git a/packages/swapper/src/types.ts b/packages/swapper/src/types.ts index 0e578a0dab9..517ef5fdb8f 100644 --- a/packages/swapper/src/types.ts +++ b/packages/swapper/src/types.ts @@ -157,7 +157,6 @@ type CommonTradeInputBase = { potentialAffiliateBps: string affiliateBps: string allowMultiHop: boolean - originalRate?: TradeRate slippageTolerancePercentageDecimal?: string } @@ -166,6 +165,7 @@ export type CommonTradeQuoteInput = CommonTradeInputBase & { receiveAddress: string accountNumber: number quoteOrRate: 'quote' + originalRate: TradeRate } type CommonTradeRateInput = CommonTradeInputBase & { From 070f3d10f17d6cefb80c79becc12c7c4f6114dfc Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:27:35 +0800 Subject: [PATCH 15/24] feat: fuarkin TS mang... --- .../getCowSwapTradeQuote.test.ts | 8 ++- .../getTradeQuote/getTradeQuote.ts | 3 +- .../ThorchainSwapper/utils/getL1Rate.ts | 9 +-- .../src/swappers/ZrxSwapper/endpoints.ts | 4 +- .../utils/test-data/setupSwapQuote.ts | 3 +- packages/swapper/src/types.ts | 18 +++--- ...teInput.ts => getTradeQuoteOrRateInput.ts} | 58 ++++++++++++------- .../hooks/useGetSwapperTradeQuoteOrRate.tsx | 6 +- .../useGetTradeQuotes/useGetTradeQuotes.tsx | 52 +++++++++-------- .../useGetTradeQuotes/useGetTradeRates.tsx | 6 +- src/components/MultiHopTrade/types.ts | 16 ++++- .../Stake/Bridge/hooks/useRfoxBridge.ts | 3 +- src/state/apis/swapper/selectors.ts | 5 +- src/state/apis/swapper/swapperApi.ts | 6 +- src/state/apis/swapper/types.ts | 6 +- 15 files changed, 127 insertions(+), 76 deletions(-) rename src/components/MultiHopTrade/hooks/useGetTradeQuotes/{getTradeQuoteInput.ts => getTradeQuoteOrRateInput.ts} (80%) diff --git a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts index f50125e5b7b..e87fa85ff56 100644 --- a/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts +++ b/packages/swapper/src/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.test.ts @@ -8,7 +8,7 @@ import { COW_SWAP_NATIVE_ASSET_MARKER_ADDRESS, DEFAULT_ADDRESS, } from '../../../cowswap-utils/constants' -import type { GetTradeQuoteInput, SwapperConfig, TradeQuote } from '../../../types' +import type { GetTradeQuoteInput, SwapperConfig, TradeQuote, TradeRate } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' import { ETH, @@ -382,6 +382,7 @@ describe('getCowSwapTradeQuote', () => { allowMultiHop: false, slippageTolerancePercentageDecimal: '0.005', // 0.5% quoteOrRate: 'quote', + originalRate: {} as TradeRate, } const maybeTradeQuote = await getCowSwapTradeQuote(input, MOCK_COWSWAP_CONFIG) @@ -409,6 +410,7 @@ describe('getCowSwapTradeQuote', () => { allowMultiHop: false, slippageTolerancePercentageDecimal: '0.005', // 0.5% quoteOrRate: 'quote', + originalRate: {} as TradeRate, } mockedCowService.post.mockReturnValue( @@ -454,6 +456,7 @@ describe('getCowSwapTradeQuote', () => { allowMultiHop: false, slippageTolerancePercentageDecimal: '0.005', // 0.5% quoteOrRate: 'quote', + originalRate: {} as TradeRate, } mockedCowService.post.mockReturnValue( @@ -499,6 +502,7 @@ describe('getCowSwapTradeQuote', () => { allowMultiHop: false, slippageTolerancePercentageDecimal: '0.005', // 0.5% quoteOrRate: 'quote', + originalRate: {} as TradeRate, } mockedCowService.post.mockReturnValue( @@ -544,6 +548,7 @@ describe('getCowSwapTradeQuote', () => { allowMultiHop: false, slippageTolerancePercentageDecimal: '0.005', // 0.5% quoteOrRate: 'quote', + originalRate: {} as TradeRate, } mockedCowService.post.mockReturnValue( @@ -589,6 +594,7 @@ describe('getCowSwapTradeQuote', () => { allowMultiHop: false, slippageTolerancePercentageDecimal: '0.005', // 0.5% quoteOrRate: 'quote', + originalRate: {} as TradeRate, } mockedCowService.post.mockReturnValue( diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index afb4bb3f5d9..c2a1de5a49c 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -17,6 +17,7 @@ import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constant import type { GetEvmTradeQuoteInput, GetEvmTradeQuoteInputBase, + GetEvmTradeRateInput, MultiHopTradeQuoteSteps, SingleHopTradeQuoteSteps, SwapErrorRight, @@ -40,7 +41,7 @@ export async function getTrade({ deps, lifiChainMap, }: { - input: GetEvmTradeQuoteInput + input: GetEvmTradeQuoteInput | GetEvmTradeRateInput deps: SwapperDeps lifiChainMap: Map }): Promise> { diff --git a/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts b/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts index b0bfe7d47fe..54eddd355bf 100644 --- a/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts +++ b/packages/swapper/src/swappers/ThorchainSwapper/utils/getL1Rate.ts @@ -17,9 +17,10 @@ import { v4 as uuid } from 'uuid' import { getDefaultSlippageDecimalPercentageForSwapper } from '../../..' import type { - GetEvmTradeQuoteInput, + GetEvmTradeRateInput, GetTradeRateInput, GetUtxoTradeQuoteInput, + GetUtxoTradeRateInput, ProtocolFee, SwapErrorRight, SwapperDeps, @@ -216,7 +217,7 @@ export const getL1Rate = async ( const sellAdapter = deps.assertGetEvmChainAdapter(sellAsset.chainId) const { networkFeeCryptoBaseUnit } = await getEvmTxFees({ adapter: sellAdapter, - supportsEIP1559: Boolean((input as GetEvmTradeQuoteInput).supportsEIP1559), + supportsEIP1559: Boolean((input as GetEvmTradeRateInput).supportsEIP1559), }) const maybeRoutes = await Promise.allSettled( @@ -327,7 +328,7 @@ export const getL1Rate = async ( const feeData = await (async () => { // This is a rate without a wallet connected, so we can't get fees - if (!(input as GetUtxoTradeQuoteInput).xpub) + if (!(input as GetUtxoTradeRateInput).xpub) return { networkFeeCryptoBaseUnit: undefined, protocolFees: getProtocolFees(quote), @@ -340,7 +341,7 @@ export const getL1Rate = async ( const { vault, opReturnData, pubkey } = await getUtxoThorTxInfo({ sellAsset, - xpub: (input as GetUtxoTradeQuoteInput).xpub!, + xpub: (input as unknown as GetUtxoTradeQuoteInput).xpub!, memo, config: deps.config, }) diff --git a/packages/swapper/src/swappers/ZrxSwapper/endpoints.ts b/packages/swapper/src/swappers/ZrxSwapper/endpoints.ts index 9ab8ba9a909..313665bc188 100644 --- a/packages/swapper/src/swappers/ZrxSwapper/endpoints.ts +++ b/packages/swapper/src/swappers/ZrxSwapper/endpoints.ts @@ -10,7 +10,7 @@ import type { EvmTransactionRequest, GetEvmTradeQuoteInputBase, GetEvmTradeRateInput, - GetTradeQuoteInput, + GetTradeRateInput, GetUnsignedEvmTransactionArgs, SwapErrorRight, SwapperApi, @@ -37,7 +37,7 @@ export const zrxApi: SwapperApi = { return tradeQuoteResult.map(tradeQuote => [tradeQuote]) }, getTradeRate: async ( - input: GetTradeQuoteInput, + input: GetTradeRateInput, { assetsById, config }: SwapperDeps, ): Promise> => { const tradeRateResult = await getZrxTradeRate( diff --git a/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts b/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts index 548d848219b..dae83fa6118 100644 --- a/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts +++ b/packages/swapper/src/swappers/utils/test-data/setupSwapQuote.ts @@ -1,7 +1,7 @@ import type { Asset } from '@shapeshiftoss/types' import { KnownChainIds } from '@shapeshiftoss/types' -import type { GetTradeQuoteInput, TradeQuote } from '../../../types' +import type { GetTradeQuoteInput, TradeQuote, TradeRate } from '../../../types' import { SwapperName } from '../../../types' import { DEFAULT_SLIPPAGE } from '../constants' import { FOX_MAINNET, WETH } from './assets' @@ -51,6 +51,7 @@ export const setupQuote = () => { allowMultiHop: false, slippageTolerancePercentageDecimal: DEFAULT_SLIPPAGE, quoteOrRate: 'quote', + originalRate: {} as TradeRate, } return { quoteInput, tradeQuote, buyAsset, sellAsset } diff --git a/packages/swapper/src/types.ts b/packages/swapper/src/types.ts index 517ef5fdb8f..2d87e357b77 100644 --- a/packages/swapper/src/types.ts +++ b/packages/swapper/src/types.ts @@ -175,7 +175,7 @@ type CommonTradeRateInput = CommonTradeInputBase & { quoteOrRate: 'rate' } -type CommonTradeInput = CommonTradeQuoteInput | CommonTradeRateInput +type CommonTradeInput = CommonTradeQuoteInput export type GetEvmTradeQuoteInputBase = CommonTradeQuoteInput & { chainId: EvmChainId @@ -185,7 +185,7 @@ export type GetEvmTradeRateInput = CommonTradeRateInput & { chainId: EvmChainId supportsEIP1559: false } -export type GetEvmTradeQuoteInput = GetEvmTradeQuoteInputBase | GetEvmTradeRateInput +export type GetEvmTradeQuoteInput = GetEvmTradeQuoteInputBase export type GetCosmosSdkTradeQuoteInputBase = CommonTradeQuoteInput & { chainId: CosmosSdkChainId @@ -206,16 +206,16 @@ type GetUtxoTradeQuoteWithWallet = CommonTradeQuoteInput & { xpub: string } -type GetUtxoTradeRateInput = CommonTradeRateInput & { +export type GetUtxoTradeRateInput = CommonTradeRateInput & { chainId: UtxoChainId - // We need a dummy script type when getting a quote without a wallet - // so we always use SegWit (which works across all UTXO chains) - accountType: UtxoAccountType.P2pkh - accountNumber: undefined - xpub: undefined + accountType: UtxoAccountType + // accountNumber and accountType may be undefined may be undefined if no wallet is connected + // accountType will default to UtxoAccountType.P2pkh without a wallet connected + accountNumber: number | undefined + xpub: string | undefined } -export type GetUtxoTradeQuoteInput = GetUtxoTradeQuoteWithWallet | GetUtxoTradeRateInput +export type GetUtxoTradeQuoteInput = GetUtxoTradeQuoteWithWallet export type GetTradeQuoteInput = | GetUtxoTradeQuoteInput diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput.ts b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts similarity index 80% rename from src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput.ts rename to src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts index c0794b22df4..1d159358a9f 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput.ts +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts @@ -1,10 +1,9 @@ import { CHAIN_NAMESPACE, fromChainId } from '@shapeshiftoss/caip' import type { HDWallet } from '@shapeshiftoss/hdwallet-core' import { supportsETH } from '@shapeshiftoss/hdwallet-core' -import type { GetTradeQuoteInput, TradeRate } from '@shapeshiftoss/swapper' +import type { GetTradeQuoteInput, GetTradeRateInput, TradeRate } from '@shapeshiftoss/swapper' import type { Asset, CosmosSdkChainId, EvmChainId, UtxoChainId } from '@shapeshiftoss/types' import { UtxoAccountType } from '@shapeshiftoss/types' -import type { TradeQuoteInputCommonArgs } from 'components/MultiHopTrade/types' import { toBaseUnit } from 'lib/math' import { assertUnreachable } from 'lib/utils' import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk' @@ -12,7 +11,7 @@ import { assertGetEvmChainAdapter } from 'lib/utils/evm' import { assertGetSolanaChainAdapter } from 'lib/utils/solana' import { assertGetUtxoChainAdapter } from 'lib/utils/utxo' -export type GetTradeQuoteInputArgs = { +export type GetTradeQuoteOrRateInputArgs = { sellAsset: Asset buyAsset: Asset sellAccountType: UtxoAccountType | undefined @@ -33,7 +32,7 @@ export type GetTradeQuoteInputArgs = { wallet: HDWallet | undefined } -export const getTradeQuoteInput = async ({ +export const getTradeQuoteOrRateInput = async ({ sellAsset, buyAsset, sellAccountNumber, @@ -48,23 +47,40 @@ export const getTradeQuoteInput = async ({ potentialAffiliateBps, slippageTolerancePercentageDecimal, pubKey, -}: GetTradeQuoteInputArgs): Promise => { - const tradeQuoteInputCommonArgs: TradeQuoteInputCommonArgs = { - sellAmountIncludingProtocolFeesCryptoBaseUnit: toBaseUnit( - sellAmountBeforeFeesCryptoPrecision, - sellAsset.precision, - ), - sellAsset, - buyAsset, - receiveAddress, - accountNumber: sellAccountNumber, - affiliateBps: affiliateBps ?? '0', - potentialAffiliateBps: potentialAffiliateBps ?? '0', - allowMultiHop, - originalRate, - slippageTolerancePercentageDecimal, - quoteOrRate, - } +}: GetTradeQuoteOrRateInputArgs): Promise => { + const tradeQuoteInputCommonArgs = + receiveAddress && sellAccountNumber !== undefined + ? { + sellAmountIncludingProtocolFeesCryptoBaseUnit: toBaseUnit( + sellAmountBeforeFeesCryptoPrecision, + sellAsset.precision, + ), + sellAsset, + buyAsset, + receiveAddress, + accountNumber: sellAccountNumber, + affiliateBps: affiliateBps ?? '0', + potentialAffiliateBps: potentialAffiliateBps ?? '0', + allowMultiHop, + slippageTolerancePercentageDecimal, + quoteOrRate: 'quote', + } + : { + sellAmountIncludingProtocolFeesCryptoBaseUnit: toBaseUnit( + sellAmountBeforeFeesCryptoPrecision, + sellAsset.precision, + ), + sellAsset, + buyAsset, + receiveAddress, + originalRate, + accountNumber: sellAccountNumber, + affiliateBps: affiliateBps ?? '0', + potentialAffiliateBps: potentialAffiliateBps ?? '0', + allowMultiHop, + slippageTolerancePercentageDecimal, + quoteOrRate: 'rate', + } const { chainNamespace } = fromChainId(sellAsset.chainId) diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useGetSwapperTradeQuoteOrRate.tsx b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useGetSwapperTradeQuoteOrRate.tsx index 841e1944e60..3a393cd0244 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useGetSwapperTradeQuoteOrRate.tsx +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useGetSwapperTradeQuoteOrRate.tsx @@ -1,5 +1,5 @@ import { skipToken } from '@reduxjs/toolkit/dist/query' -import type { GetTradeQuoteInput, SwapperName } from '@shapeshiftoss/swapper' +import type { GetTradeQuoteInput, GetTradeRateInput, SwapperName } from '@shapeshiftoss/swapper' import { useEffect, useMemo } from 'react' import { swapperApi, useGetTradeQuoteQuery } from 'state/apis/swapper/swapperApi' import { tradeQuoteSlice } from 'state/slices/tradeQuoteSlice/tradeQuoteSlice' @@ -7,14 +7,14 @@ import { useAppDispatch } from 'state/store' export type UseGetSwapperTradeQuoteOrRateArgs = { swapperName: SwapperName | undefined - tradeQuoteInput: GetTradeQuoteInput | typeof skipToken + tradeQuoteOrRateInput: GetTradeQuoteInput | GetTradeRateInput | typeof skipToken skip: boolean pollingInterval: number | undefined } export const useGetSwapperTradeQuoteOrRate = ({ swapperName, - tradeQuoteInput, + tradeQuoteOrRateInput: tradeQuoteInput, pollingInterval, skip, }: UseGetSwapperTradeQuoteOrRateArgs) => { diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx index b1afaca9b1b..c580ab3a213 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx @@ -1,7 +1,12 @@ import { skipToken as reduxSkipToken } from '@reduxjs/toolkit/query' import { fromAccountId } from '@shapeshiftoss/caip' import { isLedger } from '@shapeshiftoss/hdwallet-ledger' -import type { GetTradeQuoteInput, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' +import type { + GetTradeQuoteInput, + GetTradeRateInput, + TradeQuote, + TradeRate, +} from '@shapeshiftoss/swapper' import { DEFAULT_GET_TRADE_QUOTE_POLLING_INTERVAL, isExecutableTradeQuote, @@ -13,7 +18,7 @@ import type { LifiTradeRate } from '@shapeshiftoss/swapper/src/swappers/LifiSwap import { skipToken as reactQuerySkipToken, useQuery } from '@tanstack/react-query' import { useCallback, useEffect, useMemo, useRef } from 'react' import { useTradeReceiveAddress } from 'components/MultiHopTrade/components/TradeInput/hooks/useTradeReceiveAddress' -import { getTradeQuoteInput } from 'components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput' +import { getTradeQuoteOrRateInput } from 'components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput' import { useHasFocus } from 'hooks/useHasFocus' import { useWallet } from 'hooks/useWallet/useWallet' import { useWalletSupportsChain } from 'hooks/useWalletSupportsChain/useWalletSupportsChain' @@ -271,26 +276,27 @@ export const useGetTradeQuotes = () => { if (sellAccountNumber === undefined) throw new Error('sellAccountNumber is required') if (!receiveAddress) throw new Error('receiveAddress is required') - const updatedTradeQuoteInput: GetTradeQuoteInput | undefined = await getTradeQuoteInput({ - sellAsset, - sellAccountNumber, - sellAccountType: sellAccountMetadata?.accountType, - buyAsset, - wallet: wallet ?? undefined, - originalRate: activeRateRef?.current as LifiTradeRate, - quoteOrRate: 'quote', - receiveAddress, - sellAmountBeforeFeesCryptoPrecision: sellAmountCryptoPrecision, - allowMultiHop: true, - affiliateBps, - potentialAffiliateBps, - // Pass in the user's slippage preference if it's set, else let the swapper use its default - slippageTolerancePercentageDecimal: userSlippageTolerancePercentageDecimal, - pubKey: - wallet && isLedger(wallet) && sellAccountId - ? fromAccountId(sellAccountId).account - : undefined, - }) + const updatedTradeQuoteInput: GetTradeQuoteInput | GetTradeRateInput | undefined = + await getTradeQuoteOrRateInput({ + sellAsset, + sellAccountNumber, + sellAccountType: sellAccountMetadata?.accountType, + buyAsset, + wallet: wallet ?? undefined, + originalRate: activeRateRef?.current as LifiTradeRate, + quoteOrRate: 'quote', + receiveAddress, + sellAmountBeforeFeesCryptoPrecision: sellAmountCryptoPrecision, + allowMultiHop: true, + affiliateBps, + potentialAffiliateBps, + // Pass in the user's slippage preference if it's set, else let the swapper use its default + slippageTolerancePercentageDecimal: userSlippageTolerancePercentageDecimal, + pubKey: + wallet && isLedger(wallet) && sellAccountId + ? fromAccountId(sellAccountId).account + : undefined, + }) return updatedTradeQuoteInput } @@ -341,7 +347,7 @@ export const useGetTradeQuotes = () => { (swapperName: SwapperName | undefined): UseGetSwapperTradeQuoteOrRateArgs => { return { swapperName, - tradeQuoteInput: tradeQuoteInput ?? reduxSkipToken, + tradeQuoteOrRateInput: tradeQuoteInput ?? reduxSkipToken, // Skip trade quotes fetching which aren't for the swapper we have a rate for skip: !swapperName || !shouldFetchTradeQuotes, pollingInterval: diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx index 5e45f5d0e2e..28824e7bdc2 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeRates.tsx @@ -11,7 +11,7 @@ import { isThorTradeRate } from '@shapeshiftoss/swapper/dist/swappers/ThorchainS import { useQuery } from '@tanstack/react-query' import { useCallback, useEffect, useMemo } from 'react' import { useTradeReceiveAddress } from 'components/MultiHopTrade/components/TradeInput/hooks/useTradeReceiveAddress' -import { getTradeQuoteInput } from 'components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteInput' +import { getTradeQuoteOrRateInput } from 'components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput' import { useHasFocus } from 'hooks/useHasFocus' import { useWallet } from 'hooks/useWallet/useWallet' import { useWalletSupportsChain } from 'hooks/useWalletSupportsChain/useWalletSupportsChain' @@ -233,7 +233,7 @@ export const useGetTradeRates = () => { const potentialAffiliateBps = feeBpsBeforeDiscount.toFixed(0) const affiliateBps = feeBps.toFixed(0) - const updatedTradeRateInput = (await getTradeQuoteInput({ + const updatedTradeRateInput = (await getTradeQuoteOrRateInput({ sellAsset, sellAccountNumber, sellAccountType: sellAccountMetadata?.accountType, @@ -261,7 +261,7 @@ export const useGetTradeRates = () => { (swapperName: SwapperName): UseGetSwapperTradeQuoteOrRateArgs => { return { swapperName, - tradeQuoteInput: tradeRateInput ?? skipToken, + tradeQuoteOrRateInput: tradeRateInput ?? skipToken, skip: !shouldRefetchTradeQuotes, pollingInterval: swappers[swapperName]?.pollingInterval ?? DEFAULT_GET_TRADE_QUOTE_POLLING_INTERVAL, diff --git a/src/components/MultiHopTrade/types.ts b/src/components/MultiHopTrade/types.ts index 9bf4b88f853..164ed968d1b 100644 --- a/src/components/MultiHopTrade/types.ts +++ b/src/components/MultiHopTrade/types.ts @@ -1,5 +1,5 @@ import type { HDWallet } from '@shapeshiftoss/hdwallet-core' -import type { GetTradeQuoteInput } from '@shapeshiftoss/swapper' +import type { GetTradeQuoteInput, GetTradeRateInput } from '@shapeshiftoss/swapper' import type { AccountMetadata, Asset } from '@shapeshiftoss/types' export enum TradeRoutePaths { @@ -35,6 +35,20 @@ export type TradeQuoteInputCommonArgs = Pick< | 'originalRate' > +export type TradeRateInputCommonArgs = Pick< + GetTradeRateInput, + | 'sellAmountIncludingProtocolFeesCryptoBaseUnit' + | 'sellAsset' + | 'buyAsset' + | 'receiveAddress' + | 'accountNumber' + | 'affiliateBps' + | 'potentialAffiliateBps' + | 'allowMultiHop' + | 'slippageTolerancePercentageDecimal' + | 'quoteOrRate' +> + export enum TradeInputTab { Trade = 'trade', Claim = 'claim', diff --git a/src/pages/RFOX/components/Stake/Bridge/hooks/useRfoxBridge.ts b/src/pages/RFOX/components/Stake/Bridge/hooks/useRfoxBridge.ts index 19e25b07f04..57649fc0fc7 100644 --- a/src/pages/RFOX/components/Stake/Bridge/hooks/useRfoxBridge.ts +++ b/src/pages/RFOX/components/Stake/Bridge/hooks/useRfoxBridge.ts @@ -3,7 +3,7 @@ import { fromAccountId, fromAssetId } from '@shapeshiftoss/caip' import { CONTRACT_INTERACTION, isEvmChainId } from '@shapeshiftoss/chain-adapters' import { getEthersV5Provider, viemClientByChainId } from '@shapeshiftoss/contracts' import { supportsETH } from '@shapeshiftoss/hdwallet-core' -import type { SwapErrorRight, TradeQuote } from '@shapeshiftoss/swapper' +import type { SwapErrorRight, TradeQuote, TradeRate } from '@shapeshiftoss/swapper' import { arbitrumBridgeApi } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/endpoints' import { getTradeQuoteWithWallet } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote' import type { GetEvmTradeQuoteInputWithWallet } from '@shapeshiftoss/swapper/dist/swappers/ArbitrumBridgeSwapper/types' @@ -145,6 +145,7 @@ export const useRfoxBridge = ({ confirmedQuote }: UseRfoxBridgeProps): UseRfoxBr accountNumber: sellAssetAccountNumber, hasWallet: Boolean(walletInfo?.deviceId), quoteOrRate: 'quote' as const, + originalRate: {} as TradeRate, }), [ buyAsset, diff --git a/src/state/apis/swapper/selectors.ts b/src/state/apis/swapper/selectors.ts index 91f1c2db298..b93e5d586d5 100644 --- a/src/state/apis/swapper/selectors.ts +++ b/src/state/apis/swapper/selectors.ts @@ -4,7 +4,7 @@ import type { PartialRecord } from '@shapeshiftoss/types' import type { ReduxState } from 'state/reducer' import { createDeepEqualOutputSelector } from 'state/selector-utils' -import type { TradeQuoteRequest } from './types' +import type { TradeQuoteOrRateRequest } from './types' const selectSwapperApiQueries = (state: ReduxState) => state.swapperApi.queries @@ -17,7 +17,8 @@ export const selectIsTradeQuoteApiQueryPending = createDeepEqualOutputSelector( for (const [queryKey, queryInfo] of Object.entries(queries)) { if (!queryKey.startsWith('getTradeQuote')) continue - const swapperName = (queryInfo?.originalArgs as TradeQuoteRequest | undefined)?.swapperName + const swapperName = (queryInfo?.originalArgs as TradeQuoteOrRateRequest | undefined) + ?.swapperName if (!swapperName) continue diff --git a/src/state/apis/swapper/swapperApi.ts b/src/state/apis/swapper/swapperApi.ts index 0a145472cf4..d0c19a3cef3 100644 --- a/src/state/apis/swapper/swapperApi.ts +++ b/src/state/apis/swapper/swapperApi.ts @@ -23,7 +23,7 @@ import { assertGetSolanaChainAdapter } from 'lib/utils/solana' import { thorchainBlockTimeMs } from 'lib/utils/thorchain/constants' import { assertGetUtxoChainAdapter } from 'lib/utils/utxo' import { getInputOutputRatioFromQuote } from 'state/apis/swapper/helpers/getInputOutputRatioFromQuote' -import type { ApiQuote, TradeQuoteRequest } from 'state/apis/swapper/types' +import type { ApiQuote, TradeQuoteOrRateRequest } from 'state/apis/swapper/types' import { TradeQuoteValidationError } from 'state/apis/swapper/types' import { getEnabledSwappers } from 'state/helpers' import type { ReduxState } from 'state/reducer' @@ -42,8 +42,8 @@ export const swapperApi = createApi({ keepUnusedDataFor: Number.MAX_SAFE_INTEGER, // never clear, we will manage this tagTypes: ['TradeQuote'], endpoints: build => ({ - getTradeQuote: build.query, TradeQuoteRequest>({ - queryFn: async (tradeQuoteInput: TradeQuoteRequest, { dispatch, getState }) => { + getTradeQuote: build.query, TradeQuoteOrRateRequest>({ + queryFn: async (tradeQuoteInput: TradeQuoteOrRateRequest, { dispatch, getState }) => { const state = getState() as ReduxState const { swapperName, diff --git a/src/state/apis/swapper/types.ts b/src/state/apis/swapper/types.ts index 3809a18d0dd..24cb71f933c 100644 --- a/src/state/apis/swapper/types.ts +++ b/src/state/apis/swapper/types.ts @@ -1,5 +1,6 @@ import type { GetTradeQuoteInput, + GetTradeRateInput, SwapperName, TradeQuote, TradeQuoteError as SwapperTradeQuoteError, @@ -53,4 +54,7 @@ export type ApiQuote = { isStale: boolean } -export type TradeQuoteRequest = { swapperName: SwapperName } & GetTradeQuoteInput +export type TradeQuoteOrRateRequest = { swapperName: SwapperName } & ( + | GetTradeQuoteInput + | GetTradeRateInput +) From cf8127316edc488e2a2b0c4c3f7f456acea51aaf Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:30:10 +0800 Subject: [PATCH 16/24] fix: derp --- .../hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts index 1d159358a9f..a0ccd229e83 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts @@ -49,7 +49,7 @@ export const getTradeQuoteOrRateInput = async ({ pubKey, }: GetTradeQuoteOrRateInputArgs): Promise => { const tradeQuoteInputCommonArgs = - receiveAddress && sellAccountNumber !== undefined + quoteOrRate === 'quote' && receiveAddress && sellAccountNumber !== undefined ? { sellAmountIncludingProtocolFeesCryptoBaseUnit: toBaseUnit( sellAmountBeforeFeesCryptoPrecision, From ca4af487ba47ee50be95c8c9cbbdb2f2baadd231 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:39:30 +0800 Subject: [PATCH 17/24] fix: absolute derp --- .../hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts index a0ccd229e83..4f061de8a85 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts @@ -64,6 +64,7 @@ export const getTradeQuoteOrRateInput = async ({ allowMultiHop, slippageTolerancePercentageDecimal, quoteOrRate: 'quote', + originalRate, } : { sellAmountIncludingProtocolFeesCryptoBaseUnit: toBaseUnit( From e78c25850e2b7626e66bce8281cb78287620624e Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:54:10 +0800 Subject: [PATCH 18/24] feat: here we fuarkin go --- packages/swapper/src/swappers/LifiSwapper/endpoints.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/endpoints.ts b/packages/swapper/src/swappers/LifiSwapper/endpoints.ts index b1dd5ca4e2f..e03e7cf85a4 100644 --- a/packages/swapper/src/swappers/LifiSwapper/endpoints.ts +++ b/packages/swapper/src/swappers/LifiSwapper/endpoints.ts @@ -64,7 +64,9 @@ export const lifiApi: SwapperApi = { ) return tradeQuoteResult.map(quote => - quote.map(({ selectedLifiRoute, ...tradeQuote }) => { + quote.map(tradeQuote => { + const { selectedLifiRoute } = tradeQuote + // TODO: quotes below the minimum aren't valid and should not be processed as such // selectedLifiRoute will be missing for quotes below the minimum if (!selectedLifiRoute) throw Error('missing selectedLifiRoute') @@ -98,7 +100,9 @@ export const lifiApi: SwapperApi = { const tradeRateResult = await getTradeRate(input as GetEvmTradeRateInput, deps, lifiChainMap) return tradeRateResult.map(quote => - quote.map(({ selectedLifiRoute, ...tradeQuote }) => { + quote.map(tradeQuote => { + const { selectedLifiRoute } = tradeQuote + // TODO: quotes below the minimum aren't valid and should not be processed as such // selectedLifiRoute will be missing for quotes below the minimum if (!selectedLifiRoute) throw Error('missing selectedLifiRoute') From d908eed4b3f48f8b58b191f6204468519357f4cd Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:04:42 +0800 Subject: [PATCH 19/24] feat: revert "feat: monkey patch" This reverts commit 20792923790308e0541299d6701352eee215b15d. --- .../src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index c2a1de5a49c..6ecc147a2a3 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -145,11 +145,7 @@ export async function getTrade({ if (routesResponse.isErr()) return Err(routesResponse.unwrapErr()) - const { routes: _routes } = routesResponse.unwrap() - - // Monkey patch to always end up in the "unstable route not found the second time around" scenario, revert me before opening me, - // and link this commit to reviewers to revert before testing this PR - let routes = quoteOrRate === 'quote' ? [] : _routes + const { routes } = routesResponse.unwrap() if (routes.length === 0) { if (quoteOrRate === 'quote') From 5aa17ccc6146203a03d00362c922c7a71c26b5bf Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:42:43 +0800 Subject: [PATCH 20/24] fix: jupiter undefined receiveAddy --- .../src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts index c11af9a6196..886ff7cc8cc 100644 --- a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts +++ b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts @@ -200,7 +200,7 @@ export const getTradeRate = async ( id: uuid(), quoteOrRate: 'rate', rate: inputOutputRate, - receiveAddress: undefined, + receiveAddress, potentialAffiliateBps: affiliateBps, affiliateBps, slippageTolerancePercentageDecimal, From 3ac3a4e116aa567a16bf8325c75ba5fee4821f51 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Thu, 12 Dec 2024 23:34:09 +0800 Subject: [PATCH 21/24] Revert "feat: revert "feat: monkey patch"" This reverts commit ada024309c92402252219e3ef9cafcfda8f25f3e. --- .../src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index 6ecc147a2a3..c2a1de5a49c 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -145,7 +145,11 @@ export async function getTrade({ if (routesResponse.isErr()) return Err(routesResponse.unwrapErr()) - const { routes } = routesResponse.unwrap() + const { routes: _routes } = routesResponse.unwrap() + + // Monkey patch to always end up in the "unstable route not found the second time around" scenario, revert me before opening me, + // and link this commit to reviewers to revert before testing this PR + let routes = quoteOrRate === 'quote' ? [] : _routes if (routes.length === 0) { if (quoteOrRate === 'quote') From 4f90e8c95cb090dbb72e0826d6055b71b729ad02 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:26:25 +0800 Subject: [PATCH 22/24] Revert "Revert "feat: revert "feat: monkey patch""" This reverts commit 3ac3a4e116aa567a16bf8325c75ba5fee4821f51. --- .../src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts index c2a1de5a49c..6ecc147a2a3 100644 --- a/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts +++ b/packages/swapper/src/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts @@ -145,11 +145,7 @@ export async function getTrade({ if (routesResponse.isErr()) return Err(routesResponse.unwrapErr()) - const { routes: _routes } = routesResponse.unwrap() - - // Monkey patch to always end up in the "unstable route not found the second time around" scenario, revert me before opening me, - // and link this commit to reviewers to revert before testing this PR - let routes = quoteOrRate === 'quote' ? [] : _routes + const { routes } = routesResponse.unwrap() if (routes.length === 0) { if (quoteOrRate === 'quote') From 58d2115601748c9db59455c9cf5d9c488431a589 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:27:30 +0800 Subject: [PATCH 23/24] feat: cleanup --- src/components/MultiHopTrade/types.ts | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/components/MultiHopTrade/types.ts b/src/components/MultiHopTrade/types.ts index 164ed968d1b..9bf4b88f853 100644 --- a/src/components/MultiHopTrade/types.ts +++ b/src/components/MultiHopTrade/types.ts @@ -1,5 +1,5 @@ import type { HDWallet } from '@shapeshiftoss/hdwallet-core' -import type { GetTradeQuoteInput, GetTradeRateInput } from '@shapeshiftoss/swapper' +import type { GetTradeQuoteInput } from '@shapeshiftoss/swapper' import type { AccountMetadata, Asset } from '@shapeshiftoss/types' export enum TradeRoutePaths { @@ -35,20 +35,6 @@ export type TradeQuoteInputCommonArgs = Pick< | 'originalRate' > -export type TradeRateInputCommonArgs = Pick< - GetTradeRateInput, - | 'sellAmountIncludingProtocolFeesCryptoBaseUnit' - | 'sellAsset' - | 'buyAsset' - | 'receiveAddress' - | 'accountNumber' - | 'affiliateBps' - | 'potentialAffiliateBps' - | 'allowMultiHop' - | 'slippageTolerancePercentageDecimal' - | 'quoteOrRate' -> - export enum TradeInputTab { Trade = 'trade', Claim = 'claim', From d0fecda63969c7a3fb9c804201ed566ec5979dc4 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:30:18 +0800 Subject: [PATCH 24/24] fix: typo --- packages/swapper/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/swapper/src/types.ts b/packages/swapper/src/types.ts index 2d87e357b77..0da89b9c7d9 100644 --- a/packages/swapper/src/types.ts +++ b/packages/swapper/src/types.ts @@ -209,7 +209,7 @@ type GetUtxoTradeQuoteWithWallet = CommonTradeQuoteInput & { export type GetUtxoTradeRateInput = CommonTradeRateInput & { chainId: UtxoChainId accountType: UtxoAccountType - // accountNumber and accountType may be undefined may be undefined if no wallet is connected + // accountNumber and accountType may be undefined if no wallet is connected // accountType will default to UtxoAccountType.P2pkh without a wallet connected accountNumber: number | undefined xpub: string | undefined