Fix timeout error for getposition

This commit is contained in:
2025-08-17 00:52:53 +07:00
parent e38ad95a8b
commit 09a217ca63

View File

@@ -51,6 +51,11 @@ interface CacheEntry {
const CACHE_TTL = 30 * 60 * 1000; // 30 minutes in milliseconds const CACHE_TTL = 30 * 60 * 1000; // 30 minutes in milliseconds
const marketsCache = new Map<string, CacheEntry>(); const marketsCache = new Map<string, CacheEntry>();
// Fallback RPC configuration
const FALLBACK_RPC_URL = "https://radial-shy-cherry.arbitrum-mainnet.quiknode.pro/098e57e961b05b24bcde008c4ca02fff6fb13b51/";
const PRIMARY_RPC_URL = "https://arb1.arbitrum.io/rpc";
const MAX_RETRY_ATTEMPTS = 2; // Only allow one retry to prevent infinite loops
/** /**
* Gets markets info data from cache or fetches it from GMX SDK * Gets markets info data from cache or fetches it from GMX SDK
* @param sdk The GMX SDK client * @param sdk The GMX SDK client
@@ -134,7 +139,6 @@ const cancelOrdersSchema = z.object({
ticker: z.string().nonempty() ticker: z.string().nonempty()
}); });
// Schema for claim funding fees request // Schema for claim funding fees request
const claimFundingFeesSchema = z.object({ const claimFundingFeesSchema = z.object({
account: z.string().nonempty() account: z.string().nonempty()
@@ -174,27 +178,25 @@ const swapTokensSchema = z.object({
path: ["toTicker"] path: ["toTicker"]
}); });
/** /**
* Gets a GMX SDK client initialized for the given address * Creates a GMX SDK client with the specified RPC URL
* If a walletId is provided, it will be used with Privy for signing
* @param account The wallet address to use * @param account The wallet address to use
* @param rpcUrl The RPC URL to use for the client
* @returns An initialized GMX SDK client * @returns An initialized GMX SDK client
*/ */
export async function getClientForAddress( export async function createGmxClientWithRpc(
account: string, account: string,
rpcUrl: string = PRIMARY_RPC_URL
): Promise<GmxSdk> { ): Promise<GmxSdk> {
try { try {
console.log(`Creating GMX client with RPC: ${rpcUrl}`);
console.log("GMX UI Fee Receiver:", process.env.GMX_UI_FEE_RECEIVER);
// Create SDK instance // Create SDK instance
const arbitrumSdkConfig: GmxSdkConfig = { const arbitrumSdkConfig: GmxSdkConfig = {
chainId: arbitrum.id, chainId: arbitrum.id,
account: account, account: account,
oracleUrl: "https://arbitrum-api.gmxinfra.io", oracleUrl: "https://arbitrum-api.gmxinfra.io",
rpcUrl: "https://arb1.arbitrum.io/rpc", rpcUrl: rpcUrl,
subsquidUrl: "https://gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql", subsquidUrl: "https://gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql",
subgraphUrl: "https://subgraph.satsuma-prod.com/3b2ced13c8d9/gmx/synthetics-arbitrum-stats/api", subgraphUrl: "https://subgraph.satsuma-prod.com/3b2ced13c8d9/gmx/synthetics-arbitrum-stats/api",
settings: { settings: {
@@ -254,11 +256,23 @@ export async function getClientForAddress(
return sdk; return sdk;
} catch (error) { } catch (error) {
console.error(`Error getting GMX client: ${error instanceof Error ? error.message : 'Unknown error'}`); console.error(`Error creating GMX client with RPC ${rpcUrl}: ${error instanceof Error ? error.message : 'Unknown error'}`);
throw error; throw error;
} }
} }
/**
* Gets a GMX SDK client initialized for the given address
* If a walletId is provided, it will be used with Privy for signing
* @param account The wallet address to use
* @returns An initialized GMX SDK client
*/
export async function getClientForAddress(
account: string,
): Promise<GmxSdk> {
return createGmxClientWithRpc(account, PRIMARY_RPC_URL);
}
/** /**
* Implementation function to open a position on GMX * Implementation function to open a position on GMX
@@ -809,13 +823,16 @@ export async function getGmxTrade(
} }
/** /**
* Implementation function to get positions on GMX * Implementation function to get positions on GMX with fallback RPC support
* @param sdk The GMX SDK client * @param sdk The GMX SDK client
* @param retryCount Current retry attempt count
* @returns Array of positions * @returns Array of positions
*/ */
export const getGmxPositionsImpl = async ( export const getGmxPositionsImpl = async (
sdk: GmxSdk sdk: GmxSdk,
retryCount: number = 0
): Promise<Position[]> => { ): Promise<Position[]> => {
try {
const {marketsInfoData, tokensData} = await sdk.markets.getMarketsInfo(); const {marketsInfoData, tokensData} = await sdk.markets.getMarketsInfo();
const positionsInfo = await sdk.positions.getPositionsInfo({ const positionsInfo = await sdk.positions.getPositionsInfo({
@@ -936,8 +953,42 @@ export const getGmxPositionsImpl = async (
return position; return position;
}); });
return Promise.all(positions); return Promise.all(positions);
} catch (error) {
// Check if this is a multicall timeout error and we haven't exceeded retry limit
const errorMessage = error instanceof Error ? error.message : String(error);
const isMulticallTimeout = errorMessage.toLowerCase().includes('multicall timeout') ||
errorMessage.toLowerCase().includes('timeout') ||
errorMessage.toLowerCase().includes('rpc error');
if (isMulticallTimeout && retryCount < MAX_RETRY_ATTEMPTS) {
console.log(`🔄 Multicall timeout detected (attempt ${retryCount + 1}/${MAX_RETRY_ATTEMPTS + 1}), retrying with fallback RPC...`);
try {
// Create a new SDK client with the fallback RPC
const fallbackSdk = await createGmxClientWithRpc(sdk.account, FALLBACK_RPC_URL);
console.log('✅ Fallback RPC client created, retrying positions request...');
// Recursively call the same function with the fallback SDK and incremented retry count
const result = await getGmxPositionsImpl(fallbackSdk, retryCount + 1);
console.log('✅ Fallback RPC request successful');
return result;
} catch (fallbackError) {
console.error('❌ Fallback RPC also failed:', fallbackError);
// If fallback also fails, throw the original error
throw error;
}
}
// If it's not a multicall timeout or we've exceeded retry limit, re-throw the error
if (isMulticallTimeout && retryCount >= MAX_RETRY_ATTEMPTS) {
console.error(`❌ Maximum retry attempts (${MAX_RETRY_ATTEMPTS}) exceeded. Both primary and fallback RPCs failed.`);
}
throw error;
}
}; };
/** /**
@@ -954,7 +1005,7 @@ export async function getGmxPositions(
) { ) {
try { try {
const sdk = await this.getClientForAddress(account); const sdk = await this.getClientForAddress(account);
const positions = await getGmxPositionsImpl(sdk); const positions = await getGmxPositionsImpl(sdk, 0);
return { return {
success: true, success: true,
positions, positions,