UNPKG

@renec-foundation/redex-sdk

Version:

Typescript SDK to interact with Orca's Whirlpool program.

315 lines (314 loc) 19.6 kB
import { Percentage, TransactionBuilder } from "@orca-so/common-sdk"; import { Address } from "@project-serum/anchor"; import { PublicKey } from "@solana/web3.js"; import { WhirlpoolContext } from "./context"; import { DevFeeSwapInput, SwapInput } from "./instructions"; import { AccountFetcher } from "./network/public"; import { DecreaseLiquidityInput, IncreaseLiquidityInput, PositionData, TickData, WhirlpoolData } from "./types/public"; import { TokenAccountInfo, TokenInfo, WhirlpoolRewardInfo } from "./types/public/client-types"; /** * Helper class to help interact with Whirlpool Accounts with a simpler interface. * * @category WhirlpoolClient */ export interface WhirlpoolClient { /** * Get this client's WhirlpoolContext object * @return a WhirlpoolContext object */ getContext: () => WhirlpoolContext; /** * Get an AccountFetcher to fetch Whirlpool accounts * @return an AccountFetcher instance */ getFetcher: () => AccountFetcher; /** * Get a Whirlpool object to interact with the Whirlpool account at the given address. * @param poolAddress the address of the Whirlpool account * @param refresh true to always request newest data from chain with this request * @return a Whirlpool object to interact with */ getPool: (poolAddress: Address, refresh?: boolean) => Promise<Whirlpool>; /** * Get a list of Whirlpool objects matching the provided list of addresses. * @param poolAddresses the addresses of the Whirlpool accounts * @param refresh true to always request newest data from chain with this request * @return a list of Whirlpool objects to interact with */ getPools: (poolAddresses: Address[], refresh?: boolean) => Promise<Whirlpool[]>; /** * Gets all positions of the given owner. * @param {PublicKey} owner - the owner to get positions for. * @param {boolean} [refresh=false] - whether to refresh the positions from the blockchain. * @returns A promise that resolves to an array of positions. */ getAllPositionsOf: (owner: PublicKey, refresh?: boolean) => Promise<Position[]>; /** * Get a Position object to interact with the Position account at the given address. * @param positionAddress the address of the Position account * @param refresh true to always request newest data from chain with this request * @return a Position object to interact with. * @throws error when address does not return a Position account. */ getPosition: (positionAddress: Address, refresh?: boolean) => Promise<Position>; /** * Get a list of Position objects to interact with the Position account at the given addresses. * @param positionAddress the addresses of the Position accounts * @param refresh true to always request newest data from chain with this request * @return a Record object between account address and Position. If an address is not a Position account, it will be null. */ getPositions: (positionAddresses: Address[], refresh?: boolean) => Promise<Record<string, Position | null>>; /** * Collect all fees and rewards from a list of positions. * @experimental * @param positionAddress the addresses of the Position accounts to collect fee & rewards from. * @param refresh true to always request newest data from chain with this request * @returns A set of transaction-builders to resolve ATA for affliated tokens, collect fee & rewards for all positions. */ collectFeesAndRewardsForPositions: (positionAddresses: Address[], refresh?: boolean) => Promise<TransactionBuilder[]>; /** * Create a Whirlpool account for a group of token A, token B and tick spacing * @param whirlpoolConfig the address of the whirlpool config * @param tokenMintA the address of the token A * @param tokenMintB the address of the token B * @param tickSpacing the space between two ticks in the tick array * @param initialTick the initial tick that the pool is set to (derived from initial price) * @param funder the account to debit SOL from to fund the creation of the account(s) * @return `poolKey`: The public key of the newly created whirlpool account. `tx`: The transaction containing instructions for the on-chain operations. * @throws error when the tokens are not in the canonical byte-based ordering. To resolve this, invert the token order and the initialTick (see `TickUtil.invertTick()`, `PriceMath.invertSqrtPriceX64()`, or `PriceMath.invertPrice()`). */ createPool: (whirlpoolsConfig: Address, tokenMintA: Address, tokenMintB: Address, tickSpacing: number, initialTick: number, funder: Address) => Promise<{ poolKey: PublicKey; tx: TransactionBuilder; }>; /** * Collect protocol fees from a list of pools * @param poolAddresses the addresses of the Whirlpool accounts to collect protocol fees from * @returns A transaction builder to resolve ATA for tokenA and tokenB if needed, and collect protocol fees for all pools */ collectProtocolFeesForPools: (poolAddresses: Address[]) => Promise<TransactionBuilder>; } /** * Construct a WhirlpoolClient instance to help interact with Whirlpools accounts with. * * @category WhirlpoolClient * @param ctx - WhirlpoolContext object * @returns a WhirlpoolClient instance to help with interacting with Whirlpools accounts. */ export declare function buildWhirlpoolClient(ctx: WhirlpoolContext): WhirlpoolClient; /** * Helper class to interact with a Whirlpool account and build complex transactions. * @category WhirlpoolClient */ export interface Whirlpool { /** * Return the address for this Whirlpool instance. * @return the PublicKey for this Whirlpool instance. */ getAddress: () => PublicKey; /** * Return the most recently fetched Whirlpool account data. * @return most recently fetched WhirlpoolData for this address. */ getData: () => WhirlpoolData; /** * Fetch and return the most recently fetched Whirlpool account data. * @return the most up to date WhirlpoolData for this address. */ refreshData: () => Promise<WhirlpoolData>; /** * Get the TokenInfo for token A of this pool. * @return TokenInfo for token A */ getTokenAInfo: () => TokenInfo; /** * Get the TokenInfo for token B of this pool. * @return TokenInfo for token B */ getTokenBInfo: () => TokenInfo; /** * Get the TokenAccountInfo for token vault A of this pool. * @return TokenAccountInfo for token vault A */ getTokenVaultAInfo: () => TokenAccountInfo; /** * Get the TokenAccountInfo for token vault B of this pool. * @return TokenAccountInfo for token vault B */ getTokenVaultBInfo: () => TokenAccountInfo; /** * Get the WhirlpoolRewardInfos for this pool. * @return Array of 3 WhirlpoolRewardInfos. However, not all of them may be initialized. Use the initialized field on WhirlpoolRewardInfo to check if the reward is active. */ getRewardInfos: () => WhirlpoolRewardInfo[]; /** * Initialize a set of tick-arrays that encompasses the provided ticks. * * If `funder` is provided, the funder wallet has to sign this transaction. * * @param ticks - A group of ticks that define the desired tick-arrays to initialize. If the tick's array has been initialized, it will be ignored. * @param funder - the wallet that will fund the cost needed to initialize the position. If null, the WhirlpoolContext wallet is used. * @param refresh - whether this operation will fetch for the latest accounts if a cache version is available. * @return a transaction that will initialize the defined tick-arrays if executed. Return null if all of the tick's arrays are initialized. */ initTickArrayForTicks: (ticks: number[], funder?: Address, refresh?: boolean) => Promise<TransactionBuilder | null>; /** * Open and fund a position on this Whirlpool. * * User has to ensure the TickArray for tickLower and tickUpper has been initialized prior to calling this function. * * If `wallet` or `funder` is provided, those wallets have to sign this transaction. * * @param tickLower - the tick index for the lower bound of this position * @param tickUpper - the tick index for the upper bound of this position * @param liquidityInput - an InputLiquidityInput type to define the desired liquidity amount to deposit * @param wallet - the wallet to withdraw tokens to deposit into the position and house the position token. If null, the WhirlpoolContext wallet is used. * @param funder - the wallet that will fund the cost needed to initialize the position. If null, the WhirlpoolContext wallet is used. * @return `positionMint` - the position to be created. `tx` - The transaction containing the instructions to perform the operation on chain. */ openPosition: (tickLower: number, tickUpper: number, liquidityInput: IncreaseLiquidityInput, wallet?: Address, funder?: Address) => Promise<{ positionMint: PublicKey; tx: TransactionBuilder; }>; /** * Open and fund a position with meta-data on this Whirlpool. * * User has to ensure the TickArray for tickLower and tickUpper has been initialized prior to calling this function. * * If `wallet` or `funder` is provided, the wallet owners have to sign this transaction. * * @param tickLower - the tick index for the lower bound of this position * @param tickUpper - the tick index for the upper bound of this position * @param liquidityInput - input that defines the desired liquidity amount and maximum tokens willing to be to deposited. * @param wallet - the wallet to withdraw tokens to deposit into the position and house the position token. If null, the WhirlpoolContext wallet is used. * @param funder - the wallet that will fund the cost needed to initialize the position. If null, the WhirlpoolContext wallet is used. * @return `positionMint` - the position to be created. `tx` - The transaction containing the instructions to perform the operation on chain. */ openPositionWithMetadata: (tickLower: number, tickUpper: number, liquidityInput: IncreaseLiquidityInput, wallet?: Address, funder?: Address) => Promise<{ positionMint: PublicKey; tx: TransactionBuilder; }>; /** * Withdraw all tokens from a position, close the account and burn the position token. * * Users have to collect all fees and rewards from this position prior to closing the account. * * If `positionWallet`, `payer` is provided, the wallet owner has to sign this transaction. * * @param positionAddress - The address of the position account. * @param slippageTolerance - The amount of slippage the caller is willing to accept when withdrawing liquidity. * @param destinationWallet - The wallet that the tokens withdrawn and rent lamports will be sent to. If null, the WhirlpoolContext wallet is used. * @param positionWallet - The wallet that houses the position token that corresponds to this position address. If null, the WhirlpoolContext wallet is used. * @param payer - the wallet that will fund the cost needed to initialize the token ATA accounts. If null, the WhirlpoolContext wallet is used. */ closePosition: (positionAddress: Address, slippageTolerance: Percentage, destinationWallet?: Address, positionWallet?: Address, payer?: Address) => Promise<TransactionBuilder[]>; /** * Perform a swap between tokenA and tokenB on this pool. * * @param input - A quote on the desired tokenIn and tokenOut for this swap. Use {@link swapQuoteWithParams} or other swap quote functions to generate this object. * @param wallet - The wallet that tokens will be withdrawn and deposit into. If null, the WhirlpoolContext wallet is used. * @return a transaction that will perform the swap once executed. */ swap: (input: SwapInput, wallet?: PublicKey) => Promise<TransactionBuilder>; /** * Collect a developer fee and perform a swap between tokenA and tokenB on this pool. * * @param input - A quote on the desired tokenIn and tokenOut for this swap. Use {@link swapQuoteByInputTokenWithDevFees} to generate this object. * @param devFeeWallet - The wallet that developer fees will be deposited into. * @param wallet - The wallet that swap tokens will be withdrawn and deposit into. If null, the WhirlpoolContext wallet is used. * @param payer - The wallet that will fund the cost needed to initialize the dev wallet token ATA accounts. If null, the WhirlpoolContext wallet is used. * @return a transaction that will perform the swap once executed. */ swapWithDevFees: (input: DevFeeSwapInput, devFeeWallet: PublicKey, wallet?: PublicKey, payer?: PublicKey) => Promise<TransactionBuilder>; } /** * Helper class to interact with a Position account and build complex transactions. * @category WhirlpoolClient */ export interface Position { /** * Return the address for this Whirlpool instance. * @return the PublicKey for this Whirlpool instance. */ getAddress: () => PublicKey; /** * Return the most recently fetched Position account data. * @return most recently fetched PositionData for this address. */ getData: () => PositionData; /** * Return the most recently fetched Whirlpool account data for this position. * @return most recently fetched WhirlpoolData for this position. */ getWhirlpoolData: () => WhirlpoolData; /** * Return the most recently fetched TickData account data for this position's lower tick. * @return most recently fetched TickData for this position's lower tick. */ getLowerTickData: () => TickData; /** * Return the most recently fetched TickData account data for this position's upper tick. * @return most recently fetched TickData for this position's upper tick. */ getUpperTickData: () => TickData; /** * Fetch and return the most recently fetched Position account data. * @return the most up to date PositionData for this address. */ refreshData: () => Promise<PositionData>; /** * Deposit additional tokens into this postiion. * The wallet must contain the position token and the necessary token A & B to complete the deposit. * If `positionWallet` and `wallet` is provided, the wallet owners have to sign this transaction. * * @param liquidityInput - input that defines the desired liquidity amount and maximum tokens willing to be to deposited. * @param resolveATA - if true, add instructions to create associated token accounts for tokenA,B for the destinationWallet if necessary. (RPC call required) * @param wallet - to withdraw tokens to deposit into the position. If null, the WhirlpoolContext wallet is used. * @param positionWallet - the wallet to that houses the position token. If null, the WhirlpoolContext wallet is used. * @param ataPayer - wallet that will fund the creation of the new associated token accounts * @return the transaction that will deposit the tokens into the position when executed. */ increaseLiquidity: (liquidityInput: IncreaseLiquidityInput, resolveATA?: boolean, wallet?: Address, positionWallet?: Address, ataPayer?: Address) => Promise<TransactionBuilder>; /** * Withdraw liquidity from this position. * * If `positionWallet` is provided, the wallet owners have to sign this transaction. * * @param liquidityInput - input that defines the desired liquidity amount and minimum tokens willing to be to withdrawn from the position. * @param resolveATA - if true, add instructions to create associated token accounts for tokenA,B for the destinationWallet if necessary. (RPC call required) * @param destinationWallet - the wallet to deposit tokens into when withdrawing from the position. If null, the WhirlpoolContext wallet is used. * @param positionWallet - the wallet to that houses the position token. If null, the WhirlpoolContext wallet is used. * @param ataPayer - wallet that will fund the creation of the new associated token accounts * @return the transaction that will deposit the tokens into the position when executed. */ decreaseLiquidity: (liquidityInput: DecreaseLiquidityInput, resolveATA?: boolean, destinationWallet?: Address, positionWallet?: Address, ataPayer?: Address) => Promise<TransactionBuilder>; /** * Collect fees from this position * * If `positionWallet` is provided, the wallet owners have to sign this transaction. * * @param updateFeesAndRewards - if true, add instructions to refresh the accumulated fees and rewards data (default to true unless you know that the collect fees quote and on-chain data match for the "feeOwedA" and "feeOwedB" fields in the Position account) * @param ownerTokenAccountMap - A record that maps a given mint to the owner's token account for that mint (if an entry doesn't exist, it will be automatically resolved) * @param destinationWallet - the wallet to deposit tokens into when withdrawing from the position. If null, the WhirlpoolContext wallet is used. * @param positionWallet - the wallet to that houses the position token. If null, the WhirlpoolContext wallet is used. * @param ataPayer - wallet that will fund the creation of the new associated token accounts * @param refresh - set to true to bypass cached on-chain data * @return the transaction that will collect fees from the position */ collectFees: (updateFeesAndRewards?: boolean, ownerTokenAccountMap?: Partial<Record<string, Address>>, destinationWallet?: Address, positionWallet?: Address, ataPayer?: Address, refresh?: boolean) => Promise<TransactionBuilder>; /** * Collect rewards from this position * * If `positionWallet` is provided, the wallet owners have to sign this transaction. * * @param rewardsToCollect - reward mints to collect (omitting this parameter means all rewards will be collected) * @param updateFeesAndRewards - if true, add instructions to refresh the accumulated fees and rewards data (default to true unless you know that the collect fees quote and on-chain data match for the "feeOwedA" and "feeOwedB" fields in the Position account) * @param ownerTokenAccountMap - A record that maps a given mint to the owner's token account for that mint (if an entry doesn't exist, it will be automatically resolved) * @param destinationWallet - the wallet to deposit tokens into when withdrawing from the position. If null, the WhirlpoolContext wallet is used. * @param positionWallet - the wallet to that houses the position token. If null, the WhirlpoolContext wallet is used. * @param ataPayer - wallet that will fund the creation of the new associated token accounts * @param refresh - set to true to bypass cached on-chain data * @return the transaction that will collect fees from the position */ collectRewards: (rewardsToCollect?: Address[], updateFeesAndRewards?: boolean, ownerTokenAccountMap?: Partial<Record<string, Address>>, destinationWallet?: Address, positionWallet?: Address, ataPayer?: Address, refresh?: boolean) => Promise<TransactionBuilder>; }