@symmetry-hq/baskets-sdk
Version:
Software Development Kit for interacting with Symmetry Baskets Program
244 lines (225 loc) • 9.12 kB
text/typescript
import { Connection, Keypair, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
import { BASKETS_LOOKUP_TABLE_1, BASKETS_LOOKUP_TABLE_2, BASKETS_PROGRAM_ID, SimpleCreateParams, SimpleEditParams, SWB_PID, TransactionToSend } from "./config";
import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor";
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
import { BasketsIDL, IDL } from "./basketsIDL";
import { fetchTokenList, getOraclePrices } from "./utils";
import { Basket } from "./basketState";
import { BuyState } from "./buyState";
import { buildBuyBasketIx, buildBuyBasketWithMultipleTokensIx, buildBuyBasketWithSingleTokenIx, buildClaimTokensFromBuyStateIxs, buildClaimTokensFromSellStateIxs, buildCloseBasketIx, buildCreateBasketIx, buildEditBasketIx, buildEditManagetIx, buildMintFromBuyStateIx, buildSellBasketIx, buildSellBasketToSingleTokenIx, buildSetMetadataIx, updateOraclesTxs } from "./instructionsBuilder";
import { buildRebalanceTransactions, getConfirmedTimestamp, getLookupTableAccount, getSortedRebalanceInfo, isForceRebalanceNeeded, signAndSendTransactions } from "./flashRebalance";
async function loadSwbProgram(connection: Connection) {
let provider = new AnchorProvider(
connection,
new NodeWallet(Keypair.generate()),
{
skipPreflight: true,
preflightCommitment: "recent",
commitment: "processed",
}
);
let swbIDL = (await Program.fetchIdl(SWB_PID, provider))!;
return new Program(swbIDL, provider);
}
function loadProgram(connection: Connection): Program<BasketsIDL> {
let provider = new AnchorProvider(
connection,
new NodeWallet(Keypair.generate()),
{
skipPreflight: true,
preflightCommitment: "recent",
commitment: "processed",
}
);
let program = new Program<BasketsIDL>(IDL, provider);
return program;
}
export async function createBasketIx(
connection: Connection,
basketParams: SimpleCreateParams,
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
return await buildCreateBasketIx(program, tokenList, basketParams);
}
export async function editBasketIx(
connection: Connection,
basket: PublicKey,
basketParams: SimpleEditParams,
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildEditBasketIx(program, tokenList, basketObj, basketParams);
}
export async function editManagerIx(
connection: Connection,
basket: PublicKey,
newManager: PublicKey
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildEditManagetIx(program, basketObj, newManager);
}
export async function closeBasketIx(
connection: Connection,
basket: PublicKey
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let basketState = await Basket.loadFromPubkey(program, basket);
return await buildCloseBasketIx(program, basketState);
}
export async function setMetadataIx(
connection: Connection,
basket: PublicKey,
symbol: string = "",
name: string = "",
uri: string = "",
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildSetMetadataIx(program, basketObj, {symbol: symbol, name: name, uri: uri});
}
export async function buyBasketIx(
connection: Connection,
user: PublicKey,
basket: PublicKey,
amount: number,
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildBuyBasketIx(program, tokenList, user, basketObj, amount);
}
export async function claimTokensFromBuyStateIxs(
connection: Connection,
user: PublicKey,
buyState: PublicKey,
): Promise<TransactionInstruction[]> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let buyStateObj = await BuyState.loadFromPubkey(program, buyState);
let basketObj = buyStateObj.basket;
return await buildClaimTokensFromBuyStateIxs(program, tokenList, user, basketObj, buyStateObj);
}
export async function mintFromBuyStateIx(
connection: Connection,
user: PublicKey,
buyState: PublicKey
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let buyStateObj = await BuyState.loadFromPubkey(program, buyState);
let basketObj = buyStateObj.basket;
return await buildMintFromBuyStateIx(program, tokenList, user, basketObj, buyStateObj);
}
export async function buyBasketWithMultipleTokensIx(
connection: Connection,
user: PublicKey,
basket: PublicKey,
contribution: {token: PublicKey, amount: number}[],
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildBuyBasketWithMultipleTokensIx(program, tokenList, user, basketObj, contribution);
}
export async function buyBasketWithSingleTokenIx(
connection: Connection,
user: PublicKey,
basket: PublicKey,
contributionToken: PublicKey,
contributionAmount: number
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildBuyBasketWithSingleTokenIx(program, tokenList, user, basketObj, contributionToken, contributionAmount);
}
export async function sellBasketToSingleTokenIx(
connection: Connection,
user: PublicKey,
basket: PublicKey,
withdrawToken: PublicKey,
amount: number,
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildSellBasketToSingleTokenIx(program, tokenList, user, basketObj, withdrawToken, amount);
}
export async function sellBasketIx(
connection: Connection,
user: PublicKey,
basket: PublicKey,
amount: number,
rebalance: number,
): Promise<TransactionInstruction> {
let program = loadProgram(connection);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildSellBasketIx(program, user, basketObj, amount, rebalance);
}
export async function claimTokensFromSellStateIxs(
connection: Connection,
user: PublicKey,
basket: PublicKey,
): Promise<TransactionInstruction[]> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let basketObj = await Basket.loadFromPubkey(program, basket);
return await buildClaimTokensFromSellStateIxs(program, tokenList, user, basketObj);
}
export async function cronRebalanceBasketIxs(
connection: Connection,
user: PublicKey,
basketAddress: PublicKey,
jupAPIkey: string = "https://quote-api.jup.ag/v6/",
lamports: number = 50000,
updateOracles: boolean = true,
maxAllowedAccounts: number = 45,
softCap: number = 5,
hardCap: number = 5000,
underTokens: number = 3,
overTokens: number = 3,
): Promise<TransactionToSend[]> {
let program = loadProgram(connection);
let tokenList = await fetchTokenList(program);
let basket = await Basket.loadFromPubkey(program, basketAddress);
let swbProgram = await loadSwbProgram(connection);
let lookups = await Promise.all([
getLookupTableAccount(program.provider.connection, BASKETS_LOOKUP_TABLE_1),
getLookupTableAccount(program.provider.connection, BASKETS_LOOKUP_TABLE_2)
]);
const [oraclePriceData, timestamp, updateOraclesTxData] = await Promise.all([
getOraclePrices(program, tokenList),
getConfirmedTimestamp(connection, basket),
updateOracles ? updateOraclesTxs(
swbProgram,
user,
basket.getSwbFeeds(tokenList),
50000,
) : []
]);
const forceRebalance = isForceRebalanceNeeded(basket, user);
const rebalanceInfos = getSortedRebalanceInfo(basket, oraclePriceData, timestamp, tokenList);
const txsToSend = await buildRebalanceTransactions(
basket,
rebalanceInfos,
oraclePriceData,
forceRebalance,
lookups,
maxAllowedAccounts,
user,
connection,
program,
tokenList,
lamports,
updateOraclesTxData,
softCap,
hardCap,
underTokens,
overTokens,
jupAPIkey,
);
return txsToSend;
}