@symmetry-hq/baskets-v2-sdk
Version:
Symmetry Baskets V2 SDK
98 lines (97 loc) • 4.42 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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateTokenPricesIxs = updateTokenPricesIxs;
// Core dependencies
const anchor_1 = require("@coral-xyz/anchor");
const basket_1 = require("../../state/basket");
const constants_1 = require("../../utils/constants");
function getJupPrices(mints) {
return __awaiter(this, void 0, void 0, function* () {
let batchSize = 100;
let prices = [];
for (let i = 0; i < mints.length; i += batchSize) {
const batch = mints.slice(i, i + batchSize);
let str = batch.map(mint => mint.toBase58()).join(",");
let result = yield fetch(`https://api.jup.ag/price/v2?ids=${str}`);
let data = (yield result.json()).data;
for (let j = 0; j < batch.length; j++) {
if (data[batch[j].toBase58()])
prices.push(data[batch[j].toBase58()].price);
else {
throw new Error("Price not found for " + batch[j].toBase58());
}
}
}
return prices;
});
}
// Helper function to create update prices instruction
function createUpdatePricesIx(program, basket, accounts, tokenPrices) {
return __awaiter(this, void 0, void 0, function* () {
while (tokenPrices.length < 25)
tokenPrices.push(new anchor_1.BN(0));
return program.methods
.updateTokenPrices(tokenPrices)
.accountsStrict({
authority: constants_1.UPDATE_PRICES_AUTHORITY,
basket,
usdcPriceOracle: constants_1.PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT,
solPriceOracle: constants_1.PYTHNET_CUSTODY_PRICE_SOL_ACCOUNT,
})
.remainingAccounts(accounts)
.instruction();
});
}
;
// Update token prices instructions
function updateTokenPricesIxs(params) {
return __awaiter(this, void 0, void 0, function* () {
// Destructure params and get basket state
const { program, basket } = params;
const basketState = yield (0, basket_1.fetchBasketState)(program, basket);
let jupPrices = yield getJupPrices(basketState.compositionMints.slice(0, basketState.numTokens));
// Initialize arrays to store instructions and remaining accounts
const ixs = [];
let remainingAccounts = [];
let tokenPrices = [];
// Process each token's oracle accounts
for (let i = 0; i < basketState.numTokens; i++) {
let num = Math.floor(jupPrices[i] * 10 ** 10);
tokenPrices.push(new anchor_1.BN(num).mul(new anchor_1.BN(100)));
// Add primary oracle
remainingAccounts.push({
pubkey: basketState.compositionOracle1[i],
isSigner: false,
isWritable: false,
});
remainingAccounts.push({
pubkey: basketState.compositionOracle2[i],
isSigner: false,
isWritable: false,
});
// Create instruction if we've hit the max accounts limit
if (remainingAccounts.length + 1 >= constants_1.MAX_PRICE_UPDATES_PER_TX) {
ixs.push(yield createUpdatePricesIx(program, basket, remainingAccounts, tokenPrices));
remainingAccounts = [];
tokenPrices = [];
}
}
// Create final instruction if there are remaining accounts
if (remainingAccounts.length > 0) {
ixs.push(yield createUpdatePricesIx(program, basket, remainingAccounts, tokenPrices));
}
return {
ixs,
luts: [basketState.lookupTable1, basketState.lookupTable2],
};
});
}