@cetusprotocol/dlmm-sdk 0.0.0-experimental-20250925173459

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 (47) hide show
  1. package/.turbo/turbo-build.log +10444 -0
  2. package/README.md +654 -0
  3. package/dist/index.d.mts +1050 -0
  4. package/dist/index.d.ts +1050 -0
  5. package/dist/index.js +13 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +13 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +35 -0
  10. package/src/config/index.ts +2 -0
  11. package/src/config/mainnet.ts +25 -0
  12. package/src/config/testnet.ts +30 -0
  13. package/src/errors/errors.ts +40 -0
  14. package/src/index.ts +8 -0
  15. package/src/modules/configModule.ts +184 -0
  16. package/src/modules/index.ts +1 -0
  17. package/src/modules/partnerModule.ts +302 -0
  18. package/src/modules/poolModule.ts +578 -0
  19. package/src/modules/positionModule.ts +882 -0
  20. package/src/modules/rewardModule.ts +174 -0
  21. package/src/modules/swapModule.ts +129 -0
  22. package/src/sdk.ts +88 -0
  23. package/src/types/constants.ts +23 -0
  24. package/src/types/dlmm.ts +445 -0
  25. package/src/types/ilm.ts +33 -0
  26. package/src/types/index.ts +3 -0
  27. package/src/utils/binUtils.ts +552 -0
  28. package/src/utils/feeUtils.ts +92 -0
  29. package/src/utils/ilmUtils.ts +187 -0
  30. package/src/utils/index.ts +6 -0
  31. package/src/utils/parseData.ts +519 -0
  32. package/src/utils/strategyUtils.ts +121 -0
  33. package/src/utils/weightUtils.ts +510 -0
  34. package/tests/add_liquidity_bidask.test.ts +180 -0
  35. package/tests/add_liquidity_curve.test.ts +244 -0
  36. package/tests/add_liquidity_spot.test.ts +262 -0
  37. package/tests/bin.test.ts +80 -0
  38. package/tests/config.test.ts +73 -0
  39. package/tests/ilm.test.ts +31 -0
  40. package/tests/partner.test.ts +74 -0
  41. package/tests/pool.test.ts +174 -0
  42. package/tests/position.test.ts +76 -0
  43. package/tests/remove_liquidity.test.ts +137 -0
  44. package/tests/swap.test.ts +96 -0
  45. package/tests/tsconfig.json +26 -0
  46. package/tsconfig.json +5 -0
  47. package/tsup.config.ts +9 -0
