@@ -19,27 +19,33 @@ npm install @orca-so/whirlpools @solana/kit@2
1919## Basic Usage
2020
2121### 1. Wallet Creation
22+
2223You can [ generate a file system wallet using the Solana CLI] ( https://docs.solanalabs.com/cli/wallets/file-system ) and load it in your program.
2324
2425``` tsx
25- import { createKeyPairSignerFromBytes } from ' @solana/kit' ;
26- import fs from ' fs ' ;
26+ import { createKeyPairSignerFromBytes } from " @solana/kit" ;
27+ import fs from " fs " ;
2728
28- const keyPairBytes = new Uint8Array (JSON .parse (fs .readFileSync (' path/to/solana-keypair.json' , ' utf8' )));
29+ const keyPairBytes = new Uint8Array (
30+ JSON .parse (fs .readFileSync (" path/to/solana-keypair.json" , " utf8" ))
31+ );
2932const wallet = await createKeyPairSignerFromBytes (keyPairBytes );
3033```
3134
3235### 2. Configure the Whirlpools SDK for Your Network
36+
3337Orca's Whirlpools SDK supports several networks: Solana Mainnet, Solana Devnet, Eclipse Mainnet, and Eclipse Testnet. To select a network, use the ` setWhirlpoolsConfig ` function. This ensures compatibility with the network you’re deploying on.
3438
3539Example: Setting the SDK Configuration to Solana Devnet.
40+
3641``` tsx
37- import { setWhirlpoolsConfig } from ' @orca-so/whirlpools' ;
42+ import { setWhirlpoolsConfig } from " @orca-so/whirlpools" ;
3843
39- await setWhirlpoolsConfig (' solanaDevnet' );
44+ await setWhirlpoolsConfig (" solanaDevnet" );
4045```
4146
4247Available networks are:
48+
4349- solanaMainnet
4450- solanaDevnet
4551- eclipseMainnet
@@ -48,34 +54,36 @@ Available networks are:
4854> ℹ️ The setWhirlpoolsConfig function accepts either one of Orca's default network keys or a custom Address. This allows you to specify a custom configuration if needed.
4955
5056### 3. Create the Swap Instructions
57+
5158After configuring the SDK, you can perform a swap. Here is an example of how to perform a token swap using the Whirlpools SDK:
5259
5360``` tsx
54- import { swapInstructions } from ' @orca-so/whirlpools' ;
61+ import { swapInstructions } from " @orca-so/whirlpools" ;
5562const poolAddress = " POOL_ADDRESS" ;
5663const mintAddress = " TOKEN_MINT" ;
5764const amount = 1_000_000n ;
5865const slippageTolerance = 100 ; // 100 bps = 1%
5966
6067const { instructions, quote } = await swapInstructions (
61- devnetRpc ,
62- {
63- inputAmount: amount ,
64- mint: mintAddress
65- },
66- poolAddress ,
67- slippageTolerance ,
68- wallet
68+ devnetRpc ,
69+ {
70+ inputAmount: amount ,
71+ mint: mintAddress ,
72+ },
73+ poolAddress ,
74+ slippageTolerance ,
75+ wallet
6976);
7077```
7178
7279### 4. Putting it all together
80+
7381``` tsx
74- import { swapInstructions , setWhirlpoolsConfig } from ' @orca-so/whirlpools' ;
75- import { generateKeyPairSigner , createSolanaRpc , devnet } from ' @solana/kit' ;
82+ import { swapInstructions , setWhirlpoolsConfig } from " @orca-so/whirlpools" ;
83+ import { generateKeyPairSigner , createSolanaRpc , devnet } from " @solana/kit" ;
7684
77- const devnetRpc = createSolanaRpc (devnet (' https://api.devnet.solana.com' ));
78- await setWhirlpoolsConfig (' solanaDevnet' );
85+ const devnetRpc = createSolanaRpc (devnet (" https://api.devnet.solana.com" ));
86+ await setWhirlpoolsConfig (" solanaDevnet" );
7987const wallet = loadWallet ();
8088await devnetRpc .requestAirdrop (wallet .address , lamports (1000000000n )).send ();
8189
@@ -92,13 +100,164 @@ const amount = 1_000_000n; // 0.001 WSOL (SOL has 9 decimals)
92100const slippageTolerance = 100 ; // 100bps = 1%
93101
94102const { instructions, quote } = await swapInstructions (
95- devnetRpc ,
103+ devnetRpc ,
104+ {
105+ inputAmount: amount ,
106+ mint: mintAddress ,
107+ },
108+ poolAddress ,
109+ slippageTolerance ,
110+ wallet
111+ );
112+ ```
113+
114+ ## ACTIONS
115+
116+ To use actions, you need to set some configuration first.
117+ The only required configuration is the keypair of the payer, and the rpc url.
118+
119+ ``` tsx
120+ import { setPayerFromBytes , setRpc } from " @orca-so/whirlpools" ;
121+
122+ // Set payer from a private key byte array
123+ const privateKeyBytes = new Uint8Array ([
124+ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 ,
125+ 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 ,
126+ ]);
127+ await setPayerFromBytes (privateKeyBytes );
128+
129+ // Set rpc url
130+ await setRpc (" https://api.devnet.solana.com" );
131+ ```
132+
133+ You can also optionally set up the prioritization fees and jito tip settings according to your needs.
134+
135+ ``` tsx
136+ // Set priority fee settings
137+ setPriorityFeeSetting ({
138+ type: " dynamic" ,
139+ maxCapLamports: BigInt (4_000_000 ), // 0.004 SOL
140+ });
141+
142+ // Set Jito tip settings
143+ setJitoTipSetting ({
144+ type: " dynamic" ,
145+ maxCapLamports: BigInt (4_000_000 ), // 0.004 SOL
146+ });
147+
148+ // Set compute unit margin multiplier
149+ setComputeUnitMarginMultiplier (1.1 );
150+
151+ // Set priority fee percentile
152+ setPriorityFeePercentile (" 50" );
153+
154+ // Set Jito fee percentile (50ema is the default)
155+ setJitoFeePercentile (" 50ema" );
156+
157+ // Set Jito block engine URL
158+ await setJitoBlockEngineUrl (" https://bundles.jito.wtf" );
159+ ```
160+
161+ ### 1. Create a new whirlpool
162+
163+ ``` tsx
164+ import { createSplashPool } from " @orca-so/whirlpools" ;
165+ import { address } from " @solana/kit" ;
166+
167+ // Create a new splash pool between SOL and USDC
168+ const { poolAddress, callback } = await createSplashPool (
169+ address (" So11111111111111111111111111111111111111112" ), // SOL
170+ address (" EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" ) // USDC
171+ );
172+
173+ // Execute the transaction
174+ const signature = await callback ();
175+ console .log (` Pool created at ${poolAddress } in tx ${signature } ` );
176+ ```
177+
178+ ### 2. Add liquidity to a whirlpool
179+
180+ ``` tsx
181+ import {
182+ openFullRangePosition ,
183+ openConcentratedPosition ,
184+ } from " @orca-so/whirlpools" ;
185+ import { address } from " @solana/kit" ;
186+
187+ // Add full range liquidity to a splash pool
188+ const { positionAddress, callback : fullRangeCallback } =
189+ await openFullRangePosition (
190+ address (" POOL_ADDRESS" ), // The pool address
96191 {
97- inputAmount: amount ,
98- mint: mintAddress
192+ tokenA: BigInt (1_000_000 ), // Amount of token A to add (in native units)
99193 },
100- poolAddress ,
101- slippageTolerance ,
102- wallet
194+ 50 // Optional: Slippage tolerance in basis points (0.5%)
195+ );
196+
197+ // Execute the transaction
198+ const fullRangeSig = await fullRangeCallback ();
199+ console .log (
200+ ` Full range position created at ${positionAddress } in tx ${fullRangeSig } `
103201);
202+
203+ // Add concentrated liquidity to a whirlpool
204+ const { positionAddress : concPosAddress, callback : concCallback } =
205+ await openConcentratedPosition (
206+ address (" POOL_ADDRESS" ), // The pool address
207+ {
208+ tokenA: BigInt (1_000_000 ), // Amount of token A to add (in native units)
209+ },
210+ 19.5 , // Lower price bound
211+ 20.5 , // Upper price bound
212+ 50 // Optional: Slippage tolerance in basis points (0.5%)
213+ );
214+
215+ // Execute the transaction
216+ const concSig = await concCallback ();
217+ console .log (
218+ ` Concentrated position created at ${concPosAddress } in tx ${concSig } `
219+ );
220+
221+ // Increase liquidity in an existing position
222+ const { callback : increaseLiqCallback, quote } = await increasePosLiquidity (
223+ address (" POSITION_ADDRESS" ), // The position address
224+ {
225+ tokenA: BigInt (1_000_000 ), // Amount of token A to add (in native units)
226+ },
227+ 50 // Optional: Slippage tolerance in basis points (0.5%)
228+ );
229+
230+ // optionally check quote
231+ if (quote .tokenMaxB < 1_000_000n ) {
232+ // Check if max token B amount is acceptable
233+ const increaseLiqSig = await increaseLiqCallback ();
234+ console .log (` Added liquidity in tx ${increaseLiqSig } ` );
235+ } else {
236+ console .log (` Required token B amount ${quote .tokenMaxB } is too high ` );
237+ }
238+ ```
239+
240+ ### 3. Harvest rewards from all positions
241+
242+ ``` tsx
243+ // Harvest fees and rewards from all positions owned by the wallet
244+ const signatures = await harvestAllPositionFees ();
245+ console .log (` Harvested all positions in ${signatures .length } transactions ` );
246+
247+ // Harvest fees and rewards from a single position
248+ const {
249+ callback : harvestCallback,
250+ feesQuote,
251+ rewardsQuote,
252+ } = await harvestPosition (
253+ address (" POSITION_ADDRESS" ) // The position address
254+ );
255+
256+ // Check quotes
257+ console .log (` Fees to collect: ${feesQuote .feeOwedA }, ${feesQuote .feeOwedB } ` );
258+ console .log (` Rewards to collect: ${rewardsQuote .rewards [0 ].rewardsOwed } ` );
259+
260+ // Execute the transaction
261+ const harvestSig = await harvestCallback ();
262+ console .log (` Harvested position in tx ${harvestSig } ` );
104263```
0 commit comments