@cetusprotocol/dlmm-sdk 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +390 -51
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +1 -1
  7. package/.turbo/turbo-build.log +0 -10485
  8. package/src/config/index.ts +0 -2
  9. package/src/config/mainnet.ts +0 -25
  10. package/src/config/testnet.ts +0 -30
  11. package/src/errors/errors.ts +0 -40
  12. package/src/index.ts +0 -8
  13. package/src/modules/configModule.ts +0 -184
  14. package/src/modules/index.ts +0 -1
  15. package/src/modules/partnerModule.ts +0 -302
  16. package/src/modules/poolModule.ts +0 -625
  17. package/src/modules/positionModule.ts +0 -901
  18. package/src/modules/rewardModule.ts +0 -174
  19. package/src/modules/swapModule.ts +0 -129
  20. package/src/sdk.ts +0 -88
  21. package/src/types/constants.ts +0 -23
  22. package/src/types/dlmm.ts +0 -466
  23. package/src/types/index.ts +0 -2
  24. package/src/utils/binUtils.ts +0 -552
  25. package/src/utils/feeUtils.ts +0 -92
  26. package/src/utils/index.ts +0 -5
  27. package/src/utils/parseData.ts +0 -556
  28. package/src/utils/strategyUtils.ts +0 -202
  29. package/src/utils/weightUtils.ts +0 -684
  30. package/tests/add_liquidity_bidask.test.ts +0 -192
  31. package/tests/add_liquidity_curve.test.ts +0 -244
  32. package/tests/add_liquidity_spot.test.ts +0 -314
  33. package/tests/bin.test.ts +0 -95
  34. package/tests/config.test.ts +0 -73
  35. package/tests/partner.test.ts +0 -74
  36. package/tests/pool.test.ts +0 -184
  37. package/tests/position.test.ts +0 -76
  38. package/tests/remove_liquidity.test.ts +0 -137
  39. package/tests/swap.test.ts +0 -96
  40. package/tests/tsconfig.json +0 -26
  41. package/tsconfig.json +0 -5
  42. package/tsup.config.ts +0 -9
package/README.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  The SDK provides a DLMM (Dynamic Liquidity Market Maker) module for specialized liquidity operations with different modes to suit various trading strategies. This module enables users to perform complex liquidity operations with flexibility in how they want to manage their positions.
4
4
 
5
+ ## Features
6
+
7
+ - **Multiple Liquidity Strategies**: Spot, BidAsk, and Curve strategies for different trading approaches
8
+ - **Comprehensive Pool Management**: Create, query, and manage DLMM pools
9
+ - **Advanced Position Management**: Add/remove liquidity, collect fees and rewards
10
+ - **Flexible Swap Operations**: Support for both A-to-B and B-to-A swaps
11
+ - **Partner Integration**: Built-in partner and referral system
12
+ - **Rich Utility Functions**: Bin calculations, price conversions, and liquidity management tools
13
+ - **Multi-Network Support**: Works with both mainnet and testnet
14
+
5
15
  ## Getting Started
6
16
 
7
17
  ## How to Use the DLMM SDK?
@@ -26,27 +36,34 @@ import { CetusDlmmSDK } from '@cetusprotocol/dlmm-sdk'
26
36
 
27
37
  Initialize the SDK with the required configuration parameters. This typically includes setting up the network if needed.
28
38
 
29
- If you would like to use the mainnet network and the official Sui rpc url, you can do so as follows:
30
-
39
+ **Option 1: Use default mainnet configuration**
31
40
  ```typescript
32
41
  const sdk = CetusDlmmSDK.createSDK()
33
42
  ```
34
43
 
35
- If you wish to set your own full node URL or network (You have the option to select either 'mainnet' or 'testnet' for the network), you can do so as follows:
36
-
44
+ **Option 2: Specify network environment**
37
45
  ```typescript
38
- const env = 'mainnet'
39
- const full_rpc_url = 'YOUR_FULL_NODE_URL'
46
+ // For mainnet
47
+ const sdk = CetusDlmmSDK.createSDK({ env: 'mainnet' })
40
48
 
41
- const sdk = CetusDlmmSDK.createSDK({ env })
49
+ // For testnet
50
+ const sdk = CetusDlmmSDK.createSDK({ env: 'testnet' })
42
51
  ```
