import { PublicKey } from '@solana/web3.js'; import { StateAccount, PerpMarketAccount, SpotMarketAccount, OracleGuardRails, FeeStructure, OrderFillerRewardStructure, HistoricalOracleData, AMM, HistoricalIndexData, PoolBalance, } from '../types'; import { OraclePriceData } from '../oracles/types'; import { BN } from '../'; export function formatStateAccount(stateAccount: StateAccount) { stateAccount.admin = toPublicKey(stateAccount.admin); stateAccount.whitelistMint = toPublicKey(stateAccount.whitelistMint); stateAccount.discountMint = toPublicKey(stateAccount.discountMint); formatOracleGuardRails(stateAccount.oracleGuardRails); stateAccount.numberOfAuthorities = toBN(stateAccount.numberOfAuthorities); stateAccount.numberOfSubAccounts = toBN(stateAccount.numberOfSubAccounts); stateAccount.signer = toPublicKey(stateAccount.signer); stateAccount.srmVault = toPublicKey(stateAccount.srmVault); formatFeeStructure(stateAccount.perpFeeStructure); formatFeeStructure(stateAccount.spotFeeStructure); stateAccount.lpCooldownTime = toBN(stateAccount.lpCooldownTime); } export function formatPerpMarketAccount(perpAccount: PerpMarketAccount) { perpAccount.expiryTs = toBN(perpAccount.expiryTs); perpAccount.expiryPrice = toBN(perpAccount.expiryPrice); perpAccount.pubkey = toPublicKey(perpAccount.pubkey); formatAMM(perpAccount.amm); perpAccount.nextFillRecordId = toBN(perpAccount.nextFillRecordId); perpAccount.nextFundingRateRecordId = toBN(perpAccount.nextFundingRateRecordId); perpAccount.nextCurveRecordId = toBN(perpAccount.nextCurveRecordId); formatPoolBalance(perpAccount.pnlPool); perpAccount.unrealizedPnlMaxImbalance = toBN(perpAccount.unrealizedPnlMaxImbalance); if (perpAccount.insuranceClaim) { perpAccount.insuranceClaim.revenueWithdrawSinceLastSettle = toBN(perpAccount.insuranceClaim.revenueWithdrawSinceLastSettle); perpAccount.insuranceClaim.maxRevenueWithdrawPerPeriod = toBN(perpAccount.insuranceClaim.maxRevenueWithdrawPerPeriod); perpAccount.insuranceClaim.lastRevenueWithdrawTs = toBN(perpAccount.insuranceClaim.lastRevenueWithdrawTs); perpAccount.insuranceClaim.quoteSettledInsurance = toBN(perpAccount.insuranceClaim.quoteSettledInsurance); perpAccount.insuranceClaim.quoteMaxInsurance = toBN(perpAccount.insuranceClaim.quoteMaxInsurance); } } export function formatSpotMarketAccount(spotAccount: SpotMarketAccount) { spotAccount.pubkey = toPublicKey(spotAccount.pubkey); spotAccount.mint = toPublicKey(spotAccount.mint); spotAccount.vault = toPublicKey(spotAccount.vault); spotAccount.oracle = toPublicKey(spotAccount.oracle); formatHistoricalOracleData(spotAccount.historicalOracleData); formatHistoricalIndexData(spotAccount.historicalIndexData); if (spotAccount.insuranceFund) { spotAccount.insuranceFund.vault = toPublicKey(spotAccount.insuranceFund.vault); spotAccount.insuranceFund.totalShares = toBN(spotAccount.insuranceFund.totalShares); spotAccount.insuranceFund.userShares = toBN(spotAccount.insuranceFund.userShares); spotAccount.insuranceFund.sharesBase = toBN(spotAccount.insuranceFund.sharesBase); spotAccount.insuranceFund.unstakingPeriod = toBN(spotAccount.insuranceFund.unstakingPeriod); spotAccount.insuranceFund.lastRevenueSettleTs = toBN(spotAccount.insuranceFund.lastRevenueSettleTs); spotAccount.insuranceFund.revenueSettlePeriod = toBN(spotAccount.insuranceFund.revenueSettlePeriod); } formatPoolBalance(spotAccount.revenuePool); spotAccount.cumulativeDepositInterest = toBN(spotAccount.cumulativeDepositInterest); spotAccount.cumulativeBorrowInterest = toBN(spotAccount.cumulativeBorrowInterest); spotAccount.totalSocialLoss = toBN(spotAccount.totalSocialLoss); spotAccount.totalQuoteSocialLoss = toBN(spotAccount.totalQuoteSocialLoss); spotAccount.depositBalance = toBN(spotAccount.depositBalance); spotAccount.borrowBalance = toBN(spotAccount.borrowBalance); spotAccount.maxTokenDeposits = toBN(spotAccount.maxTokenDeposits); spotAccount.lastInterestTs = toBN(spotAccount.lastInterestTs); spotAccount.lastTwapTs = toBN(spotAccount.lastTwapTs); spotAccount.scaleInitialAssetWeightStart = toBN(spotAccount.scaleInitialAssetWeightStart); spotAccount.withdrawGuardThreshold = toBN(spotAccount.withdrawGuardThreshold); spotAccount.depositTokenTwap = toBN(spotAccount.depositTokenTwap); spotAccount.borrowTokenTwap = toBN(spotAccount.borrowTokenTwap); spotAccount.utilizationTwap = toBN(spotAccount.utilizationTwap); spotAccount.nextDepositRecordId = toBN(spotAccount.nextDepositRecordId); spotAccount.orderStepSize = toBN(spotAccount.orderStepSize); spotAccount.orderTickSize = toBN(spotAccount.orderTickSize); spotAccount.minOrderSize = toBN(spotAccount.minOrderSize); spotAccount.maxPositionSize = toBN(spotAccount.maxPositionSize); spotAccount.nextFillRecordId = toBN(spotAccount.nextFillRecordId); formatPoolBalance(spotAccount.spotFeePool); spotAccount.totalSpotFee = toBN(spotAccount.totalSpotFee); spotAccount.totalSwapFee = toBN(spotAccount.totalSwapFee); spotAccount.flashLoanAmount = toBN(spotAccount.flashLoanAmount); spotAccount.flashLoanInitialTokenAmount = toBN(spotAccount.flashLoanInitialTokenAmount); } export function formatOraclePriceData(oracleData: OraclePriceData) { oracleData.price = toBN(oracleData.price); oracleData.slot = toBN(oracleData.slot); oracleData.confidence = toBN(oracleData.confidence); oracleData.twap = toBN(oracleData.twap); oracleData.twapConfidence = toBN(oracleData.twapConfidence); oracleData.maxPrice = toBN(oracleData.maxPrice); } export function formatOracleGuardRails(rails: OracleGuardRails) { if (rails) { if (rails.priceDivergence) { rails.priceDivergence.markOraclePercentDivergence = toBN(rails.priceDivergence.markOraclePercentDivergence); rails.priceDivergence.oracleTwap5MinPercentDivergence = toBN(rails.priceDivergence.oracleTwap5MinPercentDivergence); } if (rails.validity) { rails.validity.slotsBeforeStaleForAmm = toBN(rails.validity.slotsBeforeStaleForAmm); rails.validity.slotsBeforeStaleForMargin = toBN(rails.validity.slotsBeforeStaleForMargin); rails.validity.confidenceIntervalMaxSize = toBN(rails.validity.confidenceIntervalMaxSize); rails.validity.tooVolatileRatio = toBN(rails.validity.tooVolatileRatio); } } } export function formatFeeStructure(fee: FeeStructure) { if (fee) { if (fee.fillerRewardStructure) { formatOrderFillerRewardStructure(fee.fillerRewardStructure); } fee.flatFillerFee = toBN(fee.flatFillerFee); fee.referrerRewardEpochUpperBound = toBN(fee.referrerRewardEpochUpperBound); } } export function formatOrderFillerRewardStructure(reward: OrderFillerRewardStructure) { if (reward) { reward.rewardNumerator = toBN(reward.rewardNumerator); reward.rewardDenominator = toBN(reward.rewardDenominator); reward.timeBasedRewardLowerBound = toBN(reward.timeBasedRewardLowerBound); } } export function formatAMM(amm: AMM) { if (!amm) return; amm.baseAssetReserve = toBN(amm.baseAssetReserve); amm.sqrtK = toBN(amm.sqrtK); amm.cumulativeFundingRate = toBN(amm.cumulativeFundingRate); amm.lastFundingRate = toBN(amm.lastFundingRate); amm.lastFundingRateTs = toBN(amm.lastFundingRateTs); amm.lastMarkPriceTwap = toBN(amm.lastMarkPriceTwap); amm.lastMarkPriceTwap5Min = toBN(amm.lastMarkPriceTwap5Min); amm.lastMarkPriceTwapTs = toBN(amm.lastMarkPriceTwapTs); amm.lastTradeTs = toBN(amm.lastTradeTs); amm.oracle = toPublicKey(amm.oracle); formatHistoricalOracleData(amm.historicalOracleData); amm.lastOracleReservePriceSpreadPct = toBN(amm.lastOracleReservePriceSpreadPct); amm.lastOracleConfPct = toBN(amm.lastOracleConfPct); amm.fundingPeriod = toBN(amm.fundingPeriod); amm.quoteAssetReserve = toBN(amm.quoteAssetReserve); amm.pegMultiplier = toBN(amm.pegMultiplier); amm.cumulativeFundingRateLong = toBN(amm.cumulativeFundingRateLong); amm.cumulativeFundingRateShort = toBN(amm.cumulativeFundingRateShort); amm.last24HAvgFundingRate = toBN(amm.last24HAvgFundingRate); amm.lastFundingRateShort = toBN(amm.lastFundingRateShort); amm.lastFundingRateLong = toBN(amm.lastFundingRateLong); amm.totalLiquidationFee = toBN(amm.totalLiquidationFee); amm.totalFeeMinusDistributions = toBN(amm.totalFeeMinusDistributions); amm.totalFeeWithdrawn = toBN(amm.totalFeeWithdrawn); amm.totalFee = toBN(amm.totalFee); amm.totalFeeEarnedPerLp = toBN(amm.totalFeeEarnedPerLp); amm.userLpShares = toBN(amm.userLpShares); amm.baseAssetAmountWithUnsettledLp = toBN(amm.baseAssetAmountWithUnsettledLp); amm.orderStepSize = toBN(amm.orderStepSize); amm.orderTickSize = toBN(amm.orderTickSize); amm.baseAssetAmountWithAmm = toBN(amm.baseAssetAmountWithAmm); amm.baseAssetAmountLong = toBN(amm.baseAssetAmountLong); amm.baseAssetAmountShort = toBN(amm.baseAssetAmountShort); amm.quoteAssetAmount = toBN(amm.quoteAssetAmount); amm.terminalQuoteAssetReserve = toBN(amm.terminalQuoteAssetReserve); amm.concentrationCoef = toBN(amm.concentrationCoef); amm.feePool.scaledBalance = toBN(amm.feePool.scaledBalance); amm.totalExchangeFee = toBN(amm.totalExchangeFee); amm.totalMmFee = toBN(amm.totalMmFee); amm.netRevenueSinceLastFunding = toBN(amm.netRevenueSinceLastFunding); amm.lastUpdateSlot = toBN(amm.lastUpdateSlot); amm.lastOracleNormalisedPrice = toBN(amm.lastOracleNormalisedPrice); amm.lastBidPriceTwap = toBN(amm.lastBidPriceTwap); amm.lastAskPriceTwap = toBN(amm.lastAskPriceTwap); amm.baseAssetAmountPerLp = toBN(amm.baseAssetAmountPerLp); amm.quoteAssetAmountPerLp = toBN(amm.quoteAssetAmountPerLp); amm.maxOpenInterest = toBN(amm.maxOpenInterest); amm.maxBaseAssetReserve = toBN(amm.maxBaseAssetReserve); amm.minBaseAssetReserve = toBN(amm.minBaseAssetReserve); amm.totalSocialLoss = toBN(amm.totalSocialLoss); amm.quoteBreakEvenAmountLong = toBN(amm.quoteBreakEvenAmountLong); amm.quoteBreakEvenAmountShort = toBN(amm.quoteBreakEvenAmountShort); amm.quoteEntryAmountLong = toBN(amm.quoteEntryAmountLong); amm.quoteEntryAmountShort = toBN(amm.quoteEntryAmountShort); amm.markStd = toBN(amm.markStd); amm.oracleStd = toBN(amm.oracleStd); amm.longIntensityVolume = toBN(amm.longIntensityVolume); amm.shortIntensityVolume = toBN(amm.shortIntensityVolume); amm.volume24H = toBN(amm.volume24H); amm.minOrderSize = toBN(amm.minOrderSize); amm.maxPositionSize = toBN(amm.maxPositionSize); amm.bidBaseAssetReserve = toBN(amm.bidBaseAssetReserve); amm.bidQuoteAssetReserve = toBN(amm.bidQuoteAssetReserve); amm.askBaseAssetReserve = toBN(amm.askBaseAssetReserve); amm.askQuoteAssetReserve = toBN(amm.askQuoteAssetReserve); amm.netUnsettledFundingPnl = toBN(amm.netUnsettledFundingPnl); amm.quoteAssetAmountWithUnsettledLp = toBN(amm.quoteAssetAmountWithUnsettledLp); } export function formatHistoricalOracleData(data: HistoricalOracleData) { if (data) { data.lastOraclePrice = toBN(data.lastOraclePrice); data.lastOracleDelay = toBN(data.lastOracleDelay); data.lastOracleConf = toBN(data.lastOracleConf); data.lastOraclePriceTwap = toBN(data.lastOraclePriceTwap); data.lastOraclePriceTwap5Min = toBN(data.lastOraclePriceTwap5Min); data.lastOraclePriceTwapTs = toBN(data.lastOraclePriceTwapTs); } } export function formatHistoricalIndexData(data: HistoricalIndexData) { if (data) { data.lastIndexBidPrice = toBN(data.lastIndexBidPrice); data.lastIndexAskPrice = toBN(data.lastIndexAskPrice); data.lastIndexPriceTwap = toBN(data.lastIndexPriceTwap); data.lastIndexPriceTwap5Min = toBN(data.lastIndexPriceTwap5Min); data.lastIndexPriceTwapTs = toBN(data.lastIndexPriceTwapTs); } } export function formatPoolBalance(poolBalance: PoolBalance) { if (poolBalance) { poolBalance.scaledBalance = toBN(poolBalance.scaledBalance); } } export function toBN(bn) { if (bn !== undefined) { return new BN(bn, 'hex'); } else { return undefined; } } export function toPublicKey(pubkey) { if (pubkey) { return new PublicKey(pubkey); } else { return undefined; } }