This package provides developers with low-level functionalities for interacting with the Whirlpool Program on Solana. It serves as a foundational tool that allows developers to manage and integrate detailed operations into their Typescript projects, particularly those related to Orca's Whirlpool Program. While a high-level SDK is available for easier integration, @orca-so/whirlpools, this package offers more granular control for advanced use cases.
Note: This SDK uses Solana Web3.js SDK v2. It is not compatible with the widely used v1.x.x version.
You can install the package via npm:
npm install @orca-so/whirlpools-client
Here are some basic examples of how to use the package.
The following example demonstrates how to fetch Whirlpools accounts based on specific filters, using the GPA utilities:
import { createSolanaRpc, address, devnet } from '@solana/web3.js';
import { fetchAllWhirlpoolWithFilter, whirlpoolTokenMintAFilter } from "@orca-so/whirlpools-client";
const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));
const tokenMintA = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); //DevUSDC
const filter = whirlpoolTokenMintAFilter(tokenMintA);
const accounts = await fetchAllWhirlpoolWithFilter(rpc, filter);
console.log(accounts);
To derive a PDA for a Whirlpool account, you can use the getWhirlpoolAddress
PDA utility.
import { getWhirlpoolAddress } from "@orca-so/whirlpools-client";
import { address } from '@solana/web3.js';
const whirlpoolConfigAddress = address("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR");
const tokenMintA = address("So11111111111111111111111111111111111111112"); //wSOL
const tokenMintB = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); //DevUSDC
const tickSpacing = 64;
const whirlpoolPda = await getWhirlpoolAddress(
whirlpoolConfigAddress,
tokenMintA,
tokenMintB,
tickSpacing,
);
console.log(whirlpoolPda);
The following example demonstrates how to create an InitializePool instruction using the Codama-IDL autogenerated code:
import { getInitializePoolV2Instruction, getTokenBadgeAddress, getWhirlpoolAddress, getFeeTierAddress } from "@orca-so/whirlpools-client";
import { address, generateKeyPairSigner } from '@solana/web3.js';
const whirlpoolConfigAddress = address("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR");
const tokenMintA = address("So11111111111111111111111111111111111111112"); // wSOL
const tokenMintB = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); // DevUSDC
const tokenBadgeA = await getTokenBadgeAddress(whirlpoolConfigAddress, tokenMintA)
const tokenBadgeB = await getTokenBadgeAddress(whirlpoolConfigAddress, tokenMintB)
const wallet = await generateKeyPairSigner(); // CAUTION: this wallet is not persistent
const tickSpacing = 8;
const whirlpool = await getWhirlpoolAddress(whirlpoolConfigAddress, tokenMintA, tokenMintB, tickSpacing);
const tokenVaultA = await generateKeyPairSigner();
const tokenVaultB = await generateKeyPairSigner();
const feeTier = await getFeeTierAddress(whirlpoolConfigAddress, tickSpacing);
const tokenProgramA = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const tokenProgramB = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const initialSqrtPrice = BigInt(7459106261056563200n);
const initializePoolInstruction = getInitializePoolV2Instruction({
whirlpoolsConfig: whirlpoolConfigAddress,
tokenMintA,
tokenMintB,
tokenBadgeA,
tokenBadgeB,
funder: wallet,
whirlpool,
tokenVaultA,
tokenVaultB,
feeTier,
whirlpoolBump: 1,
tickSpacing,
tokenProgramA,
tokenProgramB,
initialSqrtPrice
});
console.log(initializePoolInstruction);