@renec-foundation/redex-sdk
Version:
Typescript SDK to interact with Orca's Whirlpool program.
315 lines (314 loc) • 19.6 kB
TypeScript
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>;
}