22: Investigate and expose borrowFeeUsd in JupiterPerpsPosition
This commit is contained in:
@@ -31,8 +31,8 @@ public record JupiterPerpsPosition(
|
||||
ΩJupiterPerpsPositionAccountΩ positionAccount,
|
||||
ΩSPLMintAddressΩ tradedTokenMint,
|
||||
JupiterPerpsPositionDirection direction,
|
||||
ΩUSDCAmountΩ value,
|
||||
ΩUSDCAmountΩ size,
|
||||
ΩUSDCAmountΩ positionValue,
|
||||
ΩUSDCAmountΩ positionSize,
|
||||
ΩUSDCAmountΩ pnl,
|
||||
BigDecimal pnlPercent,
|
||||
BigDecimal leverage,
|
||||
|
||||
+6
-6
@@ -17,7 +17,7 @@ class AnchorIdlJupiterPerpsCustodyDecoder {
|
||||
ΩJupiterPerpsPostionIdlΩ idl = decodeIdl(encodedCustodyAccountInfo);
|
||||
|
||||
JupiterCustodyAccountInfo cai = new JupiterCustodyAccountInfo(
|
||||
readPublicKey(idl, MINT_OFFSET),
|
||||
decodePublicKey(idl, MINT_OFFSET),
|
||||
decodeCumulativeInterestRate(idl)
|
||||
);
|
||||
|
||||
@@ -35,9 +35,9 @@ class AnchorIdlJupiterPerpsCustodyDecoder {
|
||||
return idl;
|
||||
}
|
||||
|
||||
private BigInteger decodeCumulativeInterestRate(byte[] data) {
|
||||
byte[] bytes = readU128(data, CUMULATIVE_INTEREST_RATE_OFFSET);
|
||||
BigInteger cumulativeInterestRate = new BigInteger(1, bytes);
|
||||
private @NotNull ΩJupiterCumulativeInterestRateΩ decodeCumulativeInterestRate(ΩJupiterPerpsCustodyAccountIdlΩ idl) {
|
||||
byte[] bytes = readU128(idl, CUMULATIVE_INTEREST_RATE_OFFSET);
|
||||
ΩJupiterCumulativeInterestRateΩ cumulativeInterestRate = new ΩJupiterCumulativeInterestRateΩ(1, bytes);
|
||||
|
||||
return cumulativeInterestRate;
|
||||
}
|
||||
@@ -55,8 +55,8 @@ class AnchorIdlJupiterPerpsCustodyDecoder {
|
||||
// +8 target_ratio_bps
|
||||
// +48 assets
|
||||
|
||||
private static final int ANCHOR_DISCRIMINATOR_LENGTH = 8;
|
||||
private static final int MINT_OFFSET = ANCHOR_DISCRIMINATOR_LENGTH + PUBLIC_KEY_LENGTH;
|
||||
private static final int DISCRIMINATOR_LENGTH = 8;
|
||||
private static final int MINT_OFFSET = DISCRIMINATOR_LENGTH + PUBLIC_KEY_LENGTH;
|
||||
private static final int FUNDING_RATE_STATE_OFFSET = 262;
|
||||
private static final int CUMULATIVE_INTEREST_RATE_OFFSET = FUNDING_RATE_STATE_OFFSET;
|
||||
|
||||
|
||||
+31
-12
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Base64;
|
||||
@@ -21,47 +22,63 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
|
||||
JupiterPerpsPositionDirection direction = decodeDirection(idl);
|
||||
|
||||
long rawEntryPrice = ByteBuffer
|
||||
ΩjupiterRawEntryPriceUsdΩ rawEntryPrice = ByteBuffer
|
||||
.wrap(idl, PRICE_OFFSET, U64_LENGTH)
|
||||
.order(ByteOrder.LITTLE_ENDIAN)
|
||||
.getLong();
|
||||
|
||||
ΩUSDCPriceΩ entryPrice = BigDecimal
|
||||
ΩUSDCPriceΩ entryPrice = ΩUSDCPriceΩ
|
||||
.valueOf(rawEntryPrice)
|
||||
.movePointLeft(6);
|
||||
|
||||
long rawCollateralUsd = ByteBuffer
|
||||
ΩjupiterRawCollateralUsdΩ rawCollateralUsd = ByteBuffer
|
||||
.wrap(idl, COLLATERAL_USD_OFFSET, U64_LENGTH)
|
||||
.order(ByteOrder.LITTLE_ENDIAN)
|
||||
.getLong();
|
||||
|
||||
ΩUSDCAmountΩ collateralUsd = BigDecimal
|
||||
ΩUSDCAmountΩ collateral = ΩUSDCAmountΩ
|
||||
.valueOf(rawCollateralUsd)
|
||||
.movePointLeft(6);
|
||||
|
||||
long rawSizeUsd = ByteBuffer
|
||||
ΩjupiterRawSizeUsdΩ rawSizeUsd = ByteBuffer
|
||||
.wrap(idl, SIZE_USD_OFFSET, U64_LENGTH)
|
||||
.order(ByteOrder.LITTLE_ENDIAN)
|
||||
.getLong();
|
||||
|
||||
ΩUSDCAmountΩ sizeUsd = BigDecimal
|
||||
ΩUSDCAmountΩ positionSize = ΩUSDCAmountΩ
|
||||
.valueOf(rawSizeUsd)
|
||||
.movePointLeft(6);
|
||||
|
||||
ΩJupiterCustodyAccountAddressΩ custodyAccountAddress = readPublicKey(idl, CUSTODY_OFFSET);
|
||||
ΩJupiterPerpsCustodyAccountAddressΩ custodyAccountAddress =
|
||||
decodePublicKey(idl, CUSTODY_OFFSET);
|
||||
|
||||
ΩJupiterPerpsCollateralCustodyAccountAddressΩ collateralCustodyAccountAddress =
|
||||
decodePublicKey(idl, COLLATERAL_CUSTODY_OFFSET);
|
||||
|
||||
ΩJupiterCumulativeInterestSnapshotΩ cumulativeInterestSnapshot = decodeCumulativeInterestSnapshot(idl);
|
||||
|
||||
JupiterPerpsPositionInfo posInfo = new JupiterPerpsPositionInfo(
|
||||
entryPrice,
|
||||
direction,
|
||||
sizeUsd,
|
||||
collateralUsd,
|
||||
custodyAccountAddress
|
||||
positionSize,
|
||||
collateral,
|
||||
custodyAccountAddress,
|
||||
collateralCustodyAccountAddress,
|
||||
cumulativeInterestSnapshot
|
||||
);
|
||||
|
||||
return posInfo;
|
||||
}
|
||||
|
||||
ΩJupiterCustodyAccountAddressΩ decodeCustodyAccountAddress(SolanaAccountInfo accountInfo) {
|
||||
private @NotNull ΩJupiterCumulativeInterestSnapshotΩ decodeCumulativeInterestSnapshot(ΩJupiterPerpsPostionIdlΩ idl) {
|
||||
byte[] bytes = readU128(idl, CUMULATIVE_INTEREST_SNAPSHOT_OFFSET);
|
||||
ΩJupiterCumulativeInterestSnapshotΩ cumulativeInterestSnapshot
|
||||
= new ΩJupiterCumulativeInterestSnapshotΩ(1, bytes);
|
||||
|
||||
return cumulativeInterestSnapshot;
|
||||
}
|
||||
|
||||
ΩJupiterPerpsCustodyAccountAddressΩ decodeCustodyAccountAddress(SolanaAccountInfo accountInfo) {
|
||||
byte[] data = base64.decode(accountInfo.data());
|
||||
|
||||
if (data.length < CUSTODY_OFFSET + PUBLIC_KEY_LENGTH) {
|
||||
@@ -69,7 +86,7 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
throw new IllegalArgumentException(errorMsg);
|
||||
}
|
||||
|
||||
ΩJupiterCustodyAccountAddressΩ addr = readPublicKey(data, CUSTODY_OFFSET);
|
||||
ΩJupiterPerpsCustodyAccountAddressΩ addr = decodePublicKey(data, CUSTODY_OFFSET);
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -117,6 +134,8 @@ class AnchorIdlJupiterPerpsPositionDecoder {
|
||||
private static final int PRICE_OFFSET = SIDE_OFFSET + SIDE_ENUM_LENGTH;
|
||||
private static final int SIZE_USD_OFFSET = PRICE_OFFSET + U64_LENGTH;
|
||||
private static final int COLLATERAL_USD_OFFSET = SIZE_USD_OFFSET + U64_LENGTH;
|
||||
private static final int REALISED_PNL_USD_OFFSET = COLLATERAL_USD_OFFSET + U64_LENGTH;
|
||||
private static final int CUMULATIVE_INTEREST_SNAPSHOT_OFFSET = REALISED_PNL_USD_OFFSET + I64_LENGTH;
|
||||
|
||||
private static final Base64.Decoder base64 = Base64.getDecoder();
|
||||
}
|
||||
+62
-8
@@ -12,6 +12,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -48,7 +50,7 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
if(perpsPositionInfo == null) {
|
||||
pos = null;
|
||||
} else {
|
||||
ΩJupiterCustodyAccountAddressΩ custodyAccountAddress = positionDecoder.decodeCustodyAccountAddress(accountInfo);
|
||||
ΩJupiterPerpsCustodyAccountAddressΩ custodyAccountAddress = positionDecoder.decodeCustodyAccountAddress(accountInfo);
|
||||
ΩJupiterCustodyAccountInfoEncodedΩ encodedCustodyAccountInfo = solanaBlockChain.getAccountInfo(custodyAccountAddress);
|
||||
|
||||
if (encodedCustodyAccountInfo == null) {
|
||||
@@ -59,13 +61,31 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
JupiterCustodyAccountInfo custodyAccountInfo = custodyDecoder.decode(encodedCustodyAccountInfo);
|
||||
ΩSPLMintAddressΩ mintAddress = custodyAccountInfo.mintAddress();
|
||||
|
||||
ΩJupiterPerpsCollateralCustodyAccountAddressΩ collateralCustodyAccountAddress =
|
||||
perpsPositionInfo.collateralCustodyAccountAddress();
|
||||
|
||||
ΩJupiterCustodyAccountInfoEncodedΩ encodedCollateralCustodyAccountInfo =
|
||||
solanaBlockChain.getAccountInfo(collateralCustodyAccountAddress);
|
||||
|
||||
JupiterCustodyAccountInfo collateralCustodyAccountInfo =
|
||||
custodyDecoder.decode(encodedCollateralCustodyAccountInfo);
|
||||
|
||||
ΩJupiterPostionInterestΩ positionInterest =
|
||||
collateralCustodyAccountInfo.currentCumulativeInterestRate()
|
||||
.subtract(perpsPositionInfo.cumulativeInterestSnapshot());
|
||||
|
||||
ΩUSDCAmountΩ borrowFeesDue =
|
||||
calculateBorrowFeesDue(
|
||||
positionInterest,
|
||||
perpsPositionInfo.positionSize()
|
||||
);
|
||||
|
||||
ΩUSDCAmountΩ value = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ pnl = ZERO; // TODO - Dummy
|
||||
BigDecimal pnlPercent = ZERO; // TODO - Dummy
|
||||
BigDecimal leverage = ZERO; // TODO - Dummy
|
||||
ΩUSDCPriceΩ marketPrice = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ totalFees = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ borrowFeesDue = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ closeFeePending = ZERO; // TODO - Dummy
|
||||
ΩSolanaAmountΩ accountRent = new MoneyAmount(ZERO, WellKnownCurrencyTypes.SOLANA.getCurrencyType()); // TODO - Dummy
|
||||
|
||||
@@ -74,7 +94,7 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
mintAddress,
|
||||
perpsPositionInfo.direction(),
|
||||
value,
|
||||
perpsPositionInfo.size(),
|
||||
perpsPositionInfo.positionSize(),
|
||||
pnl,
|
||||
pnlPercent,
|
||||
leverage,
|
||||
@@ -115,12 +135,13 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
}
|
||||
|
||||
JupiterPerpsPositionInfo perpsPositionInfo = positionDecoder.decode(accountInfo);
|
||||
if(perpsPositionInfo == null || perpsPositionInfo.size().compareTo(ZERO) == 0) {
|
||||
if(perpsPositionInfo == null || perpsPositionInfo.positionSize().compareTo(ZERO) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ΩJupiterCustodyAccountAddressΩ custodyAccountAddress = perpsPositionInfo.custodyAccountAddress();
|
||||
ΩJupiterCustodyAccountInfoEncodedΩ encodedCustodyAccountInfo = solanaBlockChain.getAccountInfo(custodyAccountAddress);
|
||||
ΩJupiterPerpsCustodyAccountAddressΩ custodyAccountAddress = perpsPositionInfo.custodyAccountAddress();
|
||||
ΩJupiterCustodyAccountInfoEncodedΩ encodedCustodyAccountInfo
|
||||
= solanaBlockChain.getAccountInfo(custodyAccountAddress);
|
||||
|
||||
if (encodedCustodyAccountInfo == null) {
|
||||
String errorMsg = "Jupiter Perps custody account does not exist: " + custodyAccountAddress;
|
||||
@@ -130,13 +151,31 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
JupiterCustodyAccountInfo custodyAccountInfo = custodyDecoder.decode(encodedCustodyAccountInfo);
|
||||
ΩSPLMintAddressΩ mintAddress = custodyAccountInfo.mintAddress();
|
||||
|
||||
ΩJupiterPerpsCollateralCustodyAccountAddressΩ collateralCustodyAccountAddress =
|
||||
perpsPositionInfo.collateralCustodyAccountAddress();
|
||||
|
||||
ΩJupiterCustodyAccountInfoEncodedΩ encodedCollateralCustodyAccountInfo =
|
||||
solanaBlockChain.getAccountInfo(collateralCustodyAccountAddress);
|
||||
|
||||
JupiterCustodyAccountInfo collateralCustodyAccountInfo =
|
||||
custodyDecoder.decode(encodedCollateralCustodyAccountInfo);
|
||||
|
||||
ΩJupiterPostionInterestΩ positionInterest =
|
||||
collateralCustodyAccountInfo.currentCumulativeInterestRate()
|
||||
.subtract(perpsPositionInfo.cumulativeInterestSnapshot());
|
||||
|
||||
ΩUSDCAmountΩ borrowFeesDue =
|
||||
calculateBorrowFeesDue(
|
||||
positionInterest,
|
||||
perpsPositionInfo.positionSize()
|
||||
);
|
||||
|
||||
ΩUSDCAmountΩ value = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ pnl = ZERO; // TODO - Dummy
|
||||
BigDecimal pnlPercent = ZERO; // TODO - Dummy
|
||||
BigDecimal leverage = ZERO; // TODO - Dummy
|
||||
ΩUSDCPriceΩ marketPrice = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ totalFees = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ borrowFeesDue = ZERO; // TODO - Dummy
|
||||
ΩUSDCAmountΩ closeFeePending = ZERO; // TODO - Dummy
|
||||
ΩSolanaAmountΩ accountRent = new MoneyAmount(ZERO, WellKnownCurrencyTypes.SOLANA.getCurrencyType()); // TODO - Dummy
|
||||
|
||||
@@ -145,7 +184,7 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
mintAddress,
|
||||
perpsPositionInfo.direction(),
|
||||
value,
|
||||
perpsPositionInfo.size(),
|
||||
perpsPositionInfo.positionSize(),
|
||||
pnl,
|
||||
pnlPercent,
|
||||
leverage,
|
||||
@@ -164,6 +203,21 @@ public class AnchorIdlJupiterPerpsServiceImpl implements JupiterPerpsService {
|
||||
return Set.copyOf(positions);
|
||||
}
|
||||
|
||||
private static ΩUSDCAmountΩ calculateBorrowFeesDue(
|
||||
ΩJupiterPostionInterestΩ positionInterest,
|
||||
ΩUSDCAmountΩ size
|
||||
) {
|
||||
ΩUSDCAmountΩ fees = new BigDecimal(positionInterest)
|
||||
.multiply(size)
|
||||
.divide(
|
||||
BigDecimal.valueOf(RATE_POWER),
|
||||
6,
|
||||
RoundingMode.CEILING
|
||||
);
|
||||
return fees;
|
||||
}
|
||||
|
||||
private static final long RATE_POWER = 1_000_000_000L;
|
||||
private static final ΩJupiterPerpsProgramIdΩ JUPITER_PERPS_PROGRAM_ID =
|
||||
"PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu";
|
||||
private static final int POSITION_OWNER_OFFSET = 8;
|
||||
|
||||
+4
-1
@@ -2,6 +2,9 @@ package com.r35157.libs.jupiter.perps.impl.anchoridl;
|
||||
|
||||
import com.r35157.libs.codec.Base58Codec;
|
||||
import com.r35157.libs.codec.impl.ref.Base58CodecImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class DecodingPrimitives {
|
||||
|
||||
@@ -15,7 +18,7 @@ public class DecodingPrimitives {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static ΩSolanaAddressΩ readPublicKey(byte[] data, int offset) {
|
||||
public static @NotNull ΩSolanaAddressΩ decodePublicKey(ΩJupiterPerpsPostionIdlΩ data, int offset) {
|
||||
byte[] bytes = new byte[PUBLIC_KEY_LENGTH];
|
||||
|
||||
System.arraycopy(
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@ import java.math.BigInteger;
|
||||
|
||||
public record JupiterCustodyAccountInfo(
|
||||
ΩSPLMintAddressΩ mintAddress,
|
||||
BigInteger currentCumulativeInterestRate
|
||||
ΩJupiterCumulativeInterestRateΩ currentCumulativeInterestRate
|
||||
) {
|
||||
}
|
||||
|
||||
+5
-2
@@ -3,12 +3,15 @@ package com.r35157.libs.jupiter.perps.impl.anchoridl;
|
||||
import com.r35157.libs.jupiter.perps.JupiterPerpsPositionDirection;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public record JupiterPerpsPositionInfo(
|
||||
ΩUSDCPriceΩ entryPrice,
|
||||
JupiterPerpsPositionDirection direction,
|
||||
ΩUSDCAmountΩ size,
|
||||
ΩUSDCAmountΩ positionSize,
|
||||
ΩUSDCAmountΩ collateral,
|
||||
ΩJupiterCustodyAccountAddressΩ custodyAccountAddress
|
||||
ΩJupiterPerpsCustodyAccountAddressΩ custodyAccountAddress,
|
||||
ΩJupiterPerpsCollateralCustodyAccountAddressΩ collateralCustodyAccountAddress,
|
||||
ΩJupiterCumulativeInterestSnapshotΩ cumulativeInterestSnapshot
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import java.lang.management.ManagementFactory;
|
||||
import com.r35157.nenjim.hubd.ctx.ContextManager;
|
||||
import com.r35157.nenjim.hubd.journal.JournalManager;
|
||||
import com.r35157.nenjim.hubd.impl.ref.JournalManagerImpl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
@@ -28,10 +30,16 @@ public class Main {
|
||||
SolanaBlockChain sbc = new SolanaBlockChainImpl();
|
||||
JupiterPerpsService jupiter = new AnchorIdlJupiterPerpsServiceImpl(sbc);
|
||||
ΩSolanaWalletIdΩ walletId = "vj98roDZ7744EBfxyuDFkKpEGCsKQLr7K8UFRumJNHf";
|
||||
Set<JupiterPerpsPosition> positions = jupiter.getOpenPositions(walletId);
|
||||
int a=0;
|
||||
//Set<JupiterPerpsPosition> positions = jupiter.getOpenPositions(walletId);
|
||||
|
||||
nenjimHub.awaitShutdown();
|
||||
while(true) {
|
||||
String addr = "2z2oExdggoRPCcojntHrGbRiDWeJgVSRbasfMbPfprQi";
|
||||
JupiterPerpsPosition pos = jupiter.getPosition(addr);
|
||||
ΩUSDCAmountΩ a = pos.borrowFeesDue();
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
// nenjimHub.awaitShutdown();
|
||||
|
||||
/* try {
|
||||
log.info("Auto-starting 2 Nenjim application(s)...");
|
||||
|
||||
Reference in New Issue
Block a user