43
52
 
44
- If you wish to set your own full node URL or SuiClient, you can do so as follows:
53
+ **Option 3: Use custom RPC URL**
54
+ ```typescript
55
+ const sdk = CetusDlmmSDK.createSDK({
56
+ env: 'mainnet',
57
+ full_rpc_url: 'YOUR_FULL_NODE_URL'
58
+ })
59
+ ```
45
60
 
61
+ **Option 4: Use custom SuiClient**
46
62
  ```typescript
47
- const sdk = CetusDlmmSDK.createSDK({ env, sui_client })
48
- // or
49
- const sdk = CetusDlmmSDK.createSDK({ env, full_rpc_url })
63
+ import { SuiClient } from '@mysten/sui/client'
64
+
65
+ const suiClient = new SuiClient({ url: 'YOUR_RPC_URL' })
66
+ const sdk = CetusDlmmSDK.createSDK({ env: 'mainnet', sui_client: suiClient })
50
67
  ```
51
68
 
52
69
  ## Usage
@@ -55,15 +72,13 @@ After linking your wallet, if you need use your wallet address to do something,
55
72
 
56
73
  ```typescript
57
74
  const wallet = 'YOUR_WALLET_ADDRESS'
58
-
59
75
  sdk.setSenderAddress(wallet)
60
76
  ```
61
77
 
62
- if you need to change your rpc url, you can do so as follows:
78
+ If you need to change your RPC URL, you can do so as follows:
63
79
 
64
80
  ```typescript
65
81
  const new_rpc_url = 'YOUR_NEW_FULL_NODE_URL'
66
-
67
82
  sdk.updateFullRpcUrl(new_rpc_url)
68
83
  ```
69
84
 
@@ -75,6 +90,53 @@ sdk.updateFullRpcUrl(new_rpc_url)
75
90
  - `coin_type_a` & `coin_type_b`: Coin type identifiers for the trading pair
76
91
  - `coin_decimal_a` & `coin_decimal_b`: Decimal places for each coin type
77
92
 
93
+ ### Default Fee Options
94
+
95
+ The SDK provides predefined fee configurations for different types of trading pairs. These configurations are optimized based on asset volatility and market characteristics:
96
+
97
+ ```typescript
98
+ const dlmmDefaultFeeOptions = [
99
+ { binStep: 1, baseFactor: 10000, fee: '0.0001' },
100
+ { binStep: 1, baseFactor: 20000, fee: '0.0002' },
101
+ { binStep: 2, baseFactor: 15000, fee: '0.0003' },
102
+ { binStep: 2, baseFactor: 20000, fee: '0.0004' },
103
+ { binStep: 5, baseFactor: 10000, fee: '0.0005' },
104
+ { binStep: 10, baseFactor: 10000, fee: '0.001' },
105
+ { binStep: 15, baseFactor: 10000, fee: '0.0015' },
106
+ { binStep: 20, baseFactor: 10000, fee: '0.002' },
107
+ { binStep: 25, baseFactor: 10000, fee: '0.0025' },
108
+ { binStep: 30, baseFactor: 10000, fee: '0.003' },
109
+ { binStep: 50, baseFactor: 8000, fee: '0.004' },
110
+ { binStep: 80, baseFactor: 7500, fee: '0.006' },
111
+ { binStep: 100, baseFactor: 8000, fee: '0.008' },
112
+ { binStep: 100, baseFactor: 10000, fee: '0.01' },
113
+ { binStep: 200, baseFactor: 10000, fee: '0.02' },
114
+ { binStep: 400, baseFactor: 10000, fee: '0.04' }
115
+ ]
116
+ ```
117
+
118
+ **Parameter Explanations:**
119
+
120
+ - **`binStep`**: The step size between bins, determining the price granularity of the pool. Smaller values provide finer price resolution but require more computational resources.
121
+ - **`baseFactor`**: A multiplier used in fee calculations, affecting the overall fee structure of the pool.
122
+ - **`fee`**: The trading fee rate as a decimal (e.g., '0.0001' = 0.01%). This is the fee charged for each swap transaction.
123
+
124
+ **Fee Tier Recommendations:**
125
+
126
+ - **Low fees (0.01% - 0.05%)**: Best for stable pairs or low-volatility mainstream assets
127
+ - **Medium fees (0.1% - 0.3%)**: Suitable for medium-volatility assets or mainstream trading pairs
128
+ - **High fees (0.4% - 4%)**: Recommended for high-volatility assets, altcoins, or small market cap pairs
129
+
130
+ When creating a new pool, choose the fee configuration that best matches your trading pair's characteristics:
131
+
132
+ ```typescript
133
+ // Example: Create a pool for a stable pair (USDC/USDT)
134
+ const stablePairConfig = { binStep: 1, baseFactor: 10000, fee: '0.0001' }
135
+
136
+ // Example: Create a pool for a volatile altcoin pair
137
+ const altcoinConfig = { binStep: 100, baseFactor: 10000, fee: '0.01' }
138
+ ```
139
+
78
140
  ### 1. Pool Operations
