From 456867c3529c0491c7d59e805cd5411735a09717 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Wed, 14 May 2025 14:48:01 +0700 Subject: [PATCH] fix signal and get position during closing --- src/Managing.Domain/Strategies/Signal.cs | 3 +- .../EvmManager.cs | 12 +- .../gmxsdk/modules/orders/helpers.ts | 824 +++++++++--------- 3 files changed, 420 insertions(+), 419 deletions(-) diff --git a/src/Managing.Domain/Strategies/Signal.cs b/src/Managing.Domain/Strategies/Signal.cs index 7200ad5..6461d57 100644 --- a/src/Managing.Domain/Strategies/Signal.cs +++ b/src/Managing.Domain/Strategies/Signal.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using System.Globalization; using Managing.Core; using Managing.Domain.Candles; using Managing.Domain.Users; @@ -34,7 +35,7 @@ namespace Managing.Domain.Strategies StrategyType = strategyType; User = user; - Identifier = $"{StrategyType}-{direction}-{ticker}-{candle?.Close}-{date:yyyyMMdd-HHmmss}"; + Identifier = $"{StrategyType}-{direction}-{ticker}-{candle?.Close.ToString(CultureInfo.InvariantCulture)}-{date:yyyyMMdd-HHmmss}"; SignalType = signalType; } diff --git a/src/Managing.Infrastructure.Web3/EvmManager.cs b/src/Managing.Infrastructure.Web3/EvmManager.cs index eb4a21a..f44e61c 100644 --- a/src/Managing.Infrastructure.Web3/EvmManager.cs +++ b/src/Managing.Infrastructure.Web3/EvmManager.cs @@ -458,10 +458,10 @@ public class EvmManager : IEvmManager { // Log the error Console.Error.WriteLine($"Error initializing address: {ex.Message}"); - return new PrivyInitAddressResponse - { - Success = false, - Error = ex.Message + return new PrivyInitAddressResponse + { + Success = false, + Error = ex.Message }; } } @@ -660,7 +660,9 @@ public class EvmManager : IEvmManager { account = account.Key, ticker = ticker.ToString(), - direction = direction.ToString(), + direction = direction == TradeDirection.Long + ? TradeDirection.Short.ToString() + : TradeDirection.Long.ToString(), }); trade = new Trade( DateTime.UtcNow, diff --git a/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/helpers.ts b/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/helpers.ts index 1284969..b2aad76 100644 --- a/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/helpers.ts +++ b/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/helpers.ts @@ -15,483 +15,481 @@ import {EntryField, SidecarSlTpOrderEntryValid} from "../../types/sidecarOrders. /** Base Optional params for helpers, allows to avoid calling markets, tokens and uiFeeFactor methods if they are already passed */ interface BaseOptionalParams { - marketsInfoData?: MarketsInfoData; - tokensData?: TokensData; - uiFeeFactor?: bigint; + marketsInfoData?: MarketsInfoData; + tokensData?: TokensData; + uiFeeFactor?: bigint; } export type PositionIncreaseParams = ( - | { - /** Increase amounts will be calculated based on collateral amount */ - payAmount: bigint; - } - | { - /** Increase amounts will be calculated based on position size amount */ - sizeAmount: bigint; - } -) & { - marketAddress: string; - payTokenAddress: string; - collateralTokenAddress: string; + | { + /** Increase amounts will be calculated based on collateral amount */ + payAmount: bigint; +} + | { + /** Increase amounts will be calculated based on position size amount */ + sizeAmount: bigint; +} + ) & { + marketAddress: string; + payTokenAddress: string; + collateralTokenAddress: string; - /** @default 100 */ - allowedSlippageBps?: number; - referralCodeForTxn?: string; + /** @default 100 */ + allowedSlippageBps?: number; + referralCodeForTxn?: string; - leverage?: bigint; - /** If presented, then it's limit order */ - limitPrice?: bigint; - acceptablePriceImpactBuffer?: number; - fixedAcceptablePriceImpactBps?: bigint; + leverage?: bigint; + /** If presented, then it's limit order */ + limitPrice?: bigint; + acceptablePriceImpactBuffer?: number; + fixedAcceptablePriceImpactBps?: bigint; - skipSimulation?: boolean; - stopLossPrice?: bigint; - takeProfitPrice?: bigint; + skipSimulation?: boolean; + stopLossPrice?: bigint; + takeProfitPrice?: bigint; } & BaseOptionalParams; async function getAndValidateBaseParams(sdk: GmxSdk, params: BaseOptionalParams) { - let tokensData: TokensData | undefined = params.tokensData; - let marketsInfoData: MarketsInfoData | undefined = params.marketsInfoData; + let tokensData: TokensData | undefined = params.tokensData; + let marketsInfoData: MarketsInfoData | undefined = params.marketsInfoData; - if (!params.marketsInfoData && !params.tokensData) { - const result = await sdk.markets.getMarketsInfo(); - marketsInfoData = result.marketsInfoData; - tokensData = result.tokensData; - } + if (!params.marketsInfoData && !params.tokensData) { + const result = await sdk.markets.getMarketsInfo(); + marketsInfoData = result.marketsInfoData; + tokensData = result.tokensData; + } - if (!tokensData) { - throw new Error("Tokens data is not available"); - } + if (!tokensData) { + throw new Error("Tokens data is not available"); + } - if (!marketsInfoData) { - throw new Error("Markets info data is not available"); - } + if (!marketsInfoData) { + throw new Error("Markets info data is not available"); + } - let uiFeeFactor = params.uiFeeFactor; - if (!uiFeeFactor) { - uiFeeFactor = await sdk.utils.getUiFeeFactor(); - } + let uiFeeFactor = params.uiFeeFactor; + if (!uiFeeFactor) { + uiFeeFactor = await sdk.utils.getUiFeeFactor(); + } - return { - tokensData, - marketsInfoData, - uiFeeFactor, - }; + return { + tokensData, + marketsInfoData, + uiFeeFactor, + }; } export async function increaseOrderHelper( - sdk: GmxSdk, - params: PositionIncreaseParams & { - isLong: boolean; - } + sdk: GmxSdk, + params: PositionIncreaseParams & { + isLong: boolean; + } ) { - const { tokensData, marketsInfoData, uiFeeFactor } = await getAndValidateBaseParams(sdk, params); + const {tokensData, marketsInfoData, uiFeeFactor} = await getAndValidateBaseParams(sdk, params); - const isLimit = Boolean(params.limitPrice); + const isLimit = Boolean(params.limitPrice); - const fromToken = tokensData[params.payTokenAddress]; - const collateralToken = tokensData[params.collateralTokenAddress]; + const fromToken = tokensData[params.payTokenAddress]; + const collateralToken = tokensData[params.collateralTokenAddress]; - if (!fromToken) { - throw new Error("From token is not available"); - } + if (!fromToken) { + throw new Error("From token is not available"); + } - if (!collateralToken) { - throw new Error("Collateral token is not available"); - } + if (!collateralToken) { + throw new Error("Collateral token is not available"); + } - const marketInfo = getByKey(marketsInfoData, params.marketAddress); + const marketInfo = getByKey(marketsInfoData, params.marketAddress); - if (!marketInfo) { - throw new Error("Market info is not available"); - } + if (!marketInfo) { + throw new Error("Market info is not available"); + } - const collateralTokenAddress = collateralToken.address; - const allowedSlippage = params.allowedSlippageBps ?? 100; + const collateralTokenAddress = collateralToken.address; + const allowedSlippage = params.allowedSlippageBps ?? 100; - const graph = getMarketsGraph(Object.values(marketsInfoData)); - const wrappedFromAddress = getWrappedAddress(sdk.chainId, params.payTokenAddress); - const wrappedToAddress = getWrappedAddress(sdk.chainId, collateralTokenAddress); + const graph = getMarketsGraph(Object.values(marketsInfoData)); + const wrappedFromAddress = getWrappedAddress(sdk.chainId, params.payTokenAddress); + const wrappedToAddress = getWrappedAddress(sdk.chainId, collateralTokenAddress); - const allPaths = findAllSwapPaths({ - chainId: sdk.chainId, - fromTokenAddress: params.payTokenAddress, - toTokenAddress: collateralTokenAddress, - marketsInfoData, - graph, - wrappedFromAddress, - wrappedToAddress, - }); - - const estimator = createSwapEstimator(marketsInfoData); - - const findSwapPath = createFindSwapPath({ - chainId: sdk.chainId, - fromTokenAddress: params.payTokenAddress, - toTokenAddress: collateralTokenAddress, - marketsInfoData, - estimator, - allPaths, - }); - - const payOrSizeAmount = "payAmount" in params ? params.payAmount : params.sizeAmount; - - const increaseAmounts = getIncreasePositionAmounts({ - marketInfo, - indexToken: marketInfo.indexToken, - initialCollateralToken: fromToken, - collateralToken, - isLong: params.isLong, - initialCollateralAmount: payOrSizeAmount, - position: undefined, - indexTokenAmount: payOrSizeAmount, - leverage: params.leverage, - triggerPrice: params.limitPrice, - limitOrderType: params.limitPrice ? OrderType.LimitIncrease : undefined, - userReferralInfo: undefined, - strategy: "payAmount" in params ? "leverageByCollateral" : "leverageBySize", - findSwapPath: findSwapPath, - uiFeeFactor, - acceptablePriceImpactBuffer: params.acceptablePriceImpactBuffer, - fixedAcceptablePriceImpactBps: params.fixedAcceptablePriceImpactBps, - externalSwapQuote: undefined, - }); - - const createSltpEntries: SidecarSlTpOrderEntryValid[] = [ - - ] - - let stopLossDecreaseAmounts: DecreasePositionAmounts | undefined; - if (params.stopLossPrice) { - const stopLossCollateralDeltaUsd = convertToUsd(increaseAmounts.collateralDeltaAmount, collateralToken.decimals, params.stopLossPrice); - - const acceptablePriceInfo = getAcceptablePriceInfo({ - marketInfo, - isIncrease: false, - isLong: params.isLong, - indexPrice: params.stopLossPrice, - sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, - maxNegativePriceImpactBps: marketInfo.maxPositionImpactFactorForLiquidations, + const allPaths = findAllSwapPaths({ + chainId: sdk.chainId, + fromTokenAddress: params.payTokenAddress, + toTokenAddress: collateralTokenAddress, + marketsInfoData, + graph, + wrappedFromAddress, + wrappedToAddress, }); - stopLossDecreaseAmounts = { - isFullClose: true, - sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, - sizeDeltaInTokens: increaseAmounts.sizeDeltaInTokens, - collateralDeltaUsd: stopLossCollateralDeltaUsd, - collateralDeltaAmount: increaseAmounts.collateralDeltaAmount, - indexPrice: params.stopLossPrice, - collateralPrice: 0n, - acceptablePrice: params.isLong ? 2n ** 256n - 1n : 0n, - acceptablePriceDeltaBps: acceptablePriceInfo.acceptablePriceDeltaBps, - recommendedAcceptablePriceDeltaBps: 0n, - estimatedPnl: 0n, - estimatedPnlPercentage: 0n, - realizedPnl: 0n, - realizedPnlPercentage: 0n, - positionFeeUsd: 0n, - uiFeeUsd: 0n, - swapUiFeeUsd: 0n, - feeDiscountUsd: 0n, - borrowingFeeUsd: 0n, - fundingFeeUsd: 0n, - swapProfitFeeUsd: 0n, - positionPriceImpactDeltaUsd: 0n, - priceImpactDiffUsd: 0n, - payedRemainingCollateralAmount: 0n, - payedOutputUsd: 0n, - payedRemainingCollateralUsd: 0n, - receiveTokenAmount: 0n, - receiveUsd: 0n, - decreaseSwapType: DecreasePositionSwapType.SwapPnlTokenToCollateralToken, - triggerOrderType: OrderType.StopLossDecrease, - triggerPrice: params.stopLossPrice, - } + const estimator = createSwapEstimator(marketsInfoData); - const stopLossEntry: SidecarSlTpOrderEntryValid = { - decreaseAmounts: stopLossDecreaseAmounts, - id: "sl-order", - price: { - input: params.stopLossPrice?.toString() ?? "", - value: params.stopLossPrice, - error: null, - } as EntryField, - sizeUsd: { - input: increaseAmounts.sizeDeltaUsd.toString(), - value: increaseAmounts.sizeDeltaUsd, - error: null, - } as EntryField, - percentage: { - input: "100", - value: 100n, - error: null, - } as EntryField, - txnType: "create", - mode: "keepSize", - order: null, - increaseAmounts: undefined - } - - createSltpEntries.push(stopLossEntry) - } - - let takeProfitDecreaseAmounts: DecreasePositionAmounts | undefined; - if (params.takeProfitPrice) { - const takeProfitCollateralDeltaUsd = convertToUsd(increaseAmounts.collateralDeltaAmount, collateralToken.decimals, params.takeProfitPrice); - - const acceptablePriceInfo = getAcceptablePriceInfo({ - marketInfo, - isIncrease: false, - isLong: params.isLong, - indexPrice: params.takeProfitPrice, - sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, - maxNegativePriceImpactBps: marketInfo.maxPositionImpactFactorForLiquidations, + const findSwapPath = createFindSwapPath({ + chainId: sdk.chainId, + fromTokenAddress: params.payTokenAddress, + toTokenAddress: collateralTokenAddress, + marketsInfoData, + estimator, + allPaths, }); - takeProfitDecreaseAmounts = { - isFullClose: true, - sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, - sizeDeltaInTokens: increaseAmounts.sizeDeltaInTokens, - collateralDeltaUsd: takeProfitCollateralDeltaUsd, - collateralDeltaAmount: increaseAmounts.collateralDeltaAmount, - indexPrice: params.takeProfitPrice, // Keep original trigger price for indexPrice - collateralPrice: 0n, // Consider if this needs calculation - acceptablePrice: acceptablePriceInfo.acceptablePrice, - acceptablePriceDeltaBps: acceptablePriceInfo.acceptablePriceDeltaBps, - recommendedAcceptablePriceDeltaBps: 0n, - estimatedPnl: 0n, - estimatedPnlPercentage: 0n, - realizedPnl: 0n, - realizedPnlPercentage: 0n, - positionFeeUsd: 0n, - uiFeeUsd: 0n, - swapUiFeeUsd: 0n, - feeDiscountUsd: 0n, - borrowingFeeUsd: 0n, - fundingFeeUsd: 0n, - swapProfitFeeUsd: 0n, - positionPriceImpactDeltaUsd: 0n, - priceImpactDiffUsd: 0n, - payedRemainingCollateralAmount: 0n, - payedOutputUsd: 0n, - payedRemainingCollateralUsd: 0n, - receiveTokenAmount: 0n, - receiveUsd: 0n, - decreaseSwapType: DecreasePositionSwapType.SwapPnlTokenToCollateralToken, - triggerOrderType: OrderType.LimitDecrease, - triggerPrice: params.takeProfitPrice, + const payOrSizeAmount = "payAmount" in params ? params.payAmount : params.sizeAmount; + + const increaseAmounts = getIncreasePositionAmounts({ + marketInfo, + indexToken: marketInfo.indexToken, + initialCollateralToken: fromToken, + collateralToken, + isLong: params.isLong, + initialCollateralAmount: payOrSizeAmount, + position: undefined, + indexTokenAmount: payOrSizeAmount, + leverage: params.leverage, + triggerPrice: params.limitPrice, + limitOrderType: params.limitPrice ? OrderType.LimitIncrease : undefined, + userReferralInfo: undefined, + strategy: "payAmount" in params ? "leverageByCollateral" : "leverageBySize", + findSwapPath: findSwapPath, + uiFeeFactor, + acceptablePriceImpactBuffer: params.acceptablePriceImpactBuffer, + fixedAcceptablePriceImpactBps: params.fixedAcceptablePriceImpactBps, + externalSwapQuote: undefined, + }); + + const createSltpEntries: SidecarSlTpOrderEntryValid[] = [] + + let stopLossDecreaseAmounts: DecreasePositionAmounts | undefined; + if (params.stopLossPrice) { + const stopLossCollateralDeltaUsd = convertToUsd(increaseAmounts.collateralDeltaAmount, collateralToken.decimals, params.stopLossPrice); + + const acceptablePriceInfo = getAcceptablePriceInfo({ + marketInfo, + isIncrease: false, + isLong: params.isLong, + indexPrice: params.stopLossPrice, + sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, + maxNegativePriceImpactBps: marketInfo.maxPositionImpactFactorForLiquidations, + }); + + stopLossDecreaseAmounts = { + isFullClose: true, + sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, + sizeDeltaInTokens: increaseAmounts.sizeDeltaInTokens, + collateralDeltaUsd: stopLossCollateralDeltaUsd, + collateralDeltaAmount: increaseAmounts.collateralDeltaAmount, + indexPrice: params.stopLossPrice, + collateralPrice: 0n, + acceptablePrice: params.isLong ? 2n ** 256n - 1n : 0n, + acceptablePriceDeltaBps: acceptablePriceInfo.acceptablePriceDeltaBps + 50n, + recommendedAcceptablePriceDeltaBps: 50n, + estimatedPnl: 0n, + estimatedPnlPercentage: 0n, + realizedPnl: 0n, + realizedPnlPercentage: 0n, + positionFeeUsd: 0n, + uiFeeUsd: 0n, + swapUiFeeUsd: 0n, + feeDiscountUsd: 0n, + borrowingFeeUsd: 0n, + fundingFeeUsd: 0n, + swapProfitFeeUsd: 0n, + positionPriceImpactDeltaUsd: 0n, + priceImpactDiffUsd: 0n, + payedRemainingCollateralAmount: 0n, + payedOutputUsd: 0n, + payedRemainingCollateralUsd: 0n, + receiveTokenAmount: 0n, + receiveUsd: 0n, + decreaseSwapType: DecreasePositionSwapType.SwapPnlTokenToCollateralToken, + triggerOrderType: OrderType.StopLossDecrease, + triggerPrice: params.stopLossPrice, + } + + const stopLossEntry: SidecarSlTpOrderEntryValid = { + decreaseAmounts: stopLossDecreaseAmounts, + id: "sl-order", + price: { + input: params.stopLossPrice?.toString() ?? "", + value: params.stopLossPrice, + error: null, + } as EntryField, + sizeUsd: { + input: increaseAmounts.sizeDeltaUsd.toString(), + value: increaseAmounts.sizeDeltaUsd, + error: null, + } as EntryField, + percentage: { + input: "100", + value: 100n, + error: null, + } as EntryField, + txnType: "create", + mode: "keepSize", + order: null, + increaseAmounts: undefined + } + + createSltpEntries.push(stopLossEntry) } - const takeProfitEntry: SidecarSlTpOrderEntryValid = { - decreaseAmounts: takeProfitDecreaseAmounts, - id: "tp-order", - price: { - input: params.takeProfitPrice?.toString() ?? "", - value: params.takeProfitPrice, - error: null, - } as EntryField, - sizeUsd: { - input: increaseAmounts.sizeDeltaUsd.toString(), - value: increaseAmounts.sizeDeltaUsd, - error: null, - } as EntryField, - percentage: { - input: "100", - value: 100n, - error: null, - } as EntryField, - txnType: "create", - mode: "keepSize", - order: null, - increaseAmounts: undefined + let takeProfitDecreaseAmounts: DecreasePositionAmounts | undefined; + if (params.takeProfitPrice) { + const takeProfitCollateralDeltaUsd = convertToUsd(increaseAmounts.collateralDeltaAmount, collateralToken.decimals, params.takeProfitPrice); + + const acceptablePriceInfo = getAcceptablePriceInfo({ + marketInfo, + isIncrease: false, + isLong: params.isLong, + indexPrice: params.takeProfitPrice, + sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, + maxNegativePriceImpactBps: marketInfo.maxPositionImpactFactorForLiquidations, + }); + + takeProfitDecreaseAmounts = { + isFullClose: true, + sizeDeltaUsd: increaseAmounts.sizeDeltaUsd, + sizeDeltaInTokens: increaseAmounts.sizeDeltaInTokens, + collateralDeltaUsd: takeProfitCollateralDeltaUsd, + collateralDeltaAmount: increaseAmounts.collateralDeltaAmount, + indexPrice: params.takeProfitPrice, // Keep original trigger price for indexPrice + collateralPrice: 0n, // Consider if this needs calculation + acceptablePrice: acceptablePriceInfo.acceptablePrice, + acceptablePriceDeltaBps: acceptablePriceInfo.acceptablePriceDeltaBps + 50n, // Add 0.5% buffer to acceptable price impact + recommendedAcceptablePriceDeltaBps: 50n, // Set recommended buffer to 0.5% + estimatedPnl: 0n, + estimatedPnlPercentage: 0n, + realizedPnl: 0n, + realizedPnlPercentage: 0n, + positionFeeUsd: 0n, + uiFeeUsd: 0n, + swapUiFeeUsd: 0n, + feeDiscountUsd: 0n, + borrowingFeeUsd: 0n, + fundingFeeUsd: 0n, + swapProfitFeeUsd: 0n, + positionPriceImpactDeltaUsd: 0n, + priceImpactDiffUsd: 0n, + payedRemainingCollateralAmount: 0n, + payedOutputUsd: 0n, + payedRemainingCollateralUsd: 0n, + receiveTokenAmount: 0n, + receiveUsd: 0n, + decreaseSwapType: DecreasePositionSwapType.SwapPnlTokenToCollateralToken, + triggerOrderType: OrderType.LimitDecrease, + triggerPrice: params.takeProfitPrice, + } + + const takeProfitEntry: SidecarSlTpOrderEntryValid = { + decreaseAmounts: takeProfitDecreaseAmounts, + id: "tp-order", + price: { + input: params.takeProfitPrice?.toString() ?? "", + value: params.takeProfitPrice, + error: null, + } as EntryField, + sizeUsd: { + input: increaseAmounts.sizeDeltaUsd.toString(), + value: increaseAmounts.sizeDeltaUsd, + error: null, + } as EntryField, + percentage: { + input: "100", + value: 100n, + error: null, + } as EntryField, + txnType: "create", + mode: "keepSize", + order: null, + increaseAmounts: undefined + } + + createSltpEntries.push(takeProfitEntry) } - createSltpEntries.push(takeProfitEntry) - } + const createIncreaseOrderParams: Parameters[0] = { + marketsInfoData, + tokensData, + isLimit, + marketAddress: params.marketAddress, + fromToken: tokensData[params.payTokenAddress], + allowedSlippage, + collateralToken, + referralCodeForTxn: params.referralCodeForTxn, + triggerPrice: params.limitPrice, + collateralTokenAddress: collateralToken.address, + isLong: params.isLong, + receiveTokenAddress: collateralTokenAddress, + indexToken: marketInfo.indexToken, + marketInfo, + skipSimulation: params.skipSimulation, + increaseAmounts, + createSltpEntries: createSltpEntries.length > 0 ? createSltpEntries : undefined, + }; - const createIncreaseOrderParams: Parameters[0] = { - marketsInfoData, - tokensData, - isLimit, - marketAddress: params.marketAddress, - fromToken: tokensData[params.payTokenAddress], - allowedSlippage, - collateralToken, - referralCodeForTxn: params.referralCodeForTxn, - triggerPrice: params.limitPrice, - collateralTokenAddress: collateralToken.address, - isLong: params.isLong, - receiveTokenAddress: collateralTokenAddress, - indexToken: marketInfo.indexToken, - marketInfo, - skipSimulation: params.skipSimulation, - increaseAmounts, - createSltpEntries: createSltpEntries.length > 0 ? createSltpEntries : undefined, - }; - - return sdk.orders.createIncreaseOrder(createIncreaseOrderParams); + return sdk.orders.createIncreaseOrder(createIncreaseOrderParams); } function getTriggerRatio({ - toToken, - fromToken, - triggerPrice, -}: { - toToken: TokenData; - fromToken: TokenData; - triggerPrice: bigint; + toToken, + fromToken, + triggerPrice, + }: { + toToken: TokenData; + fromToken: TokenData; + triggerPrice: bigint; }) { - const fromTokenPrice = fromToken?.prices.minPrice; - const markPrice = toToken.prices.minPrice; + const fromTokenPrice = fromToken?.prices.minPrice; + const markPrice = toToken.prices.minPrice; - const markRatio = getTokensRatioByPrice({ - fromToken, - toToken, - fromPrice: fromTokenPrice, - toPrice: markPrice, - }); + const markRatio = getTokensRatioByPrice({ + fromToken, + toToken, + fromPrice: fromTokenPrice, + toPrice: markPrice, + }); - const triggerRatio: TokensRatio = { - ratio: triggerPrice > 0 ? triggerPrice : markRatio.ratio, - largestToken: markRatio.largestToken, - smallestToken: markRatio.smallestToken, - }; + const triggerRatio: TokensRatio = { + ratio: triggerPrice > 0 ? triggerPrice : markRatio.ratio, + largestToken: markRatio.largestToken, + smallestToken: markRatio.smallestToken, + }; - return triggerRatio; + return triggerRatio; } export type SwapParams = ( - | { - fromAmount: bigint; - } - | { - toAmount: bigint; - } -) & { - fromTokenAddress: string; - toTokenAddress: string; - allowedSlippageBps?: number; - referralCodeForTxn?: string; + | { + fromAmount: bigint; +} + | { + toAmount: bigint; +} + ) & { + fromTokenAddress: string; + toTokenAddress: string; + allowedSlippageBps?: number; + referralCodeForTxn?: string; - /** If presented, then it's limit swap order */ - triggerPrice?: bigint; + /** If presented, then it's limit swap order */ + triggerPrice?: bigint; } & BaseOptionalParams; export async function swap(sdk: GmxSdk, params: SwapParams) { - const { tokensData, marketsInfoData, uiFeeFactor } = await getAndValidateBaseParams(sdk, params); + const {tokensData, marketsInfoData, uiFeeFactor} = await getAndValidateBaseParams(sdk, params); - const fromToken = tokensData[params.fromTokenAddress]; - const toToken = tokensData[params.toTokenAddress]; + const fromToken = tokensData[params.fromTokenAddress]; + const toToken = tokensData[params.toTokenAddress]; - if (!fromToken || !toToken) { - throw new Error("From or to token is not available"); - } + if (!fromToken || !toToken) { + throw new Error("From or to token is not available"); + } - const isLimit = Boolean(params.triggerPrice); + const isLimit = Boolean(params.triggerPrice); - if (!fromToken || !toToken) { - return undefined; - } + if (!fromToken || !toToken) { + return undefined; + } - const graph = getMarketsGraph(Object.values(marketsInfoData)); - const wrappedFromAddress = getWrappedAddress(sdk.chainId, params.fromTokenAddress); - const wrappedToAddress = getWrappedAddress(sdk.chainId, params.toTokenAddress); + const graph = getMarketsGraph(Object.values(marketsInfoData)); + const wrappedFromAddress = getWrappedAddress(sdk.chainId, params.fromTokenAddress); + const wrappedToAddress = getWrappedAddress(sdk.chainId, params.toTokenAddress); - const allPaths = findAllSwapPaths({ - chainId: sdk.chainId, - fromTokenAddress: params.fromTokenAddress, - toTokenAddress: params.toTokenAddress, - marketsInfoData, - graph, - wrappedFromAddress, - wrappedToAddress, - }); + const allPaths = findAllSwapPaths({ + chainId: sdk.chainId, + fromTokenAddress: params.fromTokenAddress, + toTokenAddress: params.toTokenAddress, + marketsInfoData, + graph, + wrappedFromAddress, + wrappedToAddress, + }); - const estimator = createSwapEstimator(marketsInfoData); + const estimator = createSwapEstimator(marketsInfoData); - const findSwapPath = createFindSwapPath({ - chainId: sdk.chainId, - fromTokenAddress: params.fromTokenAddress, - toTokenAddress: params.toTokenAddress, - marketsInfoData, - estimator, - allPaths, - }); + const findSwapPath = createFindSwapPath({ + chainId: sdk.chainId, + fromTokenAddress: params.fromTokenAddress, + toTokenAddress: params.toTokenAddress, + marketsInfoData, + estimator, + allPaths, + }); - const isWrapOrUnwrap = Boolean( - fromToken && toToken && (getIsWrap(fromToken, toToken) || getIsUnwrap(fromToken, toToken)) - ); + const isWrapOrUnwrap = Boolean( + fromToken && toToken && (getIsWrap(fromToken, toToken) || getIsUnwrap(fromToken, toToken)) + ); - const swapOptimizationOrder: Parameters[1]["order"] = isLimit ? ["length", "liquidity"] : undefined; + const swapOptimizationOrder: Parameters[1]["order"] = isLimit ? ["length", "liquidity"] : undefined; - let swapAmounts: SwapAmounts | undefined; + let swapAmounts: SwapAmounts | undefined; - const fromTokenPrice = fromToken.prices.minPrice; - const triggerRatio = params.triggerPrice - ? getTriggerRatio({ - fromToken, - toToken, + const fromTokenPrice = fromToken.prices.minPrice; + const triggerRatio = params.triggerPrice + ? getTriggerRatio({ + fromToken, + toToken, + triggerPrice: params.triggerPrice, + }) + : undefined; + + if (isWrapOrUnwrap) { + const tokenAmount = "fromAmount" in params ? params.fromAmount : params.toAmount; + const usdAmount = convertToUsd(tokenAmount, fromToken.decimals, fromTokenPrice)!; + const price = fromTokenPrice; + + swapAmounts = { + amountIn: tokenAmount, + usdIn: usdAmount!, + amountOut: tokenAmount, + usdOut: usdAmount!, + swapPathStats: undefined, + priceIn: price, + priceOut: price, + minOutputAmount: tokenAmount, + }; + + return swapAmounts; + } else if ("fromAmount" in params) { + swapAmounts = getSwapAmountsByFromValue({ + tokenIn: fromToken, + tokenOut: toToken, + amountIn: params.fromAmount, + triggerRatio, + isLimit, + findSwapPath: findSwapPath, + uiFeeFactor, + swapOptimizationOrder, + allowedSwapSlippageBps: isLimit ? BigInt(params.allowedSlippageBps ?? 100) : undefined, + }); + } else { + swapAmounts = getSwapAmountsByToValue({ + tokenIn: fromToken, + tokenOut: toToken, + amountOut: params.toAmount, + triggerRatio, + isLimit: isLimit, + findSwapPath: findSwapPath, + uiFeeFactor, + swapOptimizationOrder, + allowedSwapSlippageBps: isLimit ? BigInt(params.allowedSlippageBps ?? 100) : undefined, + }); + } + + if (!swapAmounts) { + return undefined; + } + + const createSwapOrderParams: Parameters[0] = { + tokensData, + fromToken: tokensData[params.fromTokenAddress], + toToken: tokensData[params.toTokenAddress], + swapAmounts, + isLimit, + allowedSlippage: params.allowedSlippageBps ?? 100, + referralCodeForTxn: params.referralCodeForTxn, triggerPrice: params.triggerPrice, - }) - : undefined; - - if (isWrapOrUnwrap) { - const tokenAmount = "fromAmount" in params ? params.fromAmount : params.toAmount; - const usdAmount = convertToUsd(tokenAmount, fromToken.decimals, fromTokenPrice)!; - const price = fromTokenPrice; - - swapAmounts = { - amountIn: tokenAmount, - usdIn: usdAmount!, - amountOut: tokenAmount, - usdOut: usdAmount!, - swapPathStats: undefined, - priceIn: price, - priceOut: price, - minOutputAmount: tokenAmount, }; - return swapAmounts; - } else if ("fromAmount" in params) { - swapAmounts = getSwapAmountsByFromValue({ - tokenIn: fromToken, - tokenOut: toToken, - amountIn: params.fromAmount, - triggerRatio, - isLimit, - findSwapPath: findSwapPath, - uiFeeFactor, - swapOptimizationOrder, - allowedSwapSlippageBps: isLimit ? BigInt(params.allowedSlippageBps ?? 100) : undefined, - }); - } else { - swapAmounts = getSwapAmountsByToValue({ - tokenIn: fromToken, - tokenOut: toToken, - amountOut: params.toAmount, - triggerRatio, - isLimit: isLimit, - findSwapPath: findSwapPath, - uiFeeFactor, - swapOptimizationOrder, - allowedSwapSlippageBps: isLimit ? BigInt(params.allowedSlippageBps ?? 100) : undefined, - }); - } - - if (!swapAmounts) { - return undefined; - } - - const createSwapOrderParams: Parameters[0] = { - tokensData, - fromToken: tokensData[params.fromTokenAddress], - toToken: tokensData[params.toTokenAddress], - swapAmounts, - isLimit, - allowedSlippage: params.allowedSlippageBps ?? 100, - referralCodeForTxn: params.referralCodeForTxn, - triggerPrice: params.triggerPrice, - }; - - return sdk.orders.createSwapOrder(createSwapOrderParams); + return sdk.orders.createSwapOrder(createSwapOrderParams); }