package/README.md ADDED
@@ -0,0 +1,654 @@
1
+ # @cetusprotocol/dlmm-sdk
2
+
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
+
5
+ ## Getting Started
6
+
7
+ ## How to Use the DLMM SDK?
8
+
9
+ ### Installation
10
+
11
+ To start using the `DLMM SDK`, you first need to install it in your TypeScript project:
12
+
13
+ ```bash
14
+ npm install @cetusprotocol/dlmm-sdk
15
+ ```
16
+
17
+ ### Setup
18
+
19
+ Import the SDK into the TypeScript file where you intend to use it:
20
+
21
+ ```typescript
22
+ import { CetusDlmmSDK } from '@cetusprotocol/dlmm-sdk'
23
+ ```
24
+
25
+ ### Initializing the SDK
26
+
27
+ Initialize the SDK with the required configuration parameters. This typically includes setting up the network if needed.
28
+
29
+ If you would like to use the mainnet network and the official Sui rpc url, you can do so as follows:
30
+
31
+ ```typescript
32
+ const sdk = CetusDlmmSDK.createSDK()
33
+ ```
34
+
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
+
37
+ ```typescript
38
+ const env = 'mainnet'
39
+ const full_rpc_url = 'YOUR_FULL_NODE_URL'
40
+
41
+ const sdk = CetusDlmmSDK.createSDK({ env })
42
+ ```
43
+
44
+ If you wish to set your own full node URL or SuiClient, you can do so as follows:
45
+
46
+ ```typescript
47
+ const sdk = CetusDlmmSDK.createSDK({ env, sui_client })
48
+ // or
49
+ const sdk = CetusDlmmSDK.createSDK({ env, full_rpc_url })
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ After linking your wallet, if you need use your wallet address to do something, you should set it by `sdk.setSenderAddress`.
55
+
56
+ ```typescript
57
+ const wallet = 'YOUR_WALLET_ADDRESS'
58
+
59
+ sdk.setSenderAddress(wallet)
60
+ ```
61
+
62
+ if you need to change your rpc url, you can do so as follows:
63
+
64
+ ```typescript
65
+ const new_rpc_url = 'YOUR_NEW_FULL_NODE_URL'
66
+
67
+ sdk.updateFullRpcUrl(new_rpc_url)
68
+ ```
69
+
70
+ ### Common Parameters
71
+
72
+ - `pool_id`: The ID of the liquidity pool
73
+ - `bin_id`: The ID of the bin in the pool
74
+ - `bin_step`: The step size between bins
75
+ - `coin_type_a` & `coin_type_b`: Coin type identifiers for the trading pair
76
+ - `coin_decimal_a` & `coin_decimal_b`: Decimal places for each coin type
77
+
78
+ ### 1. Pool Operations
79
+
80
+ #### Get Pool Information
81
+
82
+ ```typescript
83
+ // Get all pools
84
+ const pools = await sdk.Pool.getPools()
85
+
86
+ // Get specific pool
87
+ const pool = await sdk.Pool.getPool(pool_id)
88
+
89
+ // Get specific pools by their IDs
90
+ const assign_pools = await sdk.Pool.getAssignPoolList([
91
+ '0x...',
92
+ // Add more pool IDs as needed
93
+ ])
94
+
95
+ // Get bin information
96
+ const bin_info = await sdk.Pool.getBinInfo(pool_id, bin_id, bin_step)
97
+
98
+ // Get pool bin information
99
+ const pool_bin_info = await sdk.Pool.getPoolBinInfo(pool_id)
100
+
101
+ // Get bin step configurations
102
+ const bin_step_configs = await sdk.Pool.getBinStepConfigs()
103
+
104
+ // Get pool transaction list
105
+ const pool_transactions = await sdk.Pool.getPoolTransactionList({
106
+ pool_id: '0x...',
107
+ pagination_args: { limit: 10 }
108
+ })
109
+ ```
110
+
111
+ #### Create Pool
112
+
113
+ There are two ways to create a pool:
114
+
115
+ **Method 1: Create Pool Only**
116
+
117
+ ```typescript
118
+ // Create a new pool without adding liquidity
119
+ const bin_step = 2
120
+ const base_factor = 10000
121
+ const price = '1.1'
122
+ const active_id = BinUtils.getBinIdFromPrice(price, bin_step, true, 6, 6)
123
+
124
+ const tx = new Transaction()
125
+ await sdk.Pool.createPoolPayload({
126
+ active_id,
127
+ bin_step,
128
+ coin_type_a: '0x...::usdc::USDC',
129
+ coin_type_b: '0x...::usdt::USDT',
130
+ base_factor,
131
+ }, tx)
132
+ ```
133
+
134
+ **Method 2: Create Pool and Add Liquidity in One Transaction**
135
+
136
+ ```typescript
137
+ // Create pool and add liquidity in one transaction
138
+ const bin_step = 2
139
+ const base_factor = 10000
140
+ const price = '1.1'
141
+ const active_id = BinUtils.getBinIdFromPrice(price, bin_step, true, 6, 6)
142
+
143
+ // Calculate liquidity distribution
144
+ const bin_infos = sdk.Position.calculateAddLiquidityInfo({
145
+ active_id,
146
+ bin_step,
147
+ lower_bin_id: active_id - 10,
148
+ upper_bin_id: active_id + 10,
149
+ amount_a_in_active_bin: '0',
150
+ amount_b_in_active_bin: '0',
151
+ strategy_type: StrategyType.Spot,
152
+ coin_amount: '10000000',
153
+ fix_amount_a: true,
154
+ })
155
+
156
+ const createAndAddTx = await sdk.Pool.createPoolAndAddLiquidityPayload({
157
+ active_id,
158
+ lower_bin_id: active_id - 10,
159
+ upper_bin_id: active_id + 10,
160
+ bin_step,
161
+ bin_infos,
162
+ coin_type_a: '0x14a71d857b34677a7d57e0feb303df1adb515a37780645ab763d42ce8d1a5e48::usdc::USDC',
163
+ coin_type_b: '0x14a71d857b34677a7d57e0feb303df1adb515a37780645ab763d42ce8d1a5e48::eth::ETH',
164
+ strategy_type: StrategyType.Spot,
165
+ use_bin_infos: false,
166
+ base_factor,
167
+ })
168
+ ```
169
+
170
+ ### 2. Position Operations
171
+
172
+ #### Get Position Information
173
+
174
+ ```typescript
175
+ // Get owner's position list
176
+ const positions = await sdk.Position.getOwnerPositionList(wallet)
177
+
178
+ // Get specific position
179
+ const position = await sdk.Position.getPosition(position_id)
180
+ ```
181
+
182
+ ### 3. Fee Operations
183
+
184
+ #### Fee and Reward Calculation
185
+
186
+ To calculate fees and rewards for a position, you can use the `fetchPositionFeeAndReward` method. This method allows you to get both fee and reward data for one or multiple positions:
187
+
188
+ ```typescript
189
+ // First get the pool information
190
+ const pool = await sdk.Pool.getPool(pool_id)
191
+ const { id, coin_type_a, coin_type_b, reward_manager } = pool
192
+
193
+ // Fetch fee and reward data
194
+ const { feeData, rewardData } = await sdk.Position.fetchPositionFeeAndReward([
195
+ {
196
+ pool_id: id,
197
+ position_id: position_id,
198
+ reward_coins: reward_manager.rewards.map((reward) => reward.reward_coin),
199
+ coin_type_a,
200
+ coin_type_b,
201
+ },
202
+ ])
203
+
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
+ // }
212
+
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
+ // }
222
+ ```
223
+
224
+ #### Fee Collection
225
+
226
+ You can collect fees from your positions in several ways:
227
+
228
+ 1. **Collect Fees and Rewards Together**:
229
+ ```typescript
230
+ // Build collect fee and reward transaction
231
+ const tx = await sdk.Position.collectRewardAndFeePayload([{
232
+ pool_id,
233
+ position_id,
234
+ reward_coins: reward_manager.rewards.map((reward) => reward.reward_coin),
235
+ coin_type_a,
236
+ coin_type_b
237
+ }])
238
+
239
+ // Simulate or send the transaction
240
+ const sim_result = await sdk.FullClient.sendSimulationTransaction(tx, wallet)
241
+ ```
242
+
243
+ ### 4. Liquidity Operations
244
+
245
+ #### Add Liquidity
246
+
247
+ There are three strategies for adding liquidity: Spot, BidAsk, and Curve. Here's how to use each:
248
+
249
+ 1. **Spot Strategy**:
250
+ ```typescript
251
+ // Get pool information
252
+ const pool = await sdk.Pool.getPool(pool_id)
253
+ const { active_id, bin_step, bin_manager } = pool
254
+
255
+ // Get amounts in active bin if it's within the range
256
+ const amounts_in_active_bin = await sdk.Position.getActiveBinIfInRange(
257
+ bin_manager.bin_manager_handle,
258
+ lower_bin_id,
259
+ upper_bin_id,
260
+ active_id,
261
+ bin_step
262
+ )
263
+
264
+ // Calculate liquidity distribution
265
+ const calculateOption = {
266
+ amount_a: '1000000',
267
+ amount_b: '1200000',
268
+ active_id,
269
+ bin_step,
270
+ lower_bin_id: -10,
271
+ upper_bin_id: 10,
272
+ amount_a_in_active_bin: amounts_in_active_bin?.amount_a || '0',
273
+ amount_b_in_active_bin: amounts_in_active_bin?.amount_b || '0',
274
+ strategy_type: StrategyType.Spot
275
+ }
276
+ const bin_infos = sdk.Position.calculateAddLiquidityInfo(calculateOption)
277
+
278
+ // For new position
279
+ const addOption = {
280
+ 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
287
+ }
288
+ const tx = sdk.Position.addLiquidityPayload(addOption)
289
+
290
+ // For existing position
291
+ const addOption = {
292
+ pool_id,
293
+ bin_infos,
294
+ coin_type_a: pool.coin_type_a,
295
+ coin_type_b: pool.coin_type_b,
296
+ active_id,
297
+ position_id,
298
+ collect_fee: true,
299
+ reward_coins: []
300
+ }
301
+ const tx = sdk.Position.addLiquidityPayload(addOption)
302
+ ```
303
+
304
+ Note: The `amount_a_in_active_bin` and `amount_b_in_active_bin` parameters are used to calculate the correct liquidity distribution when the active bin is within your position's range. These values are obtained using the `getActiveBinIfInRange` method, which:
305
+ 1. Checks if the active bin is within your specified range
306
+ 2. Returns the amounts of both tokens in the active bin if it is within range
307
+ 3. Returns undefined if the active bin is outside the range
308
+
309
+ 2. **BidAsk Strategy**:
310
+ ```typescript
311
+ // Similar to Spot strategy but with different strategy_type
312
+ const calculateOption = {
313
+ amount_a: '1000000',
314
+ amount_b: '1200000',
315
+ active_id,
316
+ bin_step,
317
+ lower_bin_id: -10,
318
+ upper_bin_id: 10,
319
+ amount_a_in_active_bin: '0',
320
+ amount_b_in_active_bin: '0',
321
+ strategy_type: StrategyType.BidAsk
322
+ }
323
+ ```
324
+
325
+ 3. **Curve Strategy**:
326
+ ```typescript
327
+ // Similar to Spot strategy but with different strategy_type
328
+ const calculateOption = {
329
+ amount_a: '1000000',
330
+ amount_b: '1200000',
331
+ active_id,
332
+ bin_step,
333
+ lower_bin_id: -10,
334
+ upper_bin_id: 10,
335
+ amount_a_in_active_bin: '0',
336
+ amount_b_in_active_bin: '0',
337
+ strategy_type: StrategyType.Curve
338
+ }
339
+ ```
340
+
341
+ 4. **Fixed Amount Strategy**:
342
+ ```typescript
343
+ // Calculate with fixed amount of one token
344
+ const calculateOption = {
345
+ coin_amount: '1000000',
346
+ fix_amount_a: true, // true for token A, false for token B
347
+ active_id,
348
+ bin_step,
349
+ lower_bin_id: -10,
350
+ upper_bin_id: 10,
351
+ amount_a_in_active_bin: '0',
352
+ amount_b_in_active_bin: '0',
353
+ strategy_type: StrategyType.Spot // or BidAsk or Curve
354
+ }
355
+ ```
356
+
357
+ 5. **Add Liquidity with Price**:
358
+ ```typescript
359
+ // Add liquidity with specific price range
360
+ const addOption = {
361
+ pool_id,
362
+ bin_infos,
363
+ coin_type_a: pool.coin_type_a,
364
+ coin_type_b: pool.coin_type_b,
365
+ price_base_coin: 'coin_a',
366
+ price: price.toString(),
367
+ lower_price,
368
+ upper_price,
369
+ bin_step,
370
+ amount_a_in_active_bin: amounts_in_active_bin?.amount_a || '0',
371
+ amount_b_in_active_bin: amounts_in_active_bin?.amount_b || '0',
372
+ strategy_type: StrategyType.Spot,
373
+ decimals_a: 6,
374
+ decimals_b: 6,
375
+ max_bin_slippage: 0.01,
376
+ active_id,
377
+ // If use_bin_infos is true, liquidity is allocated according to bin_infos; otherwise, it is calculated internally by the contract
378
+ use_bin_infos: false,
379
+ }
380
+ const tx = sdk.Position.addLiquidityWithPricePayload(addOption)
381
+ ```
382
+
383
+ #### Remove Liquidity
384
+
385
+ There are two ways to remove liquidity:
386
+
387
+ 1. **Remove with Both Amounts**:
388
+ ```typescript
389
+ // Get position and pool information
390
+ const pool = await sdk.Pool.getPool(pool_id)
391
+ const position = await sdk.Position.getPosition(position_id)
392
+ const { active_id, bin_step, bin_manager } = pool
393
+
394
+ // Get active bin information
395
+ const active_bin = await sdk.Pool.getBinInfo(bin_manager.bin_manager_handle, active_id, bin_step)
396
+ const liquidity_shares_data = parseLiquidityShares(position.liquidity_shares, bin_step, position.lower_bin_id, active_bin)
397
+
398
+ // Calculate removal amounts
399
+ const calculateOption = {
400
+ bins: liquidity_shares_data.bins,
401
+ active_id,
402
+ fix_amount_a: true,
403
+ coin_amount: '100000'
404
+ }
405
+ const bin_infos = sdk.Position.calculateRemoveLiquidityInfo(calculateOption)
406
+
407
+ // Build and send transaction
408
+ const removeOption = {
409
+ pool_id,
410
+ bin_infos,
411
+ coin_type_a: pool.coin_type_a,
412
+ coin_type_b: pool.coin_type_b,
413
+ position_id,
414
+ active_id,
415
+ slippage: 0.01,
416
+ reward_coins: [],
417
+ collect_fee: true,
418
+ reward_coins: [],
419
+ bin_step,
420
+ remove_percent: 0.5, // If remove_percent is specified, bin_infos will not be effective
421
+ }
422
+ const tx = sdk.Position.removeLiquidityPayload(removeOption)
423
+ ```
424
+
425
+ 2. **Remove Only One Token**:
426
+ ```typescript
427
+ const calculateOption = {
428
+ bins: liquidity_shares_data.bins,
429
+ active_id,
430
+ is_only_a: true, // true for token A, false for token B
431
+ coin_amount: '100000'
432
+ }
433
+ ```
434
+
435
+ #### Close Position
436
+
437
+ ```typescript
438
+ // Close position (This will collect all fees, rewards and remove all liquidity)
439
+ const tx = sdk.Position.closePositionPayload({
440
+ pool_id,
441
+ position_id,
442
+ coin_type_a,
443
+ coin_type_b,
444
+ reward_coins: pool.reward_manager.rewards.map(reward => reward.reward_coin) // Required: Must include all reward coin types from the pool
445
+ })
446
+
447
+ // Simulate or send the transaction
448
+ const sim_result = await sdk.FullClient.sendSimulationTransaction(tx, wallet)
449
+ ```
450
+
451
+ Note: Closing a position will:
452
+ 1. Collect all accumulated fees
453
+ 2. Collect all pending rewards (must include all reward coins from the pool)
454
+ 3. Remove all liquidity from the position
455
+ 4. Delete the position
456
+
457
+ ### 5. Swap Operations
458
+
459
+ ```typescript
460
+ // Get pool information
461
+ const pool = await sdk.Pool.getPool(pool_id)
462
+ const { coin_type_a, coin_type_b } = pool
463
+
464
+ // Get swap quote
465
+ const quote_obj = await sdk.Swap.preSwapQuote({
466
+ pool_id,
467
+ a2b: true, // true for A to B, false for B to A
468
+ by_amount_in: true, // true for exact input, false for exact output
469
+ in_amount: '2000000',
470
+ coin_type_a,
471
+ coin_type_b
472
+ })
473
+
474
+ // Build and send swap transaction
475
+ const tx = sdk.Swap.swapPayload({
476
+ coin_type_a,
477
+ coin_type_b,
478
+ quote_obj,
479
+ by_amount_in: true,
480
+ slippage: 0.01
481
+ })
482
+ ```
483
+
484
+ ### 6. Partner Operations
485
+
486
+ #### Partner Management
487
+
488
+ ```typescript
489
+ // Get partner list
490
+ const partnerList = await sdk.Partner.getPartnerList()
491
+
492
+ // Get specific partner
493
+ const partner = await sdk.Partner.getPartner(partner_id)
494
+
495
+ // Get partner capability ID
496
+ const partnerCapId = await sdk.Partner.getPartnerCapId(account, partner_id)
497
+
498
+ // Get partner balance
499
+ const partnerBalance = await sdk.Partner.getPartnerBalance(partner_id)
500
+
501
+ // Create partner
502
+ const start_time = Math.floor(Date.now() / 1000) + 5000
503
+ const tx = sdk.Partner.createPartnerPayload({
504
+ name: 'test partner',
505
+ ref_fee_rate: 0.01,
506
+ start_time,
507
+ end_time: start_time + 9 * 24 * 3600,
508
+ recipient: account,
509
+ })
510
+
511
+ // Update referral fee rate
512
+ const updateFeeTx = await sdk.Partner.updateRefFeeRatePayload({
513
+ partner_id: '0x9d171399393e3cbedffc24269eb606e735fb56fee17c15153eb5e2d5274a3677',
514
+ ref_fee_rate: 0.02,
515
+ })
516
+
517
+ // Update time range
518
+ const start_time = Math.floor(Date.now() / 1000)
519
+ const updateTimeTx = await sdk.Partner.updateTimeRangePayload({
520
+ partner_id: '0x9d171399393e3cbedffc24269eb606e735fb56fee17c15153eb5e2d5274a3677',
521
+ start_time,
522
+ end_time: start_time + 10 * 7 * 24 * 3600,
523
+ })
524
+ ```
525
+
526
+ ### 7. Reward Operations
527
+
528
+ #### Reward Management
529
+
530
+ ```typescript
531
+ // Initialize rewards for a pool
532
+ const initTx = sdk.Reward.initRewardPayload({
533
+ pool_id,
534
+ reward_coin_types: ['0x2::sui::SUI', '0x5::usdc::USDC']
535
+ })
536
+
537
+ // Add reward to a pool
538
+ const addRewardTx = sdk.Reward.addRewardPayload({
539
+ pool_id,
540
+ reward_coin_type: '0x2::sui::SUI',
541
+ reward_amount: '1000000',
542
+ end_time_seconds: Math.floor(Date.now() / 1000) + 30 * 24 * 3600, // 30 days
543
+ start_time_seconds: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
544
+ })
545
+
546
+ // Update reward access (public/private)
547
+ const accessTx = sdk.Reward.updateRewardAccessPayload({
548
+ pool_id,
549
+ type: 'to_public', // or 'to_private'
550
+ })
551
+
552
+ // Manage reward whitelist
553
+ const whitelistTx = sdk.Reward.updateRewardWhiteListPayload({
554
+ reward_coin_types: ['0x2::sui::SUI'],
555
+ type: 'add' // or 'remove'
556
+ })
557
+ ```
558
+
559
+ ### 8. Bin Operations
560
+
561
+ The SDK provides utility functions for working with bins and prices through the `BinUtils` class:
562
+
563
+ ```typescript
564
+ import { BinUtils } from '@cetusprotocol/dlmm-sdk'
565
+
566
+ // Convert price to bin ID
567
+ const binId = BinUtils.getBinIdFromPrice(
568
+ '1040.07', // price
569
+ 2, // bin step
570
+ true, // is base coin A
571
+ 6, // decimals for coin A
572
+ 9 // decimals for coin B
573
+ )
574
+
575
+ // Convert bin ID to price
576
+ const price = BinUtils.getPriceFromBinId(
577
+ -4787, // bin ID
578
+ 2, // bin step
579
+ 6, // decimals for coin A
580
+ 9 // decimals for coin B
581
+ )
582
+
583
+ // Get Q price from bin ID
584
+ const q_price = BinUtils.getQPriceFromId(
585
+ -4400, // bin ID
586
+ 100 // bin step
587
+ )
588
+
589
+ // Get price per lamport from Q price
590
+ const price_per_lamport = BinUtils.getPricePerLamportFromQPrice(q_price)
591
+
592
+ // Get liquidity from amounts
593
+ const liquidity = BinUtils.getLiquidity('0', '266666', '18431994054197767090')
594
+
595
+ // Get amount A from liquidity
596
+ const amountA = BinUtils.getAmountAFromLiquidity('4101094304427826916657468', '18461505896777422276')
597
+
598
+ // Get amount B from liquidity
599
+ const amountB = BinUtils.getAmountBFromLiquidity('4919119455159831291232256')
600
+
601
+ // Get amounts from liquidity with ratio
602
+ const [amountA, amountB] = BinUtils.getAmountsFromLiquidityWithRatio(
603
+ '4510099798813469403250688',
604
+ '18446744073709551616',
605
+ 0.9 // ratio
606
+ )
607
+
608
+ // Split bin liquidity info
609
+ const split_bin_infos = BinUtils.splitBinLiquidityInfo(bin_infos, 0, 70)
610
+ ```
611
+
612
+ These utility functions are particularly useful when:
613
+ - Setting up price ranges for liquidity positions
614
+ - Calculating optimal bin ranges for trading strategies
615
+ - Converting between different price representations
616
+ - Managing liquidity distributions across bins
617
+
618
+ ### 9. Advanced Operations
619
+
620
+ #### Validate Active ID Slippage
621
+
622
+ ```typescript
623
+ // Validate that the active ID hasn't moved too much
624
+ const isValid = await sdk.Position.validateActiveIdSlippage({
625
+ pool_id,
626
+ active_id,
627
+ max_bin_slippage: 0.01
628
+ })
629
+ ```
630
+
631
+ #### Update Position Fee and Rewards
632
+
633
+ ```typescript
634
+ // Update position fee and reward information
635
+ await sdk.Position.updatePositionFeeAndRewards({
636
+ pool_id,
637
+ position_id,
638
+ coin_type_a,
639
+ coin_type_b
640
+ })
641
+ ```
642
+
643
+ ## More About Cetus
644
+
645
+ Use the following links to learn more about Cetus:
646
+
647
+ Learn more about working with Cetus in the [Cetus Documentation](https://cetus-1.gitbook.io/cetus-docs).
648
+
649
+ Join the Cetus community on [Cetus Discord](https://discord.com/channels/1009749448022315008/1009751382783447072).
650
+
651
+ ## License
652
+
653
+ MIT
654
+