Enhance migration script to support environment-specific appsettings for Managing.Workers; improve connection string extraction logic with fallback to Managing.Api for SandboxRemote and ProductionRemote environments. Update createSwapOrderTxn to correct variable naming for clarity and add dynamic execution fee calculation in swapGmxTokensImpl.

This commit is contained in:
2025-12-26 22:42:15 +07:00
parent 96dd9086c5
commit 920980bb24
3 changed files with 84 additions and 10 deletions

View File

@@ -62,6 +62,7 @@ PROJECT_ROOT_DIR="$(dirname "$SCRIPT_DIR")" # One level up from scripts/
SRC_DIR="$PROJECT_ROOT_DIR/src" SRC_DIR="$PROJECT_ROOT_DIR/src"
DB_PROJECT_PATH="$SRC_DIR/Managing.Infrastructure.Database" DB_PROJECT_PATH="$SRC_DIR/Managing.Infrastructure.Database"
API_PROJECT_PATH="$SRC_DIR/Managing.Api" 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 DOCKER_DIR="$SRC_DIR/Managing.Docker" # Adjust if your docker-compose files are elsewhere
# Define absolute path for backup directory with environment subfolder # 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 # Helper function to extract connection details from appsettings
extract_connection_details() { extract_connection_details() {
local appsettings_file="$API_PROJECT_PATH/appsettings.$ENVIRONMENT.json" local appsettings_file=""
local default_appsettings="$API_PROJECT_PATH/appsettings.json" 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 # Try environment-specific file first, then default
if [ -f "$appsettings_file" ]; then 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 # Look for PostgreSql.ConnectionString first, then fallback to ConnectionString
CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$appsettings_file" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4) CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$appsettings_file" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4)
if [ -z "$CONNECTION_STRING" ]; then if [ -z "$CONNECTION_STRING" ]; then
CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$appsettings_file" | cut -d'"' -f4) CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$appsettings_file" | cut -d'"' -f4)
fi fi
elif [ -f "$default_appsettings" ]; then 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 # Look for PostgreSql.ConnectionString first, then fallback to ConnectionString
CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$default_appsettings" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4) CONNECTION_STRING=$(grep -A 3 '"PostgreSql"' "$default_appsettings" | grep -o '"ConnectionString": *"[^"]*"' | cut -d'"' -f4)
if [ -z "$CONNECTION_STRING" ]; then if [ -z "$CONNECTION_STRING" ]; then
CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$default_appsettings" | cut -d'"' -f4) CONNECTION_STRING=$(grep -o '"ConnectionString": *"[^"]*"' "$default_appsettings" | cut -d'"' -f4)
fi fi
else else
warn "⚠️ Could not find appsettings file for environment $ENVIRONMENT" # If Workers file not found for SandboxRemote/ProductionRemote, fallback to API
return 1 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 fi
if [ -z "$CONNECTION_STRING" ]; then if [ -z "$CONNECTION_STRING" ]; then

View File

@@ -30,13 +30,13 @@ export type SwapOrderParams = {
export async function createSwapOrderTxn(sdk: GmxSdk, p: SwapOrderParams) { export async function createSwapOrderTxn(sdk: GmxSdk, p: SwapOrderParams) {
const { encodedPayload, totalWntAmount } = await getParams(sdk, p); 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) { if (p.orderType !== OrderType.LimitSwap) {
await simulateExecuteOrder(sdk, { await simulateExecuteOrder(sdk, {
primaryPriceOverrides: {}, primaryPriceOverrides: {},
createMulticallPayload: simulationEncodedPayload, createMulticallPayload: simulationEncodedPayload,
value: sumaltionTotalWntAmount, value: simulationTotalWntAmount,
tokensData: p.tokensData, tokensData: p.tokensData,
}); });
} }

View File

@@ -32,6 +32,9 @@ import {hashDataMap, hashString} from '../../generated/gmxsdk/utils/hash.js';
import {ContractName, getContract} from '../../generated/gmxsdk/configs/contracts.js'; import {ContractName, getContract} from '../../generated/gmxsdk/configs/contracts.js';
import {abis} from '../../generated/gmxsdk/abis/index.js'; import {abis} from '../../generated/gmxsdk/abis/index.js';
import {approveContractImpl, getTokenAllowance} from './privy.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 { import {
Position, Position,
PositionStatus, PositionStatus,
@@ -2922,15 +2925,51 @@ export const swapGmxTokensImpl = async (
// Fall back to createSwapOrderTxn directly with simpler parameters // Fall back to createSwapOrderTxn directly with simpler parameters
console.log('🔄 Attempting direct createSwapOrderTxn...'); 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, { await createSwapOrderTxn(sdk, {
fromTokenAddress: fromTokenData.address, fromTokenAddress: fromTokenData.address,
fromTokenAmount: fromTokenAmount, fromTokenAmount: fromTokenAmount,
toTokenAddress: toTokenData.address, toTokenAddress: toTokenData.address,
swapPath: [fromTokenData.address, toTokenData.address], swapPath: swapPath,
orderType: OrderType.MarketSwap, orderType: OrderType.MarketSwap,
minOutputAmount: BigInt(Math.floor(amount * Math.pow(10, toTokenData.decimals) * (1 - allowedSlippage / 100))), minOutputAmount: BigInt(Math.floor(amount * Math.pow(10, toTokenData.decimals) * (1 - allowedSlippage / 100))),
referralCode: encodeReferralCode("kaigen_ai"), referralCode: encodeReferralCode("kaigen_ai"),
executionFee: 100000000000000000n, // 0.1 ETH as execution fee executionFee: executionFee.feeTokenAmount,
allowedSlippage: allowedSlippageBps, allowedSlippage: allowedSlippageBps,
tokensData: tokensData, tokensData: tokensData,
}); });