Compare commits
4 Commits
13c7b6fce0
...
e7f14d76c0
| Author | SHA256 | Date | |
|---|---|---|---|
| e7f14d76c0 | |||
| c6acd812bb | |||
| 7250824238 | |||
| aa9d924112 |
@@ -0,0 +1,70 @@
|
||||
package com.r35157.libs.codec.impl.ref;
|
||||
|
||||
import com.r35157.libs.codec.Base58Codec;
|
||||
|
||||
public class Base58CodecImpl implements Base58Codec {
|
||||
|
||||
public String encode(byte[] input) {
|
||||
if (input.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
byte[] copy = input.clone();
|
||||
|
||||
int zeros = 0;
|
||||
while (zeros < copy.length && copy[zeros] == 0) {
|
||||
zeros++;
|
||||
}
|
||||
|
||||
char[] encoded = new char[copy.length * 2];
|
||||
int outputStart = encoded.length;
|
||||
|
||||
int inputStart = zeros;
|
||||
while (inputStart < copy.length) {
|
||||
int remainder = divmod58(
|
||||
copy,
|
||||
inputStart
|
||||
);
|
||||
|
||||
if (copy[inputStart] == 0) {
|
||||
inputStart++;
|
||||
}
|
||||
|
||||
encoded[--outputStart] = ALPHABET[remainder];
|
||||
}
|
||||
|
||||
while (outputStart < encoded.length && encoded[outputStart] == ENCODED_ZERO) {
|
||||
outputStart++;
|
||||
}
|
||||
|
||||
while (zeros-- > 0) {
|
||||
encoded[--outputStart] = ENCODED_ZERO;
|
||||
}
|
||||
|
||||
return new String(
|
||||
encoded,
|
||||
outputStart,
|
||||
encoded.length - outputStart
|
||||
);
|
||||
}
|
||||
|
||||
private static int divmod58(byte[] number, int startAt) {
|
||||
int remainder = 0;
|
||||
|
||||
for (int i = startAt; i < number.length; i++) {
|
||||
int digit = number[i] & 0xff;
|
||||
int temp = remainder * 256 + digit;
|
||||
|
||||
number[i] = (byte) (temp / 58);
|
||||
remainder = temp % 58;
|
||||
}
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
private static final char[] ALPHABET =
|
||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
|
||||
|
||||
private static final char ENCODED_ZERO =
|
||||
ALPHABET[0];
|
||||
}
|
||||
+49
@@ -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();
|
||||
}
|
||||
+4
-2
@@ -13,7 +13,8 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
|
||||
JupiterPerpsPosition decode(
|
||||
ΩJupiterPerpsPositionAccountΩ positionAccount,
|
||||
SolanaAccountInfo accountInfo
|
||||
SolanaAccountInfo accountInfo,
|
||||
ΩSPLMintAddressΩ tradedTokenMint
|
||||
) {
|
||||
byte[] data = Base64.getDecoder().decode(accountInfo.dataBase64());
|
||||
|
||||
@@ -38,7 +39,8 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
JupiterPerpsPosition pos = new JupiterPerpsPosition(
|
||||
positionAccount,
|
||||
entryPrice,
|
||||
direction
|
||||
direction,
|
||||
tradedTokenMint
|
||||
);
|
||||
|
||||
return pos;
|
||||
|
||||
+22
-5
@@ -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;
|
||||
}
|
||||
|
||||
@@ -61,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;
|
||||
|
||||
Reference in New Issue
Block a user