@symmetry-hq/baskets-sdk
Version:
Software Development Kit for interacting with Symmetry Baskets Program
663 lines (662 loc) • 35.8 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
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.BasketsSDK = exports.BasketInstructions = void 0;
const web3_js_1 = require("@solana/web3.js");
const anchor_1 = require("@coral-xyz/anchor");
const basketsIDL_1 = require("./basketsIDL");
const basketState_1 = require("./basketState");
const config_1 = require("./config");
const utils_1 = require("./utils");
const buyState_1 = require("./buyState");
const simulation_1 = require("./simulation");
const splTokenHelpers_1 = require("./splTokenHelpers");
const nodewallet_1 = __importDefault(require("@coral-xyz/anchor/dist/cjs/nodewallet"));
const instructionsBuilder_1 = require("./instructionsBuilder");
const flashRebalance_1 = require("./flashRebalance");
exports.BasketInstructions = __importStar(require("./basketInstructions"));
__exportStar(require("./config"), exports);
__exportStar(require("./basketState"), exports);
__exportStar(require("./buyState"), exports);
__exportStar(require("./utils"), exports);
__exportStar(require("./basketsIDL"), exports);
class BasketsSDK {
constructor(connection, program, swbProgram, swbIDL, tokenList, lookups, wallet) {
this.jupAPIkey = "https://quote-api.jup.ag/v6/";
this.connection = connection;
this.wallet = wallet;
this.program = program;
this.swbProgram = swbProgram;
this.swbIDL = swbIDL;
this.tokenList = tokenList;
this.lamports = config_1.ADDITIONAL_FEE;
this.lookups = lookups;
}
static init(connection, wallet) {
return __awaiter(this, void 0, void 0, function* () {
let provider = new anchor_1.AnchorProvider(connection, wallet ? wallet : new nodewallet_1.default(web3_js_1.Keypair.generate()), {
skipPreflight: true,
preflightCommitment: "recent",
commitment: "processed",
});
// const symmetryEngineIDL: BasketsIDL = (await Program.fetchIdl(BASKETS_PROGRAM_ID, provider))!;
let program = new anchor_1.Program(basketsIDL_1.IDL, provider);
let swbIDL = (yield anchor_1.Program.fetchIdl(config_1.SWB_PID, provider));
let swbProgram = new anchor_1.Program(swbIDL, provider);
let tokenList = yield (0, utils_1.fetchTokenList)(program);
let lookups = yield Promise.all([
(0, flashRebalance_1.getLookupTableAccount)(program.provider.connection, config_1.BASKETS_LOOKUP_TABLE_1),
(0, flashRebalance_1.getLookupTableAccount)(program.provider.connection, config_1.BASKETS_LOOKUP_TABLE_2)
]);
return new BasketsSDK(connection, program, swbProgram, swbIDL, tokenList, lookups, wallet);
});
}
setWallet(wallet) {
this.wallet = wallet;
let provider = new anchor_1.AnchorProvider(this.connection, wallet, {
skipPreflight: true,
preflightCommitment: "recent",
commitment: "recent",
});
this.program = new anchor_1.Program(basketsIDL_1.IDL, provider);
this.swbProgram = new anchor_1.Program(this.swbIDL, provider);
}
setPriorityFee(lamports) {
this.lamports = lamports;
}
setJupAPIKey(apiKey) {
this.jupAPIkey = apiKey;
}
loadFromPubkey(pubkey) {
return __awaiter(this, void 0, void 0, function* () {
return yield basketState_1.Basket.loadFromPubkey(this.program, pubkey);
});
}
getCurrentCompositions(baskets) {
return __awaiter(this, void 0, void 0, function* () {
let oraclePriceData = yield (0, utils_1.getOraclePrices)(this.program, this.tokenList);
let parsed = baskets.map(basket => (0, utils_1.getCurrentComposition)(basket, this.tokenList, oraclePriceData));
yield Promise.all(parsed.map(x => (0, utils_1.tryMetadata)(x))).then(metadatas => {
for (let i = 0; i < parsed.length; i++)
parsed[i].metadata = metadatas[i];
});
return parsed;
});
}
findBaskets(filters) {
return __awaiter(this, void 0, void 0, function* () {
let accountFilters = [{ dataSize: 10208 }];
accountFilters.push({ memcmp: {
offset: 112,
bytes: "11111111"
} });
accountFilters = [...accountFilters, ...filters.map(filter => {
return {
memcmp: {
offset: (filter.filterType == "host") ? 128 : 16,
bytes: filter.filterPubkey.toBase58(),
}
};
})];
let accounts = yield (0, utils_1.getFilteredProgramAccounts)(this.connection, accountFilters).catch((e) => { console.log(e); return []; });
return accounts
.map(account => basketState_1.Basket.loadFromRawData(this.program, account));
});
}
findActiveSellStates(user) {
return __awaiter(this, void 0, void 0, function* () {
let accounts = yield (0, utils_1.getFilteredProgramAccounts)(this.connection, [
{ dataSize: 10208 },
{ memcmp: {
offset: 16,
bytes: user.toBase58()
} },
{ memcmp: {
offset: 112,
bytes: "Ahg1opVcGX",
} },
]);
return accounts
.map(account => basketState_1.Basket.loadFromRawData(this.program, account));
});
}
findActiveBuyStates(user) {
return __awaiter(this, void 0, void 0, function* () {
let accounts = yield (0, utils_1.getFilteredProgramAccounts)(this.connection, [
{ dataSize: 680 },
{ memcmp: {
offset: 40,
bytes: user.toBase58()
} }
]);
return yield buyState_1.BuyState.loadMultiple(this.program, accounts);
});
}
fetchAllBuyStates(filters) {
return __awaiter(this, void 0, void 0, function* () {
let accountFilters = [{ dataSize: 680 }];
accountFilters = [...accountFilters, ...filters.map(filter => {
return {
memcmp: {
offset: (filter.filterType == "host") ? 104 : 72,
bytes: filter.filterPubkey.toBase58(),
}
};
})];
let accounts = yield (0, utils_1.getFilteredProgramAccounts)(this.connection, accountFilters);
return yield buyState_1.BuyState.loadMultiple(this.program, accounts);
});
}
fetchBuyStateFromPubkey(pubkey) {
return __awaiter(this, void 0, void 0, function* () {
return yield buyState_1.BuyState.loadFromPubkey(this.program, pubkey);
});
}
fetchAllSellStates(filters) {
return __awaiter(this, void 0, void 0, function* () {
let accountFilters = [{ dataSize: 10208 }];
accountFilters.push({ memcmp: {
offset: 112,
bytes: "Ahg1opVcGX"
} });
accountFilters = [...accountFilters, ...filters.map(filter => {
return {
memcmp: {
offset: (filter.filterType == "host") ? 128 : 16,
bytes: filter.filterPubkey.toBase58(),
}
};
})];
let accounts = yield (0, utils_1.getFilteredProgramAccounts)(this.connection, accountFilters);
return accounts
.map(account => basketState_1.Basket.loadFromRawData(this.program, account));
});
}
fetchAllHoldings(user) {
return __awaiter(this, void 0, void 0, function* () {
let tokenAccountsRaw = yield this.connection.getTokenAccountsByOwner(new web3_js_1.PublicKey(user), { programId: new web3_js_1.PublicKey(splTokenHelpers_1.TOKEN_PROGRAM_ID) }, "processed");
let tokenAccountsDecoded = tokenAccountsRaw.value.map(account => {
return {
mint: new web3_js_1.PublicKey(account.account.data.slice(0, 32)),
balance: parseInt(new anchor_1.BN(account.account.data.slice(64, 72), "le").toString()),
};
});
let basketsRaw = yield (0, utils_1.getFilteredProgramAccounts)(this.connection, [
{ dataSize: 10208 },
{
memcmp: {
offset: 112,
bytes: "11111111"
}
}
]);
let basketsDecoded = basketsRaw.map(account => {
return {
decoded: this.program.coder.accounts.decode("fundState", account.account.data),
pubkey: account.pubkey
};
});
let basketHoldings = [];
for (let i = 0; i < basketsDecoded.length; i++) {
let ataIndex = tokenAccountsDecoded
.findIndex(x => x.mint.toBase58() == basketsDecoded[i].decoded.fundToken.toBase58());
if (ataIndex == -1)
continue;
basketHoldings.push({
basketAddress: basketsDecoded[i].pubkey.toBase58(),
mint: basketsDecoded[i].decoded.fundToken.toBase58(),
balance: tokenAccountsDecoded[ataIndex].balance / 10 ** 6,
basketData: basketsDecoded[i].decoded,
});
}
return basketHoldings;
});
}
getTokenListData() {
return this.tokenList.filter(x => x.isLive == true);
}
tokenIdFromMint(tokenMint) {
for (let i = 0; i < this.tokenList.length; i++)
if (this.tokenList[i].tokenMint == tokenMint)
return this.tokenList[i].id;
throw new config_1.BasketError("Token not supported by Symmetry Engine");
}
createBasket(createBasketParams) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield basketState_1.Basket.create(this.program, this.connection, this.wallet, this.tokenList, this.lookups, createBasketParams, this.lamports);
});
}
simulateBasket(createBasketParams, simulationDays) {
return __awaiter(this, void 0, void 0, function* () {
return yield (0, simulation_1.simulate)(this.program, config_1.DATABASE_ADDESS, config_1.TOKEN_LIST_ADDRESS, createBasketParams, simulationDays);
});
}
editBasket(basket, editBasketParams) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield basket.edit(this.program, this.connection, this.wallet, this.tokenList, this.lookups, editBasketParams, this.lamports);
});
}
setMetadata(basket_1, symbol_1, name_1) {
return __awaiter(this, arguments, void 0, function* (basket, symbol, name, uri = "") {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield basket.setMetaData(this.program, this.wallet, symbol, name, uri, this.lamports);
});
}
editManager(basket, newManager) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield basket.editManager(this.program, this.connection, this.wallet, newManager, this.lamports);
});
}
// async simpleEditBasket(
// basket: Basket,
// basketParams: SimpleEditParams,
// ): Promise<TransactionSignature[]> {
// if (!this.wallet)
// throw new BasketError("Wallet not provided");
// return await basket.simpleEdit(
// this.program,
// this.connection,
// this.wallet,
// this.tokenList,
// basketParams,
// this.lamports,
// )
// }
closeBasket(basket) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield basket.close(this.program, this.wallet, this.lamports);
});
}
refilterBasketInstruction(basket) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
//@ts-ignore
return yield refilterInstruction(this.program, basket.ownAddress, (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.publicKey);
});
}
// async refilterBasket(basket: Basket): Promise<TransactionSignature> {
// if (!this.wallet)
// throw new BasketError("Wallet not provided");
// return await basket.refilter(
// this.program,
// this.wallet,
// this.lamports,
// );
// }
reweightBasketInstruction(basket) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
//@ts-ignore
return yield reweightInstruction(this.program, basket.ownAddress, (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.publicKey);
});
}
// async reweightBasket(basket: Basket): Promise<TransactionSignature> {
// if (!this.wallet)
// throw new BasketError("Wallet not provided");
// return await basket.reweight(
// this.program,
// this.wallet,
// this.lamports,
// );
// }
// async rebalanceBasketToken(
// basket: Basket,
// token: PublicKey,
// updateOracles: boolean = true,
// ): Promise<TransactionSignature> {
// let oraclePriceData = await getOraclePrices(this.program, this.tokenList);
// //@ts-ignore
// let tokenSettings: TokenSettings = this.tokenList.find(x => x.tokenMint == token.toBase58());
// if (!this.wallet)
// throw new BasketError("Wallet not provided");
// if (!tokenSettings)
// throw new BasketError("Token not supported");
// let timestamp = await this.connection.getBlockTime(
// await this.connection.getSlot("finalized")
// ).catch((e) => null);
// let rebalanceInfos = basket.getRebalanceInfo(
// this.program,
// this.tokenList,
// oraclePriceData,
// timestamp ? timestamp : 2000000000,
// (this.wallet.publicKey.equals(basket.data.manager) && basket.data.activelyManaged.toNumber() == 1)
// );
// let rebalanceInfo = rebalanceInfos.find(info => info.tokenId == tokenSettings.id);
// if (!rebalanceInfo)
// throw new BasketError("Token not in composition");
// let jupSwapData = await generateJupSwapInstruction(
// rebalanceInfo,
// basket.data.rebalanceSlippage.toNumber(),
// this.connection,
// rebalanceInfo.side == Side.To ?
// oraclePriceData[rebalanceInfo.tokenId] / 10 ** this.tokenList[rebalanceInfo.tokenId].decimals :
// oraclePriceData[0] / 10 ** this.tokenList[0].decimals,
// rebalanceInfo.side == Side.From ?
// oraclePriceData[rebalanceInfo.tokenId] / 10 ** this.tokenList[rebalanceInfo.tokenId].decimals :
// oraclePriceData[0] / 10 ** this.tokenList[0].decimals,
// rebalanceInfo.tokenId == 48 ? this.tokenList[5].tokenMint : this.tokenList[1].tokenMint,
// rebalanceInfo.tokenId == 48 ? this.tokenList[5].pdaTokenAccount : this.tokenList[1].pdaTokenAccount,
// this.jupAPIkey,
// ).catch((e) => {console.log("JUP SWAP DATA", e.message); return null;})
// if (!jupSwapData)
// throw new BasketError("Couldn't load quote.");
// return await basket.rebalanceSingle(
// this.program,
// this.wallet,
// this.tokenList,
// jupSwapData,
// rebalanceInfo,
// this.lamports,
// updateOracles
// )
// }
rebalanceBasket(basket_1) {
return __awaiter(this, arguments, void 0, function* (basket, updateOracles = true) {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
let [oraclePriceData, timestamp, updateOraclesTxData] = yield Promise.all([
(0, utils_1.getOraclePrices)(this.program, this.tokenList),
(0, flashRebalance_1.getConfirmedTimestamp)(this.connection, basket),
updateOracles ? (0, instructionsBuilder_1.updateOraclesTxs)(this.swbProgram, this.wallet.publicKey, basket.getSwbFeeds(this.tokenList), this.lamports) : []
]);
let rebalanceInfos = basket.getRebalanceInfo(this.program, this.tokenList, oraclePriceData, timestamp ? timestamp : 2000000000, (this.wallet.publicKey.equals(basket.data.manager) && basket.data.activelyManaged.toNumber() == 1));
let jupSwapDatas = yield Promise.all(rebalanceInfos.map(rebalanceInfo => (0, utils_1.generateJupSwapInstruction)(rebalanceInfo, basket.data.rebalanceSlippage.toNumber(), this.connection, rebalanceInfo.side == config_1.Side.To ?
oraclePriceData[rebalanceInfo.tokenId] / 10 ** this.tokenList[rebalanceInfo.tokenId].decimals :
oraclePriceData[0] / 10 ** this.tokenList[0].decimals, rebalanceInfo.side == config_1.Side.From ?
oraclePriceData[rebalanceInfo.tokenId] / 10 ** this.tokenList[rebalanceInfo.tokenId].decimals :
oraclePriceData[0] / 10 ** this.tokenList[0].decimals, rebalanceInfo.tokenId == 48 ? this.tokenList[5].tokenMint : this.tokenList[1].tokenMint, rebalanceInfo.tokenId == 48 ? this.tokenList[5].pdaTokenAccount : this.tokenList[1].pdaTokenAccount, this.jupAPIkey).catch((e) => { console.log("JUP SWAP DATA", e.message); return null; })));
let txsToSend = updateOraclesTxData;
let updates = txsToSend.length;
yield basket.rebalanceTo(this.program, this.wallet, this.tokenList, //@ts-ignore
jupSwapDatas, rebalanceInfos, this.lookups, this.lamports).then(result => txsToSend.push(...result));
let toSwaps = txsToSend.length - updates;
if (basket.data.sellState.toNumber() == 0)
yield basket.rebalanceFrom(this.program, this.wallet, this.tokenList, //@ts-ignore
jupSwapDatas, rebalanceInfos, this.lookups, this.lamports).then(result => txsToSend.push(...result));
let blockhash = (yield this.connection.getLatestBlockhash("confirmed")).blockhash;
let signedTransactions = yield (0, utils_1.signVersionedTransactions)(this.wallet, txsToSend.map(tx => new web3_js_1.VersionedTransaction(new web3_js_1.TransactionMessage({
payerKey: tx.payerKey,
recentBlockhash: blockhash,
instructions: tx.instructions,
}).compileToV0Message(tx.lookupTables))));
let updateTxs = yield (0, utils_1.sendSignedTransactions)(this.connection, signedTransactions.slice(0, updates), 1);
let rebalanceTo = yield (0, utils_1.sendSignedTransactions)(this.connection, signedTransactions.slice(updates, updates + toSwaps), 0);
let rebalanceFrom = yield (0, utils_1.sendSignedTransactions)(this.connection, signedTransactions.slice(updates + toSwaps, signedTransactions.length), 0);
let resultTxs = [...updateTxs, ...rebalanceFrom, ...rebalanceTo];
if (resultTxs.length > 0)
yield (0, utils_1.confirmTransaction)(this.connection, resultTxs[resultTxs.length - 1]).catch(() => { });
return resultTxs;
});
}
updateAllSwbOracles() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet) {
throw new config_1.BasketError("Wallet not provided");
}
let feeds = [];
for (let i = 0; i < this.tokenList.length; i++)
if (this.tokenList[i].oracleType == "SwbOnDemand")
feeds.push(new web3_js_1.PublicKey(this.tokenList[i].oracleAccount));
let txsToSend = yield (0, instructionsBuilder_1.updateOraclesTxs)(this.swbProgram, this.wallet.publicKey, feeds, this.lamports);
return (0, flashRebalance_1.signAndSendTransactions)(txsToSend, this.connection, this.wallet, 0);
});
}
rebalanceCronJob(basket_1) {
return __awaiter(this, arguments, void 0, function* (basket, updateOracles = true, maxAllowedAccounts = 45, softCap = 5, hardCap = 5000, underTokens = 3, overTokens = 3) {
if (!this.wallet) {
throw new config_1.BasketError("Wallet not provided");
}
const [oraclePriceData, timestamp, updateOraclesTxData] = yield Promise.all([
(0, utils_1.getOraclePrices)(this.program, this.tokenList),
(0, flashRebalance_1.getConfirmedTimestamp)(this.connection, basket),
updateOracles ? (0, instructionsBuilder_1.updateOraclesTxs)(this.swbProgram, this.wallet.publicKey, basket.getSwbFeeds(this.tokenList), this.lamports) : []
]);
const forceRebalance = (0, flashRebalance_1.isForceRebalanceNeeded)(basket, this.wallet.publicKey);
const rebalanceInfos = (0, flashRebalance_1.getSortedRebalanceInfo)(basket, oraclePriceData, timestamp, this.tokenList);
const txsToSend = yield (0, flashRebalance_1.buildRebalanceTransactions)(basket, rebalanceInfos, oraclePriceData, forceRebalance, this.lookups, maxAllowedAccounts, this.wallet.publicKey, this.connection, this.program, this.tokenList, this.lamports, updateOraclesTxData, softCap, hardCap, underTokens, overTokens, this.jupAPIkey);
return (0, flashRebalance_1.signAndSendTransactions)(txsToSend, this.connection, this.wallet, updateOracles == true ? 1 : 0);
});
}
filterCronJobBaskets(allBaskets_1) {
return __awaiter(this, arguments, void 0, function* (allBaskets, softCap = 10) {
const timestamp = Date.now() / 1000;
const oraclePriceData = yield (0, utils_1.getOraclePrices)(this.program, this.tokenList);
let basketsToRebalance = [];
for (let i = 0; i < allBaskets.length; i++) {
let basket = allBaskets[i];
let possibleRebalances = 0;
if (basket.data.disableRebalance.toNumber() == 1)
continue;
let rebalanceInfos = (0, flashRebalance_1.getSortedRebalanceInfo)(basket, oraclePriceData, timestamp, this.tokenList);
for (const over of rebalanceInfos.over) {
for (const under of rebalanceInfos.under) {
if (!(0, flashRebalance_1.shouldProcessRebalance)(over, under, false))
continue;
const { from, to, tokenAmount, value } = (0, flashRebalance_1.calculateRebalanceAmounts)(over, under, oraclePriceData, this.tokenList, 10000);
if (value <= softCap)
continue;
possibleRebalances += 1;
}
}
if (possibleRebalances > 0)
basketsToRebalance.push(basket);
}
return basketsToRebalance;
});
}
buyBasket(basket, amountUsdc) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield buyState_1.BuyState.createNew(this.program, this.wallet, this.tokenList, basket, amountUsdc, this.lamports);
});
}
getOraclePrices() {
return __awaiter(this, void 0, void 0, function* () {
let oraclePrices = yield (0, utils_1.getOraclePrices)(this.program, this.tokenList);
return oraclePrices;
});
}
computeMintAmountWithMultipleTokens(basket, contribution) {
return __awaiter(this, void 0, void 0, function* () {
let oraclePrices = yield (0, utils_1.getOraclePrices)(this.program, this.tokenList);
let amount = buyState_1.BuyState.computeMintAmountWithMultipleTokens(this.tokenList, basket, contribution, oraclePrices);
return amount;
});
}
// async buyBasketWithMultipleTokens(
// basket: Basket,
// contribution: {token: PublicKey, amount: number}[],
// updateOracles: boolean = true,
// ): Promise<TransactionSignature> {
// if (!this.wallet)
// throw new BasketError("Wallet not provided");
// return await BuyState.multipleTokensDeposit(
// this.program,
// this.wallet,
// this.tokenList,
// basket,
// contribution,
// this.lamports,
// updateOracles,
// );
// }
computeMintAmountWithSingleToken(basket, token, amount) {
return __awaiter(this, void 0, void 0, function* () {
let oraclePrices = yield (0, utils_1.getOraclePrices)(this.program, this.tokenList);
let tokenSettings = this.tokenList.find(x => x.tokenMint == token.toBase58());
if (!tokenSettings)
throw new config_1.BasketError("Token not in composition");
let exp = buyState_1.BuyState.computeMintAmountWithSingleToken(this.tokenList, basket, tokenSettings, amount, oraclePrices);
return exp;
});
}
buyWithSingleToken(basket_1, token_1, amount_1) {
return __awaiter(this, arguments, void 0, function* (basket, token, amount, updateOracles = true) {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield buyState_1.BuyState.singleTokenDeposit(this.program, this.wallet, this.tokenList, basket, token, amount, this.lamports, updateOracles);
});
}
rebalanceBuyState(buyState_2) {
return __awaiter(this, arguments, void 0, function* (buyState, updateOracles = true) {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
let [oraclePriceData, updateOraclesTxData] = yield Promise.all([
yield (0, utils_1.getOraclePrices)(this.program, this.tokenList),
updateOracles ? (0, instructionsBuilder_1.updateOraclesTxs)(this.swbProgram, this.wallet.publicKey, buyState.basket.getSwbFeeds(this.tokenList), this.lamports) : []
]);
let rebalanceInfos = buyState.getBuyStateRebalanceInfo(this.tokenList);
let jupSwapDatas = yield Promise.all(rebalanceInfos.map(rebalanceInfo => (0, utils_1.generateJupSwapInstruction)(rebalanceInfo, buyState.basket.data.rebalanceSlippage.toNumber(), this.connection, rebalanceInfo.side == config_1.Side.To ?
oraclePriceData[rebalanceInfo.tokenId] / 10 ** this.tokenList[rebalanceInfo.tokenId].decimals :
oraclePriceData[0] / 10 ** this.tokenList[0].decimals, rebalanceInfo.side == config_1.Side.From ?
oraclePriceData[rebalanceInfo.tokenId] / 10 ** this.tokenList[rebalanceInfo.tokenId].decimals :
oraclePriceData[0] / 10 ** this.tokenList[0].decimals, rebalanceInfo.tokenId == 48 ? this.tokenList[5].tokenMint : this.tokenList[1].tokenMint, rebalanceInfo.tokenId == 48 ? this.tokenList[5].pdaTokenAccount : this.tokenList[1].pdaTokenAccount, this.jupAPIkey).catch((e) => { console.log("JUP SWAP DATA", e.message); return null; })));
return yield buyState.rebalanceBuyState(this.program, this.wallet, this.tokenList, //@ts-ignore
jupSwapDatas, this.lamports, updateOraclesTxData, this.lookups);
});
}
mintBasket(buyState_2) {
return __awaiter(this, arguments, void 0, function* (buyState, updateOracles = true) {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield buyState.mint(this.program, this.swbProgram, this.wallet, this.tokenList, this.lookups, this.lamports, updateOracles);
});
}
// async sellBasketToSingleToken(
// basket: Basket,
// withdrawToken: PublicKey,
// amount: number,
// updateOracles: boolean = true,
// ): Promise<TransactionSignature> {
// if (!this.wallet)
// throw new BasketError("Wallet not provided");
// return await basket.sellBasketToSingleToken(
// this.program,
// this.wallet,
// this.tokenList,
// withdrawToken,
// amount,
// this.lamports,
// updateOracles,
// )
// }
computeOutputAmountWithSingleToken(basket, withdrawToken, amount) {
return __awaiter(this, void 0, void 0, function* () {
let oraclePrices = yield (0, utils_1.getOraclePrices)(this.program, this.tokenList);
let tokenSettings = this.tokenList.find(x => x.tokenMint == withdrawToken.toBase58());
if (!tokenSettings)
throw new config_1.BasketError("Token not in composition");
let exp = basket.computeOutputAmountWithSingleToken(oraclePrices, this.tokenList, tokenSettings, amount);
return exp;
});
}
sellBasket(basket, amount, rebalance) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield basket.sell(this.program, this.wallet, amount, rebalance, this.lamports);
});
}
claimTokensFromBuyState(buyState) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield buyState.claimTokens(this.program, this.wallet, this.tokenList, this.lamports);
});
}
claimTokens(basket) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
return yield basket.claimTokens(this.program, this.wallet, this.tokenList, this.lamports);
});
}
removeDust(basket_1) {
return __awaiter(this, arguments, void 0, function* (basket, updateOracles = true) {
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
let oraclePriceData = yield (0, utils_1.getOraclePrices)(this.program, this.tokenList);
return yield basket.removeDust(this.program, this.wallet, this.tokenList, oraclePriceData, this.lamports, updateOracles);
});
}
freezeProgram() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
let transaction = new web3_js_1.Transaction();
transaction = transaction.add(yield this.program.methods.freezeProgram().accounts({
owner: (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.publicKey,
tokenList: config_1.TOKEN_LIST_ADDRESS,
systemProgram: web3_js_1.SystemProgram.programId,
}).instruction());
transaction = transaction.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: config_1.ADDITIONAL_UNITS })).add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.lamports }));
let signedTransactions = yield (0, utils_1.signTransactionsWithWallet)(this.program.provider.connection, this.wallet, [{ transaction: transaction, signers: [] }]);
return (yield (0, utils_1.sendSignedTransactions)(this.program.provider.connection, signedTransactions, 1))[0];
});
}
unfreezeProgram() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (!this.wallet)
throw new config_1.BasketError("Wallet not provided");
let transaction = new web3_js_1.Transaction();
transaction = transaction.add(yield this.program.methods.unfreezeProgram().accounts({
owner: (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.publicKey,
tokenList: config_1.TOKEN_LIST_ADDRESS,
systemProgram: web3_js_1.SystemProgram.programId,
}).instruction());
transaction = transaction.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: config_1.ADDITIONAL_UNITS })).add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.lamports }));
let signedTransactions = yield (0, utils_1.signTransactionsWithWallet)(this.program.provider.connection, this.wallet, [{ transaction: transaction, signers: [] }]);
return (yield (0, utils_1.sendSignedTransactions)(this.program.provider.connection, signedTransactions, 1))[0];
});
}
}
exports.BasketsSDK = BasketsSDK;