diff --git a/scripts/apply-migrations.sh b/scripts/apply-migrations.sh index 2176dae3..9e2eda3b 100755 --- a/scripts/apply-migrations.sh +++ b/scripts/apply-migrations.sh @@ -62,6 +62,7 @@ PROJECT_ROOT_DIR="$(dirname "$SCRIPT_DIR")" # One level up from scripts/ SRC_DIR="$PROJECT_ROOT_DIR/src" DB_PROJECT_PATH="$SRC_DIR/Managing.Infrastructure.Database" API_PROJECT_PATH="$SRC_DIR/Managing.Api" +WORKERS_PROJECT_PATH="$SRC_DIR/Managing.Workers" DOCKER_DIR="$SRC_DIR/Managing.Docker" # Adjust if your docker-compose files are elsewhere # Define absolute path for backup directory with environment subfolder @@ -108,27 +109,61 @@ start_postgres_if_needed() { # Helper function to extract connection details from appsettings extract_connection_details() { - local appsettings_file="$API_PROJECT_PATH/appsettings.$ENVIRONMENT.json" - local default_appsettings="$API_PROJECT_PATH/appsettings.json" + local appsettings_file="" + local default_appsettings="" + + # For SandboxRemote and ProductionRemote, check Managing.Workers first + if [ "$ENVIRONMENT" = "SandboxRemote" ] || [ "$ENVIRONMENT" = "ProductionRemote" ]; then + appsettings_file="$WORKERS_PROJECT_PATH/appsettings.$ENVIRONMENT.json" + default_appsettings="$WORKERS_PROJECT_PATH/appsettings.json" + log "📋 Checking Managing.Workers for environment: $ENVIRONMENT" + else + appsettings_file="$API_PROJECT_PATH/appsettings.$ENVIRONMENT.json" + default_appsettings="$API_PROJECT_PATH/appsettings.json" + fi # Try environment-specific file first, then default if [ -f "$appsettings_file" ]; then - log "📋 Reading connection string from: appsettings.$ENVIRONMENT.json" + log "📋 Reading connection string from: $(basename "$appsettings_file")" # Look for PostgreSql.ConnectionString first, then fallback to ConnectionString CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$appsettings_file" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4) if [ -z "$CONNECTION_STRING" ]; then CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$appsettings_file" | cut -d'"' -f4) fi elif [ -f "$default_appsettings" ]; then - log "📋 Reading connection string from: appsettings.json (default)" + log "📋 Reading connection string from: $(basename "$default_appsettings") (default)" # Look for PostgreSql.ConnectionString first, then fallback to ConnectionString CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$default_appsettings" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4) if [ -z "$CONNECTION_STRING" ]; then CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$default_appsettings" | cut -d'"' -f4) fi else - warn "⚠️ Could not find appsettings file for environment $ENVIRONMENT" - return 1 + # If Workers file not found for SandboxRemote/ProductionRemote, fallback to API + if [ "$ENVIRONMENT" = "SandboxRemote" ] || [ "$ENVIRONMENT" = "ProductionRemote" ]; then + warn "⚠️ Could not find appsettings file in Managing.Workers, trying Managing.Api..." + appsettings_file="$API_PROJECT_PATH/appsettings.$ENVIRONMENT.json" + default_appsettings="$API_PROJECT_PATH/appsettings.json" + + if [ -f "$appsettings_file" ]; then + log "📋 Reading connection string from: $(basename "$appsettings_file") (fallback to API)" + CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$appsettings_file" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4) + if [ -z "$CONNECTION_STRING" ]; then + CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$appsettings_file" | cut -d'"' -f4) + fi + elif [ -f "$default_appsettings" ]; then + log "📋 Reading connection string from: $(basename "$default_appsettings") (default, fallback to API)" + CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$default_appsettings" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4) + if [ -z "$CONNECTION_STRING" ]; then + CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$default_appsettings" | cut -d'"' -f4) + fi + else + warn "⚠️ Could not find appsettings file for environment $ENVIRONMENT" + return 1 + fi + else + warn "⚠️ Could not find appsettings file for environment $ENVIRONMENT" + return 1 + fi fi if [ -z "$CONNECTION_STRING" ]; then diff --git a/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/transactions/createSwapOrderTxn.ts b/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/transactions/createSwapOrderTxn.ts index b9bc86f9..accdebe1 100644 --- a/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/transactions/createSwapOrderTxn.ts +++ b/src/Managing.Web3Proxy/src/generated/gmxsdk/modules/orders/transactions/createSwapOrderTxn.ts @@ -30,13 +30,13 @@ export type SwapOrderParams = { export async function createSwapOrderTxn(sdk: GmxSdk, p: SwapOrderParams) { const { encodedPayload, totalWntAmount } = await getParams(sdk, p); - const { encodedPayload: simulationEncodedPayload, totalWntAmount: sumaltionTotalWntAmount } = await getParams(sdk, p); + const { encodedPayload: simulationEncodedPayload, totalWntAmount: simulationTotalWntAmount } = await getParams(sdk, p); if (p.orderType !== OrderType.LimitSwap) { await simulateExecuteOrder(sdk, { primaryPriceOverrides: {}, createMulticallPayload: simulationEncodedPayload, - value: sumaltionTotalWntAmount, + value: simulationTotalWntAmount, tokensData: p.tokensData, }); } diff --git a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts index 737adffd..e9681cc0 100644 --- a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts +++ b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts @@ -32,6 +32,9 @@ import {hashDataMap, hashString} from '../../generated/gmxsdk/utils/hash.js'; import {ContractName, getContract} from '../../generated/gmxsdk/configs/contracts.js'; import {abis} from '../../generated/gmxsdk/abis/index.js'; import {approveContractImpl, getTokenAllowance} from './privy.js'; +import {estimateExecuteSwapOrderGasLimit} from '../../generated/gmxsdk/utils/fees/executionFee.js'; +import {getExecutionFee} from '../../generated/gmxsdk/utils/fees/executionFee.js'; +import {estimateOrderOraclePriceCount} from '../../generated/gmxsdk/utils/fees/estimateOraclePriceCount.js'; import { Position, PositionStatus, @@ -2922,15 +2925,51 @@ export const swapGmxTokensImpl = async ( // Fall back to createSwapOrderTxn directly with simpler parameters console.log('🔄 Attempting direct createSwapOrderTxn...'); + + // Calculate execution fee dynamically + const swapPath = [fromTokenData.address, toTokenData.address]; + // For a direct swap (token A -> token B), there's 1 swap through 1 market + // The swapPath length represents the number of markets/swaps in the path + // For a simple direct swap, we estimate 1 swap + const swapsCount = 1; + const gasLimits = await sdk.utils.getGasLimits(); + const gasPrice = await sdk.utils.getGasPrice(); + + if (!gasLimits || gasPrice === undefined) { + throw new Error("Failed to get gas limits or gas price for execution fee calculation"); + } + + const estimatedGasLimit = estimateExecuteSwapOrderGasLimit(gasLimits, { + swapsCount: swapsCount, + callbackGasLimit: 0n, + }); + + const oraclePriceCount = estimateOrderOraclePriceCount(swapsCount); + + const executionFee = getExecutionFee( + sdk.chainId, + gasLimits, + tokensData, + estimatedGasLimit, + gasPrice, + oraclePriceCount + ); + + if (!executionFee) { + throw new Error("Failed to calculate execution fee"); + } + + console.log(`💰 Calculated execution fee: ${(Number(executionFee.feeTokenAmount) / 1e18).toFixed(6)} ETH`); + await createSwapOrderTxn(sdk, { fromTokenAddress: fromTokenData.address, fromTokenAmount: fromTokenAmount, toTokenAddress: toTokenData.address, - swapPath: [fromTokenData.address, toTokenData.address], + swapPath: swapPath, orderType: OrderType.MarketSwap, minOutputAmount: BigInt(Math.floor(amount * Math.pow(10, toTokenData.decimals) * (1 - allowedSlippage / 100))), referralCode: encodeReferralCode("kaigen_ai"), - executionFee: 100000000000000000n, // 0.1 ETH as execution fee + executionFee: executionFee.feeTokenAmount, allowedSlippage: allowedSlippageBps, tokensData: tokensData, });