UNPKG

@renec-foundation/redex-sdk

Version:

Typescript SDK to interact with Orca's Whirlpool program.

127 lines (126 loc) 6.51 kB
"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()); }); }; 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;