79
141
 
80
142
  #### Get Pool Information
@@ -201,27 +263,25 @@ const { feeData, rewardData } = await sdk.Position.fetchPositionFeeAndReward([
201
263
  },
202
264
  ])
203
265
 
204
- // feeData structure
205
- // {
206
- // [position_id]: {
207
- // position_id: string,
208
- // fee_owned_a: string, // Amount of token A fees owned
209
- // fee_owned_b: string // Amount of token B fees owned
210
- // }
211
- // }
266
+ ```
267
+
268
+ #### Fee Rate Calculations
212
269
 
213
- // rewardData structure
214
- // {
215
- // [position_id]: {
216
- // position_id: string,
217
- // rewards: {
218
- // [coin_type]: string // Amount of reward tokens owned
219
- // }
220
- // }
221
- // }
270
+ ```typescript
271
+ // Get total fee rate for a pool
272
+ const totalFeeRate = await sdk.Pool.getTotalFeeRate({
273
+ pool_id,
274
+ coin_type_a,
275
+ coin_type_b
276
+ })
277
+
278
+ // Get variable fee from pool parameters
279
+ const variableFee = FeeUtils.getVariableFee(pool.variable_parameters)
280
+ console.log('Variable fee:', variableFee)
281
+ console.log('Variable fee percentage:', d(variableFee).div(d(FEE_PRECISION)).toString())
222
282
  ```
223
283
 
224
- #### Fee Collection
284
+ #### Fee and Reward Collection
225
285
 
226
286
  You can collect fees from your positions in several ways:
227
287
 
@@ -236,6 +296,18 @@ const tx = await sdk.Position.collectRewardAndFeePayload([{
236
296
  coin_type_b
237
297
  }])
238
298
 
299
+ // Simulate or send the transaction
300
+ const sim_result = await sdk.FullClient.sendSimulationTransaction(tx, wallet)
301
+ ```
302
+ 2. **Collect Partner ref fee**:
303
+ ```typescript
304
+ // Build collect fee and reward transaction
305
+ const tx = await sdk.Position.claimRefFeePayload({
306
+ partner_id: "0x..",
307
+ partner_cap_id: "0x..", // Optional parameter
308
+ fee_coin_types: [coin_type]
309
+ })
310
+
239
311
  // Simulate or send the transaction
240
312
  const sim_result = await sdk.FullClient.sendSimulationTransaction(tx, wallet)
241
313
  ```
@@ -244,6 +316,174 @@ const sim_result = await sdk.FullClient.sendSimulationTransaction(tx, wallet)
244
316
 
245
317
  #### Add Liquidity
246
318
 
319
+ The DLMM SDK provides two main methods for adding liquidity:
320
+
321
+ 1. **`calculateAddLiquidityInfo(option)`** - Calculates the liquidity distribution across bins
322
+ 2. **`addLiquidityPayload(option, tx?)`** - Creates the transaction payload for adding liquidity
323
+
324
+ **Method 1: `calculateAddLiquidityInfo(option: CalculateAddLiquidityOption | CalculateAddLiquidityAutoFillOption)`**
325
+
326
+ This method calculates how liquidity should be distributed across different bins based on your strategy and parameters.
327
+
328
+ **Parameters for `CalculateAddLiquidityOption`:**
329
+ ```typescript
330
+ interface CalculateAddLiquidityOption {
331
+ pool_id: string // Pool ID
332
+ amount_a: string // Amount of token A to add
333
+ amount_b: string // Amount of token B to add
334
+ active_id: number // Current active bin ID
335
+ bin_step: number // Bin step size
336
+ lower_bin_id: number // Lower bound of bin range
337
+ upper_bin_id: number // Upper bound of bin range
338
+ active_bin_of_pool?: { // Active bin amounts (if active bin is in range)
339
+ amount_a: string
340
+ amount_b: string
341
+ }
342
+ strategy_type: StrategyType // Liquidity strategy (Spot, BidAsk, Curve)
343
+ }
344
+ ```
345
+
346
+ **Parameters for `CalculateAddLiquidityAutoFillOption`:**
347
+ ```typescript
348
+ interface CalculateAddLiquidityAutoFillOption {
349
+ pool_id: string // Pool ID
350
+ coin_amount: string // Fixed amount of one token
351
+ fix_amount_a: boolean // true for token A, false for token B
352
+ active_id: number // Current active bin ID
353
+ bin_step: number // Bin step size
354
+ lower_bin_id: number // Lower bound of bin range
355
+ upper_bin_id: number // Upper bound of bin range
356
+ active_bin_of_pool?: { // Active bin amounts (if active bin is in range)
357
+ amount_a: string
358
+ amount_b: string
359
+ }
360
+ strategy_type: StrategyType // Liquidity strategy (Spot, BidAsk, Curve)
361
+ }
362
+ ```
363
+
364
+ **Method 2: `addLiquidityPayload(option: AddLiquidityOption | OpenAndAddLiquidityOption, tx?: Transaction)`**
365
+
366
+ This method creates the transaction payload for adding liquidity to an existing position or opening a new position.
367
+
368
+ **Parameters for `AddLiquidityOption` (existing position):**
369
+ ```typescript
370
+ interface AddLiquidityOption {
371
+ pool_id: string // Pool ID
372
+ bin_infos: BinLiquidityInfo // Calculated bin distribution from calculateAddLiquidityInfo
373
+ coin_type_a: string // Token A coin type
374
+ coin_type_b: string // Token B coin type
375
+ active_id: number // Current active bin ID
376
+ position_id: string // Existing position ID
377
+ collect_fee: boolean // Whether to collect fees
378
+ reward_coins: string[] // Reward coin types
379
+ strategy_type: StrategyType // Liquidity strategy
380
+ use_bin_infos: boolean // Whether to use calculated bin_infos
381
+ max_price_slippage: number // Maximum price slippage tolerance
382
+ bin_step: number // Bin step size
383
+ }
384
+ ```
385
+
386
+ **Parameters for `OpenAndAddLiquidityOption` (new position):**
387
+ ```typescript
388
+ interface OpenAndAddLiquidityOption {
389
+ pool_id: string // Pool ID
390
+ bin_infos: BinLiquidityInfo // Calculated bin distribution from calculateAddLiquidityInfo
391
+ coin_type_a: string // Token A coin type
392
+ coin_type_b: string // Token B coin type
393
+ lower_bin_id: number // Lower bound of bin range
394
+ upper_bin_id: number // Upper bound of bin range
395
+ active_id: number // Current active bin ID
396
+ strategy_type: StrategyType // Liquidity strategy
397
+ use_bin_infos: boolean // Whether to use calculated bin_infos
398
+ max_price_slippage: number // Maximum price slippage tolerance
399
+ bin_step: number // Bin step size
400
+ }
401
+ ```
402
+
403
+ **Complete Example - Adding Liquidity to Existing Position:**
404
+
405
+ ```typescript
406
+ // Step 1: Calculate liquidity distribution
407
+ const calculateOption: CalculateAddLiquidityOption = {
408
+ pool_id: '0x...',
409
+ amount_a: '1000000',
410
+ amount_b: '1200000',
411
+ active_id: 100,
412
+ bin_step: 2,
413
+ lower_bin_id: 90,
414
+ upper_bin_id: 110,
415
+ active_bin_of_pool: amounts_in_active_bin, // Optional: if active bin is in range
416
+ strategy_type: StrategyType.Spot
417
+ }
418
+
419
+ const bin_infos = await sdk.Position.calculateAddLiquidityInfo(calculateOption)
420
+
421
+ // Step 2: Create transaction payload
422
+ const addLiquidityOption: AddLiquidityOption = {
423
+ pool_id: '0x...',
424
+ bin_infos: bin_infos,
425
+ coin_type_a: '0x...::usdc::USDC',
426
+ coin_type_b: '0x...::usdt::USDT',
427
+ active_id: 100,
428
+ position_id: '0x...',
429
+ collect_fee: true,
430
+ reward_coins: [],
431
+ strategy_type: StrategyType.Spot,
432
+ use_bin_infos: false,
433
+ max_price_slippage: 0.01,
434
+ bin_step: 2
435
+ }
436
+
437
+ const tx = sdk.Position.addLiquidityPayload(addLiquidityOption)
438
+ ```
439
+
440
+ **Complete Example - Opening New Position:**
441
+
442
+ ```typescript
443
+ // Step 1: Calculate liquidity distribution
444
+ const calculateOption: CalculateAddLiquidityOption = {
445
+ pool_id: '0x...',
446
+ amount_a: '1000000',
447
+ amount_b: '1200000',
448
+ active_id: 100,
449
+ bin_step: 2,
450
+ lower_bin_id: 90,
451
+ upper_bin_id: 110,
452
+ active_bin_of_pool: amounts_in_active_bin,
453
+ strategy_type: StrategyType.Spot
454
+ }
455
+
456
+ const bin_infos = await sdk.Position.calculateAddLiquidityInfo(calculateOption)
457
+
458
+ // Step 2: Create transaction payload for new position
459
+ const openPositionOption: OpenAndAddLiquidityOption = {
460
+ pool_id: '0x...',
461
+ bin_infos: bin_infos,
462
+ coin_type_a: '0x...::usdc::USDC',
463
+ coin_type_b: '0x...::usdt::USDT',
464
+ lower_bin_id: 90,
465
+ upper_bin_id: 110,
466
+ active_id: 100,
467
+ strategy_type: StrategyType.Spot,
468
+ use_bin_infos: false,
469
+ max_price_slippage: 0.01,
470
+ bin_step: 2
471
+ }
472
+
473
+ const tx = sdk.Position.addLiquidityPayload(openPositionOption)
474
+ ```
475
+
476
+ **Important Parameter Notes:**
477
+
478
+ - **`active_bin_of_pool`**: This parameter is crucial when the active bin falls within your position's range. Use `getActiveBinIfInRange()` to get the correct values.
479
+ - **`use_bin_infos`**: When `false`, the contract calculates liquidity distribution internally; when `true`, it uses the provided `bin_infos`.
480
+ - **`max_price_slippage`**: Protects against price movements during transaction execution (e.g., 0.01 = 1% slippage tolerance).
481
+ - **`collect_fee`**: Only applicable for existing positions; determines whether to collect accumulated fees when adding liquidity.
482
+ - **`strategy_type`**: Affects how liquidity is distributed across bins:
483
+ - `Spot`: Even distribution around current price
484
+ - `BidAsk`: Concentrated at specific price levels
485
+ - `Curve`: Smooth distribution following a curve
486
+
247
487
  There are three strategies for adding liquidity: Spot, BidAsk, and Curve. Here's how to use each:
248
488
 
249
489
  1. **Spot Strategy**:
@@ -263,6 +503,7 @@ const amounts_in_active_bin = await sdk.Position.getActiveBinIfInRange(
263
503
 
264
504
  // Calculate liquidity distribution
265
505
  const calculateOption = {
506
+ pool_id,
266
507
  amount_a: '1000000',
267
508
  amount_b: '1200000',
268
509
  active_id,
@@ -273,30 +514,36 @@ const calculateOption = {
273
514
  amount_b_in_active_bin: amounts_in_active_bin?.amount_b || '0',
274
515
  strategy_type: StrategyType.Spot
275
516
  }
276
- const bin_infos = sdk.Position.calculateAddLiquidityInfo(calculateOption)
517
+ const bin_infos = await sdk.Position.calculateAddLiquidityInfo(calculateOption)
277
518
 
278
519
  // For new position
279
520
  const addOption = {
280
521
  pool_id,
281
- bin_infos,
282
- coin_type_a: pool.coin_type_a,
283
- coin_type_b: pool.coin_type_b,
284
- lower_bin_id: -10,
285
- upper_bin_id: 10,
286
- active_id
522
+ amount_a,
523
+ amount_b,
524
+ active_id,
525
+ bin_step,
526
+ lower_bin_id,
527
+ upper_bin_id,
528
+ active_bin_of_pool: amounts_in_active_bin,
529
+ strategy_type: StrategyType.Spot,
287
530
  }
288
531
  const tx = sdk.Position.addLiquidityPayload(addOption)
289
532
 
290
533
  // For existing position
291
534
  const addOption = {
292
535
  pool_id,
293
- bin_infos,
294
- coin_type_a: pool.coin_type_a,
295
- coin_type_b: pool.coin_type_b,
536
+ bin_infos: bin_infos,
537
+ coin_type_a,
538
+ coin_type_b,
296
539
  active_id,
297
540
  position_id,
298
541
  collect_fee: true,
299
- reward_coins: []
542
+ reward_coins: [],
543
+ strategy_type: StrategyType.Spot,
544
+ use_bin_infos: false,
545
+ max_price_slippage: 0.01,
546
+ bin_step,
300
547
  }
301
548
  const tx = sdk.Position.addLiquidityPayload(addOption)
302
549
  ```
@@ -306,6 +553,8 @@ Note: The `amount_a_in_active_bin` and `amount_b_in_active_bin` parameters are u
306
553
  2. Returns the amounts of both tokens in the active bin if it is within range
307
554
  3. Returns undefined if the active bin is outside the range
308
555
 
556
+ ---
557
+
309
558
  2. **BidAsk Strategy**:
310
559
  ```typescript
311
560
  // Similar to Spot strategy but with different strategy_type
@@ -556,9 +805,31 @@ const whitelistTx = sdk.Reward.updateRewardWhiteListPayload({
556
805
  })
557
806
  ```
558
807
 
559
- ### 8. Bin Operations
808
+ ### 8. Configuration Management
560
809
 
561
- The SDK provides utility functions for working with bins and prices through the `BinUtils` class:
810
+ The SDK provides configuration management through the `Config` module:
811
+
812
+ ```typescript
813
+ // Get global DLMM configuration
814
+ const globalConfig = await sdk.Config.getDlmmGlobalConfig()
815
+
816
+ // Get bin step configuration list
817
+ const binStepConfigs = await sdk.Config.getBinStepConfigList(pool_id)
818
+
819
+ // Fetch all SDK configurations
820
+ const sdkConfigs = await sdk.Config.fetchDlmmSdkConfigs()
821
+
822
+ // Get reward period emission data
823
+ const rewardEmission = await sdk.Reward.getRewardPeriodEmission(
824
+ reward_manager_id,
825
+ reward_period,
826
+ current_time
827
+ )
828
+ ```
829
+
830
+ ### 9. Bin Operations
831
+
832
+ The SDK provides comprehensive utility functions for working with bins and prices through the `BinUtils` class:
562
833
 
563
834
  ```typescript
564
835
  import { BinUtils } from '@cetusprotocol/dlmm-sdk'
@@ -598,15 +869,15 @@ const amountA = BinUtils.getAmountAFromLiquidity('4101094304427826916657468', '1
598
869
  // Get amount B from liquidity
599
870
  const amountB = BinUtils.getAmountBFromLiquidity('4919119455159831291232256')
600
871
 
601
- // Get amounts from liquidity with ratio
602
- const [amountA, amountB] = BinUtils.getAmountsFromLiquidityWithRatio(
603
- '4510099798813469403250688',
604
- '18446744073709551616',
605
- 0.9 // ratio
606
- )
607
872
 
608
873
  // Split bin liquidity info
609
874
  const split_bin_infos = BinUtils.splitBinLiquidityInfo(bin_infos, 0, 70)
875
+
876
+ // Get position count between bin ranges
877
+ const positionCount = BinUtils.getPositionCount(-750, 845)
878
+
879
+ // Find min/max bin ID for a given bin step
880
+ const { minBinId, maxBinId } = BinUtils.findMinMaxBinId(10)
610
881
  ```
611
882
 
612
883
  These utility functions are particularly useful when:
@@ -614,6 +885,7 @@ These utility functions are particularly useful when:
614
885
  - Calculating optimal bin ranges for trading strategies
615
886
  - Converting between different price representations
616
887
  - Managing liquidity distributions across bins
888
+ - Analyzing position density and distribution
617
889
 
618
890
  ### 9. Advanced Operations
619
891
 
@@ -640,6 +912,73 @@ await sdk.Position.updatePositionFeeAndRewards({
640
912
  })
641
913
  ```
642
914
 
915
+ ## Troubleshooting
916
+
917
+ ### Common Issues
918
+
919
+ **1. Transaction Simulation Failures**
920
+ ```typescript
921
+ // Always simulate transactions before sending
922
+ const simResult = await sdk.FullClient.sendSimulationTransaction(tx, wallet)
923
+ if (simResult.effects.status.status === 'failure') {
924
+ console.error('Transaction simulation failed:', simResult.effects.status.error)
925
+ }
926
+ ```
927
+
928
+ **2. Insufficient Gas Budget**
929
+ ```typescript
930
+ // Set appropriate gas budget for complex operations
931
+ tx.setGasBudget(10000000000) // 10 SUI
932
+ ```
933
+
934
+ **3. Active Bin Range Validation**
935
+ ```typescript
936
+ // Always check if active bin is within your position range
937
+ const amounts_in_active_bin = await sdk.Position.getActiveBinIfInRange(
938
+ pool.bin_manager.bin_manager_handle,
939
+ lower_bin_id,
940
+ upper_bin_id,
941
+ active_id,
942
+ bin_step
943
+ )
944
+ ```
945
+
946
+ **4. Price Slippage Protection**
947
+ ```typescript
948
+ // Use appropriate slippage protection
949
+ const isValid = await sdk.Position.validateActiveIdSlippage({
950
+ pool_id,
951
+ active_id,
952
+ max_bin_slippage: 0.01 // 1% slippage tolerance
953
+ })
954
+ ```
955
+
956
+ ### Debugging Tips
957
+
958
+ **1. Print Transaction Details**
959
+ ```typescript
960
+ import { printTransaction } from '@cetusprotocol/common-sdk'
961
+
962
+ // Print transaction for debugging
963
+ printTransaction(tx)
964
+ ```
965
+
966
+ **2. Check Pool State**
967
+ ```typescript
968
+ // Always verify pool state before operations
969
+ const pool = await sdk.Pool.getPool(pool_id)
970
+ console.log('Pool active_id:', pool.active_id)
971
+ console.log('Pool bin_step:', pool.bin_step)
972
+ ```
973
+
974
+ **3. Validate Position Data**
975
+ ```typescript
976
+ // Parse and validate position liquidity shares
977
+ const active_bin = await sdk.Pool.getBinInfo(pool.bin_manager.bin_manager_handle, pool.active_id, pool.bin_step)
978
+ const liquidity_shares_data = parseLiquidityShares(position.liquidity_shares, pool.bin_step, position.lower_bin_id, active_bin)
979
+ console.log('Liquidity shares data:', liquidity_shares_data)
980
+ ```
981
+
643
982
  ## More About Cetus
644
983
 
645
984
  Use the following links to learn more about Cetus: