@marinade.finance/kamino-sdk
Version:
272 lines (238 loc) • 7.1 kB
text/typescript
import { PublicKey, TransactionInstruction, TransactionMessage } from '@solana/web3.js';
import { WhirlpoolStrategy } from '../kamino-client/accounts';
import { Dex, collToLamportsDecimal } from './utils';
import Decimal from 'decimal.js';
import { RebalanceTypeKind } from '../kamino-client/types';
export const RAYDIUM_DEVNET_PROGRAM_ID = new PublicKey('devi51mZmdwUJGU9hjN27vEz64Gps7uUefqxg27EAtH');
export type StrategyType = 'NON_PEGGED' | 'PEGGED' | 'STABLE';
export type StrategyCreationStatus = 'IGNORED' | 'SHADOW' | 'LIVE' | 'DEPRECATED' | 'STAGING';
export type StrategiesFilters = {
strategyType?: StrategyType;
strategyCreationStatus?: StrategyCreationStatus;
isCommunity?: boolean;
};
export function strategyTypeToBase58(strategyType: StrategyType): string {
switch (strategyType) {
case 'NON_PEGGED':
return '1';
case 'PEGGED':
return '2';
case 'STABLE':
return '3';
default:
throw new Error(`Invalid strategyType ${strategyType}`);
}
}
export function strategyTypeToNumber(strategyType: StrategyType): number {
switch (strategyType) {
case 'NON_PEGGED':
return 0;
case 'PEGGED':
return 1;
case 'STABLE':
return 2;
default:
throw new Error(`Invalid strategyType ${strategyType}`);
}
}
export function getStrategyTypeFromStrategy(strategy: WhirlpoolStrategy): StrategyType {
switch (strategy.strategyType.toNumber()) {
case 0:
return 'NON_PEGGED';
case 1:
return 'PEGGED';
case 2:
return 'STABLE';
default:
throw new Error(`Unknown strategyType value ${strategy.strategyType.toNumber()}`);
}
}
export function strategyCreationStatusToBase58(strategyCreationStatus: StrategyCreationStatus): string {
switch (strategyCreationStatus) {
case 'IGNORED':
return '1';
case 'SHADOW':
return '2';
case 'LIVE':
return '3';
case 'DEPRECATED':
return '4';
case 'STAGING':
return '5';
default:
throw new Error(`Invalid strategyCreationStatus ${strategyCreationStatus}`);
}
}
export function strategyCreationStatusToNumber(strategyCreationStatus: StrategyCreationStatus): number {
switch (strategyCreationStatus) {
case 'IGNORED':
return 0;
case 'SHADOW':
return 1;
case 'LIVE':
return 2;
case 'DEPRECATED':
return 3;
case 'STAGING':
return 4;
default:
throw new Error(`Invalid strategyCreationStatus ${strategyCreationStatus}`);
}
}
export function getStrategyCreationStatusFromStrategy(strategy: WhirlpoolStrategy): StrategyCreationStatus {
switch (strategy.creationStatus) {
case 0:
return 'IGNORED';
case 1:
return 'SHADOW';
case 2:
return 'LIVE';
case 3:
return 'DEPRECATED';
case 4:
return 'STAGING';
default:
throw new Error(`Invalid strategyCreationStatus ${strategy.creationStatus}`);
}
}
export interface GenericPoolInfo {
dex: Dex;
address: PublicKey;
tokenMintA: PublicKey;
tokenMintB: PublicKey;
price: Decimal;
feeRate: Decimal;
volumeOnLast7d: Decimal | undefined;
tvl: Decimal | undefined;
tickSpacing: Decimal;
positions: Decimal;
}
export interface GenericPositionRangeInfo {
estimatedApy: Decimal;
estimatedVolume: Decimal | undefined;
}
export interface VaultParameters {
tokenMintA: PublicKey;
tokenMintB: PublicKey;
dex: Dex;
feeTier: Decimal;
rebalancingParameters: RebalanceFieldInfo[];
}
export interface LiquidityDistribution {
currentPrice: Decimal;
currentTickIndex: number;
distribution: LiquidityForPrice[];
}
export interface LiquidityForPrice {
price: Decimal;
liquidity: Decimal;
tickIndex: number;
}
export interface DepositAmountsForSwap {
requiredAAmountToDeposit: Decimal;
requiredBAmountToDeposit: Decimal;
tokenAToSwapAmount: Decimal;
tokenBToSwapAmount: Decimal;
}
export function depositAmountsForSwapToLamports(
depositAmounts: DepositAmountsForSwap,
tokenADecimals: number,
tokenBDecimals: number
): DepositAmountsForSwap {
return {
requiredAAmountToDeposit: collToLamportsDecimal(depositAmounts.requiredAAmountToDeposit, tokenADecimals),
requiredBAmountToDeposit: collToLamportsDecimal(depositAmounts.requiredBAmountToDeposit, tokenBDecimals),
tokenAToSwapAmount: collToLamportsDecimal(depositAmounts.tokenAToSwapAmount, tokenADecimals),
tokenBToSwapAmount: collToLamportsDecimal(depositAmounts.tokenBToSwapAmount, tokenBDecimals),
};
}
export interface RebalanceParams {
rebalanceType: RebalanceTypeKind;
lowerRangeBps?: Decimal;
upperRangeBps?: Decimal;
resetRangeLowerBps?: Decimal;
resetRangeUpperBps?: Decimal;
startMidTick?: Decimal;
ticksBelowMid?: Decimal;
ticksAboveMid?: Decimal;
secondsPerTick?: Decimal;
driftDirection?: Decimal;
period?: Decimal;
lowerRangePrice?: Decimal;
upperRangePrice?: Decimal;
destinationToken?: Decimal;
}
export interface RebalanceParamsAsPrices {
rebalanceType: RebalanceTypeKind;
rangePriceLower: Decimal;
rangePriceUpper: Decimal;
resetPriceLower?: Decimal;
resetPriceUpper?: Decimal;
}
export interface PositionRange {
lowerPrice: Decimal;
upperPrice: Decimal;
}
export interface MaybeTokensBalances {
a?: Decimal;
b?: Decimal;
}
export interface TokensBalances {
a: Decimal;
b: Decimal;
}
export interface SwapperIxBuilder {
(
input: DepositAmountsForSwap,
tokenAMint: PublicKey,
tokenBMint: PublicKey,
owner: PublicKey,
slippage: Decimal,
allKeys: PublicKey[]
): Promise<[TransactionInstruction[], PublicKey[]]>;
}
export interface ProfiledFunctionExecution {
(promise: Promise<any>, transactionName: string, tags: [string, string][]): Promise<any>;
}
export function noopProfiledFunctionExecution(promise: Promise<any>, transactionName: string): Promise<any> {
return promise;
}
export interface CreateAta {
ata: PublicKey;
createIxns: TransactionInstruction[];
closeIxns: TransactionInstruction[];
}
export interface DeserializedVersionedTransaction {
txMessage: TransactionMessage[];
lookupTablesAddresses: PublicKey[];
}
export interface InstructionsWithLookupTables {
instructions: TransactionInstruction[];
lookupTablesAddresses: PublicKey[];
}
export interface PerformanceFees {
feesFeeBPS: Decimal;
reward0FeeBPS: Decimal;
reward1FeeBPS: Decimal;
reward2FeeBPS: Decimal;
}
export interface RebalanceFieldInfo {
label: string;
type: string;
value: Decimal | string;
enabled: boolean; // if true, the field is editable and it is one of the rebalancing fields; if false it is a field that is calculated/generated from the rebalancing fields + other data (price, fee tier, etc)
}
export type RebalanceFieldsDict = { [key: string]: Decimal };
export interface PriceReferenceType {
name: string;
descriptionShort?: string;
description?: string;
}
export interface InputRebalanceFieldInfo {
label: string;
value: Decimal;
}
export interface WithdrawAllAndCloseIxns {
withdrawIxns: TransactionInstruction[];
closeIxn: TransactionInstruction;
}