@orca-so/whirlpools-sdk
Advanced tools
Comparing version 0.8.1 to 0.8.2
@@ -55,3 +55,2 @@ import { TransactionBuilder } from "@orca-so/common-sdk"; | ||
* @returns A set of transaction-builders to resolve ATA for affliated tokens, collect fee & rewards for all positions. | ||
* The first transaction should always be processed as it contains all the resolve ATA instructions to receive tokens. | ||
*/ | ||
@@ -58,0 +57,0 @@ export declare function collectAllForPositionAddressesTxns(ctx: WhirlpoolContext, params: CollectAllPositionAddressParams, refresh?: boolean): Promise<TransactionBuilder[]>; |
@@ -42,3 +42,2 @@ "use strict"; | ||
* @returns A set of transaction-builders to resolve ATA for affliated tokens, collect fee & rewards for all positions. | ||
* The first transaction should always be processed as it contains all the resolve ATA instructions to receive tokens. | ||
*/ | ||
@@ -81,31 +80,24 @@ function collectAllForPositionAddressesTxns(ctx, params, refresh = false) { | ||
const whirlpools = (0, txn_utils_1.convertListToMap)(whirlpoolDatas, whirlpoolAddrs); | ||
const allMints = (0, whirlpool_ata_utils_1.getTokenMintsFromWhirlpools)(whirlpoolDatas); | ||
const accountExemption = yield ctx.fetcher.getAccountRentExempt(); | ||
const { ataTokenAddresses: affliatedTokenAtaMap, resolveAtaIxs } = yield (0, whirlpool_ata_utils_1.resolveAtaForMints)(ctx, { | ||
mints: (0, whirlpool_ata_utils_1.getTokenMintsFromWhirlpools)(whirlpoolDatas).mintMap, | ||
accountExemption, | ||
receiver: receiverKey, | ||
payer: payerKey, | ||
}); | ||
// resolvedAtas[mint] => Instruction & { address } | ||
// if already ATA exists, Instruction will be EMPTY_INSTRUCTION | ||
const resolvedAtas = (0, txn_utils_1.convertListToMap)(yield (0, common_sdk_1.resolveOrCreateATAs)(ctx.connection, receiverKey, allMints.mintMap.map((tokenMint) => ({ tokenMint })), () => __awaiter(this, void 0, void 0, function* () { return accountExemption; }), payerKey, true // CreateIdempotent | ||
), allMints.mintMap.map((mint) => mint.toBase58())); | ||
const latestBlockhash = yield ctx.connection.getLatestBlockhash("singleGossip"); | ||
const txBuilders = []; | ||
let pendingTxBuilder = new common_sdk_1.TransactionBuilder(ctx.connection, ctx.wallet).addInstructions(resolveAtaIxs); | ||
let pendingTxBuilderTxSize = yield pendingTxBuilder.txnSize({ latestBlockhash }); | ||
let posIndex = 0; | ||
let pendingTxBuilder = null; | ||
let touchedMints = null; | ||
let reattempt = false; | ||
while (posIndex < positionList.length) { | ||
if (!pendingTxBuilder || !touchedMints) { | ||
pendingTxBuilder = new common_sdk_1.TransactionBuilder(ctx.connection, ctx.wallet); | ||
touchedMints = new Set(); | ||
resolvedAtas[spl_token_1.NATIVE_MINT.toBase58()] = (0, spl_token_utils_1.createWSOLAccountInstructions)(receiverKey, common_sdk_1.ZERO, accountExemption); | ||
} | ||
// Build collect instructions | ||
const [positionAddr, position] = positionList[posIndex]; | ||
let positionTxBuilder = new common_sdk_1.TransactionBuilder(ctx.connection, ctx.wallet); | ||
const { whirlpool: whirlpoolKey, positionMint } = position; | ||
const whirlpool = whirlpools[whirlpoolKey.toBase58()]; | ||
if (!whirlpool) { | ||
throw new Error(`Unable to process positionMint ${positionMint} - unable to derive whirlpool ${whirlpoolKey.toBase58()}`); | ||
} | ||
const posHandlesNativeMint = common_sdk_1.TokenUtil.isNativeMint(whirlpool.tokenMintA) || common_sdk_1.TokenUtil.isNativeMint(whirlpool.tokenMintB); | ||
const txBuilderHasNativeMint = !!affliatedTokenAtaMap[spl_token_1.NATIVE_MINT.toBase58()]; | ||
// Add NATIVE_MINT token account creation to this transaction if position requires NATIVE_MINT handling. | ||
if (posHandlesNativeMint && !txBuilderHasNativeMint) { | ||
(0, whirlpool_ata_utils_1.addNativeMintHandlingIx)(positionTxBuilder, affliatedTokenAtaMap, receiverKey, accountExemption); | ||
} | ||
// Build position instructions | ||
const collectIxForPosition = constructCollectPositionIx(ctx, new web3_js_1.PublicKey(positionAddr), position, whirlpools, positionOwnerKey, positionAuthorityKey, affliatedTokenAtaMap); | ||
const collectIxForPosition = constructCollectIxForPosition(ctx, new web3_js_1.PublicKey(positionAddr), position, whirlpools, positionOwnerKey, positionAuthorityKey, resolvedAtas, touchedMints); | ||
const positionTxBuilder = new common_sdk_1.TransactionBuilder(ctx.connection, ctx.wallet); | ||
positionTxBuilder.addInstructions(collectIxForPosition); | ||
@@ -115,6 +107,5 @@ // Attempt to push the new instructions into the pending builder | ||
// Create a builder and reattempt if the current one is full. | ||
const incrementTxSize = yield positionTxBuilder.txnSize({ latestBlockhash }); | ||
if (pendingTxBuilderTxSize + incrementTxSize < web3_js_1.PACKET_DATA_SIZE) { | ||
const mergeable = yield (0, txn_utils_1.checkMergedTransactionSizeIsValid)(ctx, [pendingTxBuilder, positionTxBuilder], latestBlockhash); | ||
if (mergeable) { | ||
pendingTxBuilder.addInstruction(positionTxBuilder.compressIx(false)); | ||
pendingTxBuilderTxSize = pendingTxBuilderTxSize + incrementTxSize; | ||
posIndex += 1; | ||
@@ -128,9 +119,10 @@ reattempt = false; | ||
txBuilders.push(pendingTxBuilder); | ||
delete affliatedTokenAtaMap[spl_token_1.NATIVE_MINT.toBase58()]; | ||
pendingTxBuilder = new common_sdk_1.TransactionBuilder(ctx.connection, ctx.provider.wallet); | ||
pendingTxBuilderTxSize = 0; | ||
pendingTxBuilder = null; | ||
touchedMints = null; | ||
reattempt = true; | ||
} | ||
} | ||
txBuilders.push(pendingTxBuilder); | ||
if (pendingTxBuilder) { | ||
txBuilders.push(pendingTxBuilder); | ||
} | ||
return txBuilders; | ||
@@ -141,3 +133,3 @@ }); | ||
// TODO: Once individual collect ix for positions is implemented, maybe migrate over if it can take custom ATA? | ||
const constructCollectPositionIx = (ctx, positionKey, position, whirlpools, positionOwner, positionAuthority, affliatedTokenAtaMap) => { | ||
const constructCollectIxForPosition = (ctx, positionKey, position, whirlpools, positionOwner, positionAuthority, resolvedAtas, touchedMints) => { | ||
const ixForPosition = []; | ||
@@ -150,2 +142,5 @@ const { whirlpool: whirlpoolKey, liquidity, tickLowerIndex, tickUpperIndex, positionMint, rewardInfos: positionRewardInfos, } = position; | ||
const { tickSpacing } = whirlpool; | ||
const mintA = whirlpool.tokenMintA.toBase58(); | ||
const mintB = whirlpool.tokenMintB.toBase58(); | ||
const positionTokenAccount = (0, spl_token_utils_1.getAssociatedTokenAddressSync)(positionMint.toBase58(), positionOwner.toBase58()); | ||
// Update fee and reward values if necessary | ||
@@ -161,3 +156,10 @@ if (!liquidity.eq(common_sdk_1.ZERO)) { | ||
// Collect Fee | ||
const positionTokenAccount = (0, spl_token_utils_1.getAssociatedTokenAddressSync)(positionMint.toBase58(), positionOwner.toBase58()); | ||
if (!touchedMints.has(mintA)) { | ||
ixForPosition.push(resolvedAtas[mintA]); | ||
touchedMints.add(mintA); | ||
} | ||
if (!touchedMints.has(mintB)) { | ||
ixForPosition.push(resolvedAtas[mintB]); | ||
touchedMints.add(mintB); | ||
} | ||
ixForPosition.push(ix_1.WhirlpoolIx.collectFeesIx(ctx.program, { | ||
@@ -168,4 +170,4 @@ whirlpool: whirlpoolKey, | ||
positionTokenAccount, | ||
tokenOwnerAccountA: affliatedTokenAtaMap[whirlpool.tokenMintA.toBase58()], | ||
tokenOwnerAccountB: affliatedTokenAtaMap[whirlpool.tokenMintB.toBase58()], | ||
tokenOwnerAccountA: resolvedAtas[mintA].address, | ||
tokenOwnerAccountB: resolvedAtas[mintB].address, | ||
tokenVaultA: whirlpool.tokenVaultA, | ||
@@ -179,2 +181,7 @@ tokenVaultB: whirlpool.tokenVaultB, | ||
if (public_1.PoolUtil.isRewardInitialized(rewardInfo)) { | ||
const mintReward = rewardInfo.mint.toBase58(); | ||
if (!touchedMints.has(mintReward)) { | ||
ixForPosition.push(resolvedAtas[mintReward]); | ||
touchedMints.add(mintReward); | ||
} | ||
ixForPosition.push(ix_1.WhirlpoolIx.collectRewardIx(ctx.program, { | ||
@@ -186,3 +193,3 @@ whirlpool: whirlpoolKey, | ||
rewardIndex: index, | ||
rewardOwnerAccount: affliatedTokenAtaMap[rewardInfo.mint.toBase58()], | ||
rewardOwnerAccount: resolvedAtas[mintReward].address, | ||
rewardVault: rewardInfo.vault, | ||
@@ -189,0 +196,0 @@ })); |
@@ -0,1 +1,7 @@ | ||
import { TransactionBuilder } from "@orca-so/common-sdk"; | ||
import { WhirlpoolContext } from ".."; | ||
export declare function convertListToMap<T>(fetchedData: T[], addresses: string[]): Record<string, T>; | ||
export declare function checkMergedTransactionSizeIsValid(ctx: WhirlpoolContext, builders: TransactionBuilder[], latestBlockhash: Readonly<{ | ||
blockhash: string; | ||
lastValidBlockHeight: number; | ||
}>): Promise<boolean>; |
"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()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.convertListToMap = void 0; | ||
exports.checkMergedTransactionSizeIsValid = exports.convertListToMap = void 0; | ||
const common_sdk_1 = require("@orca-so/common-sdk"); | ||
; | ||
function convertListToMap(fetchedData, addresses) { | ||
@@ -15,1 +26,15 @@ const result = {}; | ||
exports.convertListToMap = convertListToMap; | ||
function checkMergedTransactionSizeIsValid(ctx, builders, latestBlockhash) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const merged = new common_sdk_1.TransactionBuilder(ctx.connection, ctx.wallet); | ||
builders.forEach((builder) => merged.addInstruction(builder.compressIx(true))); | ||
try { | ||
const size = yield merged.txnSize({ latestBlockhash }); // throws if txnSize is too large | ||
return true; | ||
} | ||
catch (e) { | ||
return false; | ||
} | ||
}); | ||
} | ||
exports.checkMergedTransactionSizeIsValid = checkMergedTransactionSizeIsValid; |
@@ -60,3 +60,2 @@ import { Percentage, TransactionBuilder } from "@orca-so/common-sdk"; | ||
* @returns A set of transaction-builders to resolve ATA for affliated tokens, collect fee & rewards for all positions. | ||
* The first transaction should always be processed as it contains all the resolve ATA instructions to receive tokens. | ||
*/ | ||
@@ -63,0 +62,0 @@ collectFeesAndRewardsForPositions: (positionAddresses: Address[], refresh?: boolean) => Promise<TransactionBuilder[]>; |
{ | ||
"name": "@orca-so/whirlpools-sdk", | ||
"version": "0.8.1", | ||
"version": "0.8.2", | ||
"description": "Typescript SDK to interact with Orca's Whirlpool program.", | ||
@@ -10,3 +10,3 @@ "license": "Apache-2.0", | ||
"@metaplex-foundation/mpl-token-metadata": "1.2.5", | ||
"@orca-so/common-sdk": "^0.1.9", | ||
"@orca-so/common-sdk": "^0.1.10", | ||
"@project-serum/anchor": "~0.25.0", | ||
@@ -13,0 +13,0 @@ "@solana/spl-token": "^0.1.8", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
653253
156
14216
1
Updated@orca-so/common-sdk@^0.1.10