From e7f14d76c00165f9af018b5a4d96b9e1f3545890cd2a244f6867365e0ac82a40 Mon Sep 17 00:00:00 2001 From: Minimons Date: Fri, 26 Jun 2026 20:44:01 +0200 Subject: [PATCH] 17: Implement AnchorIdlJupiterPerpsCustodyDecoder --- .../AnchorIdlJupiterPerpsCustodyDecoder.tjava | 49 +++++++++++++++++++ .../AnchorIdlJupiterPerpsServiceImpl.tjava | 27 +++++++--- 2 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsCustodyDecoder.tjava diff --git a/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsCustodyDecoder.tjava b/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsCustodyDecoder.tjava new file mode 100644 index 0000000..fc2ceb9 --- /dev/null +++ b/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsCustodyDecoder.tjava @@ -0,0 +1,49 @@ +package com.r35157.libs.jupiter.perps.impl.anchoridl; + +import com.r35157.libs.solana.SolanaAccountInfo; +import org.apache.commons.codec.binary.Base58; + +import java.util.Base64; + +class AnchorIdlJupiterPerpsCustodyDecoder { + + ΩSPLMintAddressΩ decodeMint( + SolanaAccountInfo custodyAccountInfo + ) { + byte[] data = Base64.getDecoder().decode(custodyAccountInfo.dataBase64()); + + if (data.length < MINT_OFFSET + PUBLIC_KEY_LENGTH) { + throw new IllegalArgumentException( + "Jupiter Perps custody account data is too short: " + data.length + ); + } + + return readPublicKey(data, MINT_OFFSET); + } + + private ΩSPLMintAddressΩ readPublicKey( + byte[] data, + int offset + ) { + byte[] publicKeyBytes = new byte[PUBLIC_KEY_LENGTH]; + + System.arraycopy( + data, + offset, + publicKeyBytes, + 0, + PUBLIC_KEY_LENGTH + ); + + return base58.encode(publicKeyBytes); + } + + private static final int ANCHOR_DISCRIMINATOR_LENGTH = 8; + private static final int PUBLIC_KEY_LENGTH = 32; + + private static final int MINT_OFFSET = + ANCHOR_DISCRIMINATOR_LENGTH + + PUBLIC_KEY_LENGTH; // pool + + private static final Base58 base58 = Base58.getInstance(); +} \ No newline at end of file diff --git a/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsServiceImpl.tjava b/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsServiceImpl.tjava index c7b8640..78a718a 100644 --- a/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsServiceImpl.tjava +++ b/src/main/tjava/com/r35157/libs/jupiter/perps/impl/anchoridl/AnchorIdlJupiterPerpsServiceImpl.tjava @@ -34,9 +34,9 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService { ); } - ΩSPLMintAddressΩ tradedTokenMint = ""; - + ΩSPLMintAddressΩ tradedTokenMint = getTradedTokenMint(accountInfo); JupiterPerpsPosition pos = positionDecoder.decode(positionAccount, accountInfo, tradedTokenMint); + return pos; } @@ -63,16 +63,31 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService { throw new IllegalArgumentException(errorMsg); } - JupiterPerpsPosition position = positionDecoder.decode( - address, - accountInfo - ); + ΩSPLMintAddressΩ tradedTokenMint = getTradedTokenMint(accountInfo); + + JupiterPerpsPosition position = positionDecoder.decode(address, accountInfo, tradedTokenMint); positions.add(position); } return Set.copyOf(positions); } + private ΩSPLMintAddressΩ getTradedTokenMint(SolanaAccountInfo positionAccountInfo) + throws IOException, InterruptedException + { + ΩSolanaAddressΩ custodyAccount = positionDecoder.decodeCustodyAccount(positionAccountInfo); + SolanaAccountInfo custodyAccountInfo = solanaBlockChain.getAccountInfo(custodyAccount); + + if (custodyAccountInfo == null) { + throw new IllegalArgumentException( + "Jupiter Perps custody account does not exist: " + custodyAccount + ); + } + + ΩSPLMintAddressΩ mintAddress = custodyDecoder.decodeMint(custodyAccountInfo); + return mintAddress; + } + private static final ΩJupiterPerpsProgramIdΩ JUPITER_PERPS_PROGRAM_ID = "PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu"; private static final int POSITION_OWNER_OFFSET = 8;