From 1cb78fa3dbabd4ac8191c415d94a65bbc5accb723bd46fb44b7750af2bafe229 Mon Sep 17 00:00:00 2001 From: Minimons Date: Fri, 26 Jun 2026 16:15:19 +0200 Subject: [PATCH] 15: Add getOpenPositions() to Jupiter Perps API --- .../perps/JupiterPerpsPositionService.tjava | 15 ++++++++ ...orIdlJupiterPerpsPositionServiceImpl.tjava | 37 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/main/tjava/com/r35157/libs/jupiter/perps/JupiterPerpsPositionService.tjava b/src/main/tjava/com/r35157/libs/jupiter/perps/JupiterPerpsPositionService.tjava index 2f47ad3..533cad7 100644 --- a/src/main/tjava/com/r35157/libs/jupiter/perps/JupiterPerpsPositionService.tjava +++ b/src/main/tjava/com/r35157/libs/jupiter/perps/JupiterPerpsPositionService.tjava @@ -1,6 +1,7 @@ package com.r35157.libs.jupiter.perps; import java.io.IOException; +import java.util.Set; /** * Service for reading Jupiter Perps positions. @@ -27,4 +28,18 @@ public interface JupiterPerpsPositionService { */ JupiterPerpsPosition getPosition(ΩJupiterPerpsPositionAccountΩ positionAccount) throws IOException, InterruptedException; + + /** + * Finds open Jupiter Perps positions owned by a wallet. + * + *

This method returns decoded Jupiter Perps position objects. It does not return + * raw Solana accounts or account ids.

+ * + * @param owner the wallet address that owns the Jupiter Perps positions + * @return the open Jupiter Perps positions owned by the wallet + * @throws IOException if the position accounts could not be fetched or decoded + * @throws InterruptedException if the calling thread is interrupted while fetching positions + */ + Set getOpenPositions(ΩSolanaWalletIdΩ owner) + throws IOException, InterruptedException; } \ No newline at end of file diff --git a/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsPositionServiceImpl.tjava b/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsPositionServiceImpl.tjava index 79d4cbf..259d9e7 100644 --- a/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsPositionServiceImpl.tjava +++ b/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsPositionServiceImpl.tjava @@ -4,8 +4,11 @@ import com.r35157.libs.jupiter.perps.JupiterPerpsPosition; import com.r35157.libs.jupiter.perps.JupiterPerpsPositionService; import com.r35157.libs.solana.SolanaAccountInfo; import com.r35157.libs.solana.SolanaBlockChain; +import com.r35157.libs.solana.SolanaProgramAccountMemcmpFilter; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; public class AnchorIdlJupiterPerpsPositionServiceImpl implements JupiterPerpsPositionService { @@ -35,8 +38,42 @@ public class AnchorIdlJupiterPerpsPositionServiceImpl implements JupiterPerpsPos return pos; } + @Override + public Set getOpenPositions(ΩSolanaWalletIdΩ owner) + throws IOException, InterruptedException { + Set accountInfos = solanaBlockChain.getProgramAccounts( + JUPITER_PERPS_PROGRAM_ID, + Set.of(new SolanaProgramAccountMemcmpFilter( + POSITION_OWNER_OFFSET, + owner + )) + ); + + Set positions = new HashSet<>(); + + for (SolanaAccountInfo accountInfo : accountInfos) { + ΩSolanaAddressΩ address = accountInfo.address(); + ΩSolanaProgramIdΩ programId = accountInfo.owner(); + + if (!JUPITER_PERPS_PROGRAM_ID.equals(programId)) { + String errorMsg = "Account '" + address + "' is not owned by Jupiter Perps program '" + + programId + "'"; + throw new IllegalArgumentException(errorMsg); + } + + JupiterPerpsPosition position = positionDecoder.decode( + address, + accountInfo + ); + positions.add(position); + } + + return Set.copyOf(positions); + } + private static final ΩJupiterPerpsProgramIdΩ JUPITER_PERPS_PROGRAM_ID = "PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu"; + private static final int POSITION_OWNER_OFFSET = 8; private final SolanaBlockChain solanaBlockChain; private final AnchorIdlJupiterPerpsPositionDecoder positionDecoder;