Compare commits
1 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| d28a95a1f7 |
@@ -1,70 +0,0 @@
|
||||
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];
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package com.r35157.libs.jupiter.perps.impl.anchoridl;
|
||||
|
||||
import com.r35157.libs.codec.Base58Codec;
|
||||
import com.r35157.libs.codec.impl.ref.Base58CodecImpl;
|
||||
import com.r35157.libs.solana.SolanaAccountInfo;
|
||||
|
||||
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 Base58Codec base58 = new Base58CodecImpl();
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package com.r35157.libs.jupiter.perps.impl.anchoridl;
|
||||
|
||||
public record AnchorIdlJupiterPerpsDecodedPositionAccount() {
|
||||
}
|
||||
+14
-48
@@ -1,7 +1,5 @@
|
||||
package com.r35157.libs.jupiter.perps.impl.anchoridl;
|
||||
|
||||
import com.r35157.libs.codec.Base58Codec;
|
||||
import com.r35157.libs.codec.impl.ref.Base58CodecImpl;
|
||||
import com.r35157.libs.jupiter.perps.JupiterPerpsPosition;
|
||||
import com.r35157.libs.jupiter.perps.JupiterPerpsPositionDirection;
|
||||
import com.r35157.libs.solana.SolanaAccountInfo;
|
||||
@@ -15,8 +13,7 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
|
||||
JupiterPerpsPosition decode(
|
||||
ΩJupiterPerpsPositionAccountΩ positionAccount,
|
||||
SolanaAccountInfo accountInfo,
|
||||
ΩSPLMintAddressΩ tradedTokenMint
|
||||
SolanaAccountInfo accountInfo
|
||||
) {
|
||||
byte[] data = Base64.getDecoder().decode(accountInfo.dataBase64());
|
||||
|
||||
@@ -41,28 +38,12 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
JupiterPerpsPosition pos = new JupiterPerpsPosition(
|
||||
positionAccount,
|
||||
entryPrice,
|
||||
direction,
|
||||
tradedTokenMint
|
||||
direction
|
||||
);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
ΩSolanaAddressΩ decodeCustodyAccount(SolanaAccountInfo accountInfo) {
|
||||
byte[] data = Base64.getDecoder().decode(accountInfo.dataBase64());
|
||||
|
||||
if (data.length < CUSTODY_OFFSET + PUBLIC_KEY_LENGTH) {
|
||||
throw new IllegalArgumentException(
|
||||
"Jupiter Perps position account data is too short: " + data.length
|
||||
);
|
||||
}
|
||||
|
||||
return readPublicKey(
|
||||
data,
|
||||
CUSTODY_OFFSET
|
||||
);
|
||||
}
|
||||
|
||||
private JupiterPerpsPositionDirection decodeDirection(
|
||||
byte rawSide
|
||||
) {
|
||||
@@ -78,37 +59,22 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
return direction;
|
||||
}
|
||||
|
||||
private ΩSolanaAddressΩ 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 I64_LENGTH = 8;
|
||||
private static final int SIDE_ENUM_LENGTH = 1;
|
||||
private static final int U64_LENGTH = 8;
|
||||
private static final int SIDE_ENUM_LENGTH = 1;
|
||||
|
||||
private static final int OWNER_OFFSET = ANCHOR_DISCRIMINATOR_LENGTH;
|
||||
private static final int POOL_OFFSET = OWNER_OFFSET + PUBLIC_KEY_LENGTH;
|
||||
private static final int CUSTODY_OFFSET = POOL_OFFSET + PUBLIC_KEY_LENGTH;
|
||||
private static final int COLLATERAL_CUSTODY_OFFSET = CUSTODY_OFFSET + PUBLIC_KEY_LENGTH; // custody
|
||||
private static final int OPEN_TIME_OFFSET = COLLATERAL_CUSTODY_OFFSET + PUBLIC_KEY_LENGTH;
|
||||
private static final int UPDATE_TIME_OFFSET = OPEN_TIME_OFFSET + I64_LENGTH; // openTime
|
||||
private static final int SIDE_OFFSET = UPDATE_TIME_OFFSET + I64_LENGTH;
|
||||
private static final int PRICE_OFFSET = SIDE_OFFSET + SIDE_ENUM_LENGTH;
|
||||
private static final int SIDE_OFFSET =
|
||||
ANCHOR_DISCRIMINATOR_LENGTH
|
||||
+ PUBLIC_KEY_LENGTH // owner
|
||||
+ PUBLIC_KEY_LENGTH // pool
|
||||
+ PUBLIC_KEY_LENGTH // custody
|
||||
+ PUBLIC_KEY_LENGTH // collateralCustody
|
||||
+ I64_LENGTH // openTime
|
||||
+ I64_LENGTH; // updateTime
|
||||
|
||||
private static final Base58Codec base58 = new Base58CodecImpl();
|
||||
private static final int PRICE_OFFSET =
|
||||
SIDE_OFFSET
|
||||
+ SIDE_ENUM_LENGTH; // side
|
||||
}
|
||||
+5
-24
@@ -17,7 +17,6 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
) {
|
||||
this.solanaBlockChain = solanaBlockChain;
|
||||
this.positionDecoder = new AnchorIdlJupiterPerpsPositionDecoder();
|
||||
this.custodyDecoder = new AnchorIdlJupiterPerpsCustodyDecoder();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,9 +34,7 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
);
|
||||
}
|
||||
|
||||
ΩSPLMintAddressΩ tradedTokenMint = getTradedTokenMint(accountInfo);
|
||||
JupiterPerpsPosition pos = positionDecoder.decode(positionAccount, accountInfo, tradedTokenMint);
|
||||
|
||||
JupiterPerpsPosition pos = positionDecoder.decode(positionAccount, accountInfo);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -64,36 +61,20 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
throw new IllegalArgumentException(errorMsg);
|
||||
}
|
||||
|
||||
ΩSPLMintAddressΩ tradedTokenMint = getTradedTokenMint(accountInfo);
|
||||
|
||||
JupiterPerpsPosition position = positionDecoder.decode(address, accountInfo, tradedTokenMint);
|
||||
JupiterPerpsPosition position = positionDecoder.decode(
|
||||
address,
|
||||
accountInfo
|
||||
);
|
||||
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;
|
||||
|
||||
private final SolanaBlockChain solanaBlockChain;
|
||||
private final AnchorIdlJupiterPerpsPositionDecoder positionDecoder;
|
||||
private final AnchorIdlJupiterPerpsCustodyDecoder custodyDecoder;
|
||||
}
|
||||
@@ -24,10 +24,9 @@ public class Main {
|
||||
// TODO: Consider if we really need a Main class or we just need to move the main method to NenjimHubImpl?
|
||||
static void main(String[] args) throws Exception {
|
||||
NenjimHubImpl nenjimHub = new NenjimHubImpl();
|
||||
|
||||
/*
|
||||
SolanaBlockChain sbc = new SolanaBlockChainImpl();
|
||||
JupiterPerpsService jupiter = new AnchorIdlJupiterPerpsServiceImpl(sbc);
|
||||
JupiterPerpsPositionService jupiter = new AnchorIdlJupiterPerpsPositionServiceImpl(sbc);
|
||||
ΩSolanaWalletIdΩ walletId = "vj98roDZ7744EBfxyuDFkKpEGCsKQLr7K8UFRumJNHf";
|
||||
Set<JupiterPerpsPosition> positions = jupiter.getOpenPositions(walletId);
|
||||
int a=0;
|
||||
|
||||
Reference in New Issue
Block a user