3 Commits

3 changed files with 75 additions and 7 deletions
@@ -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();
}
@@ -13,7 +13,8 @@ class AnchorIdlJupiterPerpsPositionDecoder {
JupiterPerpsPosition decode( JupiterPerpsPosition decode(
ΩJupiterPerpsPositionAccountΩ positionAccount, ΩJupiterPerpsPositionAccountΩ positionAccount,
SolanaAccountInfo accountInfo SolanaAccountInfo accountInfo,
ΩSPLMintAddressΩ tradedTokenMint
) { ) {
byte[] data = Base64.getDecoder().decode(accountInfo.dataBase64()); byte[] data = Base64.getDecoder().decode(accountInfo.dataBase64());
@@ -38,7 +39,8 @@ class AnchorIdlJupiterPerpsPositionDecoder {
JupiterPerpsPosition pos = new JupiterPerpsPosition( JupiterPerpsPosition pos = new JupiterPerpsPosition(
positionAccount, positionAccount,
entryPrice, entryPrice,
direction direction,
tradedTokenMint
); );
return pos; return pos;
@@ -34,7 +34,9 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
); );
} }
JupiterPerpsPosition pos = positionDecoder.decode(positionAccount, accountInfo); ΩSPLMintAddressΩ tradedTokenMint = getTradedTokenMint(accountInfo);
JupiterPerpsPosition pos = positionDecoder.decode(positionAccount, accountInfo, tradedTokenMint);
return pos; return pos;
} }
@@ -61,16 +63,31 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
throw new IllegalArgumentException(errorMsg); throw new IllegalArgumentException(errorMsg);
} }
JupiterPerpsPosition position = positionDecoder.decode( ΩSPLMintAddressΩ tradedTokenMint = getTradedTokenMint(accountInfo);
address,
accountInfo JupiterPerpsPosition position = positionDecoder.decode(address, accountInfo, tradedTokenMint);
);
positions.add(position); positions.add(position);
} }
return Set.copyOf(positions); 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 = private static final ΩJupiterPerpsProgramIdΩ JUPITER_PERPS_PROGRAM_ID =
"PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu"; "PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu";
private static final int POSITION_OWNER_OFFSET = 8; private static final int POSITION_OWNER_OFFSET = 8;