@symmetry-hq/baskets-v2-sdk
Version:
Symmetry Baskets V2 SDK
199 lines (198 loc) • 9.79 kB
JavaScript
"use strict";
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buyBasketHandler = buyBasketHandler;
exports.sellBasketHandler = sellBasketHandler;
exports.sellRebalanceTokensIxs = sellRebalanceTokensIxs;
exports.sellRebalanceHandler = sellRebalanceHandler;
exports.claimTokensHandler = claimTokensHandler;
const web3_js_1 = require("@solana/web3.js");
const programAccounts_1 = require("./utils/programAccounts");
const txUtils_1 = require("./utils/txUtils");
const updateTokenPrices_1 = require("./instructions/update/updateTokenPrices");
const deposit_1 = require("./instructions/buy/deposit");
const withdraw_1 = require("./instructions/sell/withdraw");
const initializeWithdrawState_1 = require("./instructions/sell/initializeWithdrawState");
const jup_1 = require("./instructions/jup");
const withdrawState_1 = require("./state/withdrawState");
const depositAfterRebalance_1 = require("./instructions/sell/depositAfterRebalance");
const withdrawBeforeRebalance_1 = require("./instructions/sell/withdrawBeforeRebalance");
const claimTokens_1 = require("./instructions/sell/claimTokens");
const constants_1 = require("./utils/constants");
const spl_token_1 = require("@solana/spl-token");
const createAtas_1 = require("./utils/createAtas");
function buyBasketHandler(sdkParams, params) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const preIxs = [];
if (params.depositMint.equals(constants_1.WSOL_MINT)) {
const ata = (0, programAccounts_1.getAta)(sdkParams.payer, constants_1.WSOL_MINT);
const info = yield sdkParams.connection.getAccountInfo(ata);
let toWrap = params.depositAmount;
if (info)
toWrap -= parseInt((_b = (_a = info.data) === null || _a === void 0 ? void 0 : _a.readBigUInt64LE(64).toString()) !== null && _b !== void 0 ? _b : "0");
else
preIxs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(sdkParams.payer, ata, sdkParams.payer, constants_1.WSOL_MINT));
if (toWrap > 0) {
preIxs.push(web3_js_1.SystemProgram.transfer({
fromPubkey: sdkParams.payer,
toPubkey: ata,
lamports: toWrap,
}));
preIxs.push((0, spl_token_1.createSyncNativeInstruction)(ata));
}
}
const { ixs: updatePricesIxs, luts: updatePricesLuts, } = yield (0, updateTokenPrices_1.updateTokenPricesIxs)({
program: sdkParams.program,
basket: params.basket,
});
const buyIx = yield (0, deposit_1.depositIx)(Object.assign({ program: sdkParams.program, buyer: sdkParams.payer }, params));
const txs = updatePricesIxs.map(ix => [ix]);
const luts = new Array(updatePricesIxs.length).fill(updatePricesLuts);
const signers = new Array(updatePricesIxs.length).fill([]);
if (preIxs.length > 0) {
txs.push(preIxs);
luts.push([]);
signers.push([]);
}
txs.push([buyIx]);
luts.push([]);
signers.push([]);
return yield (0, txUtils_1.prepareV0Transactions)({
connection: sdkParams.connection,
payer: sdkParams.payer,
priorityFee: sdkParams.priorityFee,
multipleIxs: txs,
multipleLookupTableAddresses: luts,
signers: signers,
batches: [txs.length - 1, 1],
});
});
}
function sellBasketHandler(sdkParams, params) {
return __awaiter(this, void 0, void 0, function* () {
const { ixs: updatePricesIxs, luts: updatePricesLuts, } = yield (0, updateTokenPrices_1.updateTokenPricesIxs)({
program: sdkParams.program,
basket: params.basket,
});
const initIx = yield (0, initializeWithdrawState_1.initializeWithdrawStateIx)({
program: sdkParams.program,
withdrawStateSeed: params.withdrawStateSeed,
});
const sellIx = yield (0, withdraw_1.withdrawIx)(Object.assign({ program: sdkParams.program, seller: sdkParams.payer }, params));
return yield (0, txUtils_1.prepareV0Transactions)({
connection: sdkParams.connection,
payer: sdkParams.payer,
priorityFee: sdkParams.priorityFee,
multipleIxs: [...updatePricesIxs.map(ix => [ix]), [initIx, sellIx]],
multipleLookupTableAddresses: [...new Array(updatePricesIxs.length).fill(updatePricesLuts), []],
signers: [...new Array(updatePricesIxs.length).fill([]), []],
batches: [updatePricesIxs.length, 1],
});
});
}
function sellRebalanceTokensIxs(sdkParams, params) {
return __awaiter(this, void 0, void 0, function* () {
const { withdrawStateData, fromToken } = params;
const fromTokenIndex = withdrawStateData.compositionMints.findIndex(mint => mint.equals(fromToken));
const fromAmount = parseInt(withdrawStateData.compositionAmounts[fromTokenIndex].toString());
const quoteResponse = yield (0, jup_1.getQuoteResponseHandler)({
jupiterApiKey: sdkParams.jupiterApiKey,
maxAllowedAccounts: sdkParams.maxAllowedAccounts,
fromToken: params.fromToken,
toToken: withdrawStateData.destinationMint,
amount: fromAmount,
slippageBps: 100,
});
const withdrawIx = yield (0, withdrawBeforeRebalance_1.sellWithdrawBeforeRebalanceIx)({
program: sdkParams.program,
withdrawStateData: withdrawStateData,
payer: sdkParams.payer,
fromTokenMint: params.fromToken,
});
const jupIxAndLuts = yield (0, jup_1.generateSwapInstruction)({
payer: sdkParams.payer,
jupiterApiKey: sdkParams.jupiterApiKey,
quoteResponse: quoteResponse,
}).catch(() => null);
if (!jupIxAndLuts) {
return {
ixs: [],
luts: [],
};
}
const depositIx = yield (0, depositAfterRebalance_1.sellDepositAfterRebalanceIx)({
program: sdkParams.program,
withdrawStateData: withdrawStateData,
payer: sdkParams.payer,
fromTokenMint: params.fromToken,
});
return {
ixs: [withdrawIx, jupIxAndLuts.ix, depositIx],
luts: jupIxAndLuts.luts,
};
});
}
function sellRebalanceHandler(sdkParams, params) {
return __awaiter(this, void 0, void 0, function* () {
const withdrawStateData = yield (0, withdrawState_1.fetchWithdrawState)(sdkParams.program, params.withdrawState);
const ixs = [];
const luts = [];
const tokenMints = [];
for (let i = 0; i < withdrawStateData.compositionMints.length; i++) {
const fromToken = withdrawStateData.compositionMints[i];
const fromAmount = parseInt(withdrawStateData.compositionAmounts[i].toString());
if (fromAmount > 0) {
const { ixs: tempIxs, luts: tempLuts } = yield sellRebalanceTokensIxs(sdkParams, {
withdrawStateData,
fromToken,
});
if (tempIxs.length > 0) {
ixs.push(tempIxs);
luts.push(tempLuts);
tokenMints.push(withdrawStateData.destinationMint, fromToken);
}
}
}
if (ixs.length === 0)
throw new Error("No rebalance transactions found");
const preIxs = yield (0, createAtas_1.createAtasIxs)(sdkParams.connection, {
payer: sdkParams.payer,
mints: tokenMints,
});
return yield (0, txUtils_1.prepareV0Transactions)({
connection: sdkParams.connection,
payer: sdkParams.payer,
priorityFee: sdkParams.priorityFee,
multipleIxs: [...preIxs, ...ixs],
multipleLookupTableAddresses: [...new Array(preIxs.length).fill([]), ...luts],
signers: [...new Array(preIxs.length).fill([]), ...new Array(ixs.length).fill([])],
batches: [preIxs.length, ixs.length],
});
});
}
function claimTokensHandler(sdkParams, params) {
return __awaiter(this, void 0, void 0, function* () {
const ixs = yield (0, claimTokens_1.claimTokensIxs)(Object.assign({ program: sdkParams.program, payer: sdkParams.payer }, params));
const bundledIxs = [];
for (let i = 0; i < ixs.length; i += constants_1.MAX_CLAIM_TOKENS_PER_TX)
bundledIxs.push(ixs.slice(i, i + constants_1.MAX_CLAIM_TOKENS_PER_TX));
return yield (0, txUtils_1.prepareV0Transactions)({
connection: sdkParams.connection,
payer: sdkParams.payer,
priorityFee: sdkParams.priorityFee,
multipleIxs: bundledIxs,
multipleLookupTableAddresses: new Array(bundledIxs.length).fill([]),
signers: new Array(bundledIxs.length).fill([]),
batches: [bundledIxs.length],
});
});
}