@renec-foundation/redex-sdk
Version:
Typescript SDK to interact with Orca's Whirlpool program.
127 lines (126 loc) • 6.51 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 __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addNativeMintHandlingIx = exports.resolveAtaForMints = exports.getTokenMintsFromWhirlpools = exports.TokenMintTypes = void 0;
const common_sdk_1 = require("@orca-so/common-sdk");
const spl_token_1 = require("@solana/spl-token");
const web3_js_1 = require("@solana/web3.js");
const __1 = require("..");
const spl_token_utils_1 = require("./spl-token-utils");
const txn_utils_1 = require("./txn-utils");
var TokenMintTypes;
(function (TokenMintTypes) {
TokenMintTypes["ALL"] = "ALL";
TokenMintTypes["POOL_ONLY"] = "POOL_ONLY";
TokenMintTypes["REWARD_ONLY"] = "REWARDS_ONLY";
})(TokenMintTypes = exports.TokenMintTypes || (exports.TokenMintTypes = {}));
/**
* Fetch a list of affliated tokens from a list of whirlpools
*
* SOL tokens does not use the ATA program and therefore not handled.
* @param whirlpoolDatas An array of whirlpoolData (from fetcher.listPools)
* @param mintTypes The set of mints to collect from these whirlpools
* @returns All the whirlpool, reward token mints in the given set of whirlpools
*/
function getTokenMintsFromWhirlpools(whirlpoolDatas, mintTypes = TokenMintTypes.ALL) {
let hasNativeMint = false;
const mints = Array.from(whirlpoolDatas.reduce((accu, whirlpoolData) => {
if (whirlpoolData) {
if (mintTypes === TokenMintTypes.ALL || mintTypes === TokenMintTypes.POOL_ONLY) {
const { tokenMintA, tokenMintB } = whirlpoolData;
// TODO: Once we move to sync-native for wSOL wrapping, we can simplify and use wSOL ATA instead of a custom token account.
if (!common_sdk_1.TokenUtil.isNativeMint(tokenMintA)) {
accu.add(tokenMintA.toBase58());
}
else {
hasNativeMint = true;
}
if (!common_sdk_1.TokenUtil.isNativeMint(tokenMintB)) {
accu.add(tokenMintB.toBase58());
}
else {
hasNativeMint = true;
}
}
if (mintTypes === TokenMintTypes.ALL || mintTypes === TokenMintTypes.REWARD_ONLY) {
const rewardInfos = whirlpoolData.rewardInfos;
rewardInfos.forEach((reward) => {
if (common_sdk_1.TokenUtil.isNativeMint(reward.mint)) {
hasNativeMint = true;
}
if (__1.PoolUtil.isRewardInitialized(reward)) {
accu.add(reward.mint.toBase58());
}
});
}
}
return accu;
}, new Set())).map((mint) => new web3_js_1.PublicKey(mint));
return {
mintMap: mints,
hasNativeMint,
};
}
exports.getTokenMintsFromWhirlpools = getTokenMintsFromWhirlpools;
/**
* Build instructions to resolve ATAs (Associated Tokens Addresses) for affliated tokens in a list of Whirlpools.
* Affliated tokens are tokens that are part of the trade pair or reward in a Whirlpool.
*
* @param ctx - WhirlpoolContext object for the current environment.
* @param params - ResolveAtaInstructionParams
* @returns a ResolvedTokenAddressesIxSet containing the derived ATA addresses & ix set to initialize the accounts.
*/
function resolveAtaForMints(ctx, params) {
return __awaiter(this, void 0, void 0, function* () {
const { mints, receiver, payer, accountExemption } = params;
const receiverKey = receiver !== null && receiver !== void 0 ? receiver : ctx.wallet.publicKey;
const payerKey = payer !== null && payer !== void 0 ? payer : ctx.wallet.publicKey;
const resolvedAtaResults = yield (0, common_sdk_1.resolveOrCreateATAs)(ctx.connection, receiverKey, mints.map((tokenMint) => {
return { tokenMint };
}), () => __awaiter(this, void 0, void 0, function* () { return accountExemption; }), payerKey);
// Convert the results back into the specified format
const { resolveAtaIxs, resolvedAtas } = resolvedAtaResults.reduce((accu, curr) => {
const { address } = curr, ix = __rest(curr, ["address"]);
accu.resolvedAtas.push(address);
// TODO: common-sdk needs to have an easier way to check for empty instruction
if (ix.instructions.length) {
accu.resolveAtaIxs.push(ix);
}
return accu;
}, { resolvedAtas: [], resolveAtaIxs: [] });
const affliatedTokenAtaMap = (0, txn_utils_1.convertListToMap)(resolvedAtas, mints.map((mint) => mint.toBase58()));
return {
ataTokenAddresses: affliatedTokenAtaMap,
resolveAtaIxs,
};
});
}
exports.resolveAtaForMints = resolveAtaForMints;
/**
* Add native WSOL mint handling to a transaction builder.
*/
function addNativeMintHandlingIx(txBuilder, affliatedTokenAtaMap, destinationWallet, accountExemption) {
let _a = (0, spl_token_utils_1.createWSOLAccountInstructions)(destinationWallet, common_sdk_1.ZERO, accountExemption), { address: wSOLAta } = _a, resolveWSolIx = __rest(_a, ["address"]);
affliatedTokenAtaMap[spl_token_1.NATIVE_MINT.toBase58()] = wSOLAta;
txBuilder.prependInstruction(resolveWSolIx);
}
exports.addNativeMintHandlingIx = addNativeMintHandlingIx;