@orca-so/whirlpool-sdk
Version:
Whirlpool SDK for the Orca protocol.
133 lines (132 loc) • 6.67 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSwapQuote = exports.getClosePositionQuote = exports.getOpenPositionQuote = void 0;
const whirlpool_client_sdk_1 = require("@orca-so/whirlpool-client-sdk");
const anchor_1 = require("@project-serum/anchor");
const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
const public_1 = require("../constants/public");
const add_liquidity_1 = require("./add-liquidity");
const address_1 = require("../utils/address");
const public_2 = require("../utils/public");
const tick_util_1 = require("../utils/whirlpool/tick-util");
const swap_quoter_1 = require("./swap-quoter");
const remove_liquidity_1 = require("./remove-liquidity");
const types_1 = require("./types");
/**
* Construct a quote for opening a new position
*/
function getOpenPositionQuote(ctx, param) {
return __awaiter(this, void 0, void 0, function* () {
const { poolAddress, tokenMint, tokenAmount, slippageTolerance, refresh } = param;
const whirlpool = yield ctx.accountFetcher.getPool(poolAddress, refresh);
if (!whirlpool) {
throw new Error(`Whirlpool not found: ${(0, anchor_1.translateAddress)(poolAddress).toBase58()}`);
}
let tickLowerIndex = undefined;
let tickUpperIndex = undefined;
if ((0, types_1.isQuoteByTickIndex)(param)) {
tickLowerIndex = param.tickLowerIndex;
tickUpperIndex = param.tickUpperIndex;
}
else {
(0, tiny_invariant_1.default)((0, types_1.isQuoteByPrice)(param), "invalid OpenPositionQuoteParam");
tickLowerIndex = tick_util_1.TickUtil.toValid((0, whirlpool_client_sdk_1.sqrtPriceX64ToTickIndex)((0, whirlpool_client_sdk_1.toX64)(param.priceLower.sqrt())), whirlpool.tickSpacing);
tickUpperIndex = tick_util_1.TickUtil.toValid((0, whirlpool_client_sdk_1.sqrtPriceX64ToTickIndex)((0, whirlpool_client_sdk_1.toX64)(param.priceUpper.sqrt())), whirlpool.tickSpacing);
}
const internalParam = {
tokenMintA: whirlpool.tokenMintA,
tokenMintB: whirlpool.tokenMintB,
tickCurrentIndex: whirlpool.tickCurrentIndex,
sqrtPrice: whirlpool.sqrtPrice,
inputTokenMint: (0, address_1.toPubKey)(tokenMint),
inputTokenAmount: tokenAmount,
tickLowerIndex,
tickUpperIndex,
slippageTolerance: slippageTolerance || public_1.defaultSlippagePercentage,
};
return Object.assign({ poolAddress,
tickLowerIndex,
tickUpperIndex }, (0, add_liquidity_1.getAddLiquidityQuote)(internalParam));
});
}
exports.getOpenPositionQuote = getOpenPositionQuote;
/**
* Construct a quote for closing an existing position
*/
function getClosePositionQuote(ctx, param) {
return __awaiter(this, void 0, void 0, function* () {
const { positionAddress, refresh, slippageTolerance } = param;
const position = yield ctx.accountFetcher.getPosition(positionAddress, refresh);
if (!position) {
throw new Error(`Position not found: ${(0, anchor_1.translateAddress)(positionAddress).toBase58()}`);
}
const whirlpool = yield ctx.accountFetcher.getPool(position.whirlpool, refresh);
if (!whirlpool) {
throw new Error(`Whirlpool not found: ${(0, anchor_1.translateAddress)(position.whirlpool).toBase58()}`);
}
return (0, remove_liquidity_1.getRemoveLiquidityQuote)({
positionAddress: (0, address_1.toPubKey)(positionAddress),
tickCurrentIndex: whirlpool.tickCurrentIndex,
sqrtPrice: whirlpool.sqrtPrice,
tickLowerIndex: position.tickLowerIndex,
tickUpperIndex: position.tickUpperIndex,
liquidity: position.liquidity,
slippageTolerance: slippageTolerance || public_1.defaultSlippagePercentage,
});
});
}
exports.getClosePositionQuote = getClosePositionQuote;
/**
* Construct a quote for swap
*/
function getSwapQuote(ctx, param) {
return __awaiter(this, void 0, void 0, function* () {
const { poolAddress, tokenMint, tokenAmount, isInput, slippageTolerance = public_1.defaultSlippagePercentage, refresh, } = param;
const whirlpool = yield ctx.accountFetcher.getPool(poolAddress, refresh);
if (!whirlpool) {
throw new Error(`Whirlpool not found: ${(0, anchor_1.translateAddress)(poolAddress).toBase58()}`);
}
const swapDirection = (0, address_1.toPubKey)(tokenMint).equals(whirlpool.tokenMintA) === isInput
? swap_quoter_1.SwapDirection.AtoB
: swap_quoter_1.SwapDirection.BtoA;
const amountSpecified = isInput ? swap_quoter_1.AmountSpecified.Input : swap_quoter_1.AmountSpecified.Output;
const swapSimulator = new swap_quoter_1.SwapSimulator();
// Return sqrtPriceLimit
const { amountIn, amountOut, sqrtPriceLimitX64 } = yield swapSimulator.simulateSwap(ctx, {
refresh,
dal: ctx.accountFetcher,
poolAddress,
whirlpoolData: whirlpool,
amountSpecified,
swapDirection,
}, {
amount: tokenAmount,
currentSqrtPriceX64: whirlpool.sqrtPrice,
currentTickIndex: whirlpool.tickCurrentIndex,
currentLiquidity: whirlpool.liquidity,
});
const otherAmountThreshold = (0, public_2.adjustAmountForSlippage)(amountIn, amountOut, slippageTolerance, amountSpecified);
return {
poolAddress,
otherAmountThreshold,
sqrtPriceLimitX64,
amountIn,
amountOut,
aToB: swapDirection === swap_quoter_1.SwapDirection.AtoB,
fixedInput: isInput,
};
});
}
exports.getSwapQuote = getSwapQuote;
;