@cetusprotocol/sui-clmm-sdk 1.0.0

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 (64) hide show
  1. package/.turbo/turbo-build.log +11100 -0
  2. package/README.md +108 -0
  3. package/dist/index.d.mts +2251 -0
  4. package/dist/index.d.ts +2251 -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/docs/add_liquidity.md +145 -0
  10. package/docs/close_position.md +57 -0
  11. package/docs/collect_fees.md +37 -0
  12. package/docs/create_clmm_pool.md +228 -0
  13. package/docs/error_code.md +69 -0
  14. package/docs/get_clmm_pools.md +92 -0
  15. package/docs/get_positions.md +70 -0
  16. package/docs/get_reward.md +53 -0
  17. package/docs/get_ticks.md +39 -0
  18. package/docs/migrate_to_version_6.0.md +143 -0
  19. package/docs/open_position.md +224 -0
  20. package/docs/partner_swap.md +60 -0
  21. package/docs/pre_swap.md +136 -0
  22. package/docs/remove_liquidity.md +124 -0
  23. package/docs/swap.md +153 -0
  24. package/docs/utils.md +85 -0
  25. package/package.json +37 -0
  26. package/src/config/index.ts +2 -0
  27. package/src/config/mainnet.ts +41 -0
  28. package/src/config/testnet.ts +40 -0
  29. package/src/errors/errors.ts +93 -0
  30. package/src/errors/index.ts +1 -0
  31. package/src/index.ts +10 -0
  32. package/src/math/apr.ts +167 -0
  33. package/src/math/index.ts +1 -0
  34. package/src/modules/configModule.ts +540 -0
  35. package/src/modules/index.ts +5 -0
  36. package/src/modules/poolModule.ts +1066 -0
  37. package/src/modules/positionModule.ts +932 -0
  38. package/src/modules/rewarderModule.ts +430 -0
  39. package/src/modules/swapModule.ts +389 -0
  40. package/src/sdk.ts +131 -0
  41. package/src/types/clmm_type.ts +1002 -0
  42. package/src/types/clmmpool.ts +366 -0
  43. package/src/types/config_type.ts +241 -0
  44. package/src/types/index.ts +8 -0
  45. package/src/types/sui.ts +124 -0
  46. package/src/types/token_type.ts +189 -0
  47. package/src/utils/common.ts +426 -0
  48. package/src/utils/index.ts +3 -0
  49. package/src/utils/positionUtils.ts +434 -0
  50. package/src/utils/swapUtils.ts +499 -0
  51. package/tests/add_liquidity.test.ts +121 -0
  52. package/tests/add_liquidity_fix_token.test.ts +182 -0
  53. package/tests/apr.test.ts +71 -0
  54. package/tests/cetus_config.test.ts +26 -0
  55. package/tests/collect_fees.test.ts +11 -0
  56. package/tests/pool.test.ts +267 -0
  57. package/tests/position.test.ts +145 -0
  58. package/tests/remove_liquidity.test.ts +119 -0
  59. package/tests/rewarder.test.ts +60 -0
  60. package/tests/sdk_config.test.ts +49 -0
  61. package/tests/swap.test.ts +254 -0
  62. package/tests/tsconfig.json +26 -0
  63. package/tsconfig.json +5 -0
  64. package/tsup.config.ts +10 -0
@@ -0,0 +1,93 @@
1
+ import { BaseError } from '@cetusprotocol/common-sdk'
2
+
3
+ export enum SwapErrorCode {
4
+ InvalidSqrtPriceLimitDirection = `InvalidSqrtPriceLimitDirection`,
5
+ ZeroTradableAmount = `ZeroTradableAmount`,
6
+ AmountOutBelowMinimum = `AmountOutBelowMinimum`,
7
+ AmountInAboveMaximum = `AmountInAboveMaximum`,
8
+ NextTickNotFound = `NextTickNotFound`,
9
+ TickArraySequenceInvalid = `TickArraySequenceInvalid`,
10
+ TickArrayCrossingAboveMax = `TickArrayCrossingAboveMax`,
11
+ TickArrayIndexNotInitialized = `TickArrayIndexNotInitialized`,
12
+ ParamsLengthNotEqual = `ParamsLengthNotEqual`,
13
+ }
14
+
15
+ export enum PositionErrorCode {
16
+ InvalidTickEvent = `InvalidTickEvent`,
17
+ InvalidPositionObject = `InvalidPositionObject`,
18
+ InvalidPositionRewardObject = `InvalidPositionRewardObject`,
19
+ InvalidParams = `InvalidParams`,
20
+ }
21
+
22
+ export enum PoolErrorCode {
23
+ InvalidCoinTypeSequence = `InvalidCoinTypeSequence`,
24
+ InvalidTickIndex = `InvalidTickIndex`,
25
+ InvalidPoolObject = `InvalidPoolObject`,
26
+ InvalidTickObjectId = `InvalidTickObjectId`,
27
+ InvalidTickObject = `InvalidTickObject`,
28
+ InvalidTickFields = `InvalidTickFields`,
29
+ PoolsNotFound = `PoolsNotFound`,
30
+ StatsPoolsUrlNotSet = `StatsPoolsUrlNotSet`,
31
+ FetchError = `FetchError`,
32
+ }
33
+
34
+ export enum PartnerErrorCode {
35
+ NotFoundPartnerObject = `NotFoundPartnerObject`,
36
+ InvalidPartnerRefFeeFields = `InvalidPartnerRefFeeFields`,
37
+ }
38
+
39
+ export enum ConfigErrorCode {
40
+ InvalidConfig = `InvalidConfig`,
41
+ InvalidConfigHandle = `InvalidConfigHandle`,
42
+ InvalidSimulateAccount = `InvalidSimulateAccount`,
43
+ }
44
+
45
+ export enum UtilsErrorCode {
46
+ InvalidSendAddress = `InvalidSendAddress`,
47
+ InvalidRecipientAddress = `InvalidRecipientAddress`,
48
+ InvalidRecipientAndAmountLength = `InvalidRecipientAndAmountLength`,
49
+ InsufficientBalance = `InsufficientBalance`,
50
+ InvalidTarget = `InvalidTarget`,
51
+ InvalidTransactionBuilder = `InvalidTransactionBuilder`,
52
+ }
53
+
54
+ export enum RouterErrorCode {
55
+ InvalidCoin = `InvalidCoin`,
56
+ NotFoundPath = `NotFoundPath`,
57
+ NoDowngradeNeedParams = `NoDowngradeNeedParams`,
58
+ InvalidSwapCountUrl = `InvalidSwapCountUrl`,
59
+ InvalidTransactionBuilder = `InvalidTransactionBuilder`,
60
+ InvalidServerResponse = `InvalidServerResponse`,
61
+ }
62
+
63
+ export enum TypesErrorCode {
64
+ InvalidType = `InvalidType`,
65
+ }
66
+
67
+ export type ClmmErrorCode =
68
+ | SwapErrorCode
69
+ | PoolErrorCode
70
+ | PositionErrorCode
71
+ | PartnerErrorCode
72
+ | ConfigErrorCode
73
+ | UtilsErrorCode
74
+ | RouterErrorCode
75
+ | TypesErrorCode
76
+
77
+ export class ClmmError extends BaseError {
78
+ constructor(message: string, errorCode?: ClmmErrorCode, details?: Record<string, any>) {
79
+ super(message, errorCode || 'UnknownError', details)
80
+ }
81
+
82
+ static isVaultsErrorCode(e: any, code: ClmmErrorCode): boolean {
83
+ return this.isErrorCode<ClmmError>(e, code)
84
+ }
85
+ }
86
+
87
+ export const handleError = (code: ClmmErrorCode, error: Error, details?: Record<string, any>) => {
88
+ throw new ClmmError(error.message, code, details)
89
+ }
90
+
91
+ export const handleMessageError = (code: ClmmErrorCode, message: string, details?: Record<string, any>) => {
92
+ throw new ClmmError(message, code, details)
93
+ }
@@ -0,0 +1 @@
1
+ export * from './errors'
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { CetusClmmSDK, SdkOptions } from './sdk'
2
+
3
+ export * from './utils'
4
+ export * from './math'
5
+ export * from './types'
6
+ export * from './modules'
7
+ export * from './config'
8
+ export * from './errors'
9
+ export { CetusClmmSDK, SdkOptions }
10
+ export default CetusClmmSDK
@@ -0,0 +1,167 @@
1
+ import BN from 'bn.js'
2
+ import { MathUtil, TickMath } from '@cetusprotocol/common-sdk'
3
+ import Decimal from 'decimal.js'
4
+
5
+ const D365 = new BN(365)
6
+ const H24 = new BN(24)
7
+ const S3600 = new BN(3600)
8
+ const B05 = new BN(0.5)
9
+
10
+ export function estPoolAPR(pre_block_reward: BN, reward_price: BN, total_trading_fee: BN, total_liquidity_value: BN): BN {
11
+ const annualRate = D365.mul(H24).mul(S3600).mul(B05)
12
+
13
+ const APR = annualRate.mul(pre_block_reward.mul(reward_price).add(total_trading_fee).div(total_liquidity_value))
14
+
15
+ return APR
16
+ }
17
+
18
+ function calculatePoolValidTVL(
19
+ amount_a: BN,
20
+ amount_b: BN,
21
+ decimals_a: number,
22
+ decimals_b: number,
23
+ coin_a_price: Decimal,
24
+ coin_b_price: Decimal
25
+ ): Decimal {
26
+ const poolValidAmountA = new Decimal(amount_a.toString()).div(new Decimal(10 ** decimals_a))
27
+ const poolValidAmountB = new Decimal(amount_b.toString()).div(new Decimal(10 ** decimals_b))
28
+
29
+ const TVL = poolValidAmountA.mul(coin_a_price).add(poolValidAmountB.mul(coin_b_price))
30
+
31
+ return TVL
32
+ }
33
+
34
+ export type estPosAPRResult = {
35
+ fee_apr: Decimal
36
+ pos_rewarder_0_apr: Decimal
37
+ pos_rewarder_1_apr: Decimal
38
+ pos_rewarder_2_apr: Decimal
39
+ }
40
+
41
+ export function estPositionAPRWithDeltaMethod(
42
+ current_tick_index: number,
43
+ lower_tick_index: number,
44
+ upper_tick_index: number,
45
+ current_sqrt_price_x64: BN,
46
+ pool_liquidity: BN,
47
+ decimals_a: number,
48
+ decimals_b: number,
49
+ decimals_rewarder_0: number,
50
+ decimals_rewarder_1: number,
51
+ decimals_rewarder_2: number,
52
+ fee_rate: number,
53
+ amount_a_str: string,
54
+ amount_b_str: string,
55
+ pool_amount_a: BN,
56
+ pool_amount_b: BN,
57
+ swap_volume_str: string,
58
+ pool_rewarders_0_str: string,
59
+ pool_rewarders_1_str: string,
60
+ pool_rewarders_2_str: string,
61
+ coin_a_price_str: string,
62
+ coin_b_price_str: string,
63
+ rewarder_0_price_str: string,
64
+ rewarder_1_price_str: string,
65
+ rewarder_2_price_str: string
66
+ ): estPosAPRResult {
67
+ const amount_a = new Decimal(amount_a_str)
68
+ const amount_b = new Decimal(amount_b_str)
69
+ const swap_volume = new Decimal(swap_volume_str)
70
+ const pool_rewarders_0 = new Decimal(pool_rewarders_0_str)
71
+ const pool_rewarders_1 = new Decimal(pool_rewarders_1_str)
72
+ const pool_rewarders_2 = new Decimal(pool_rewarders_2_str)
73
+ const coin_a_price = new Decimal(coin_a_price_str)
74
+ const coin_b_price = new Decimal(coin_b_price_str)
75
+ const rewarder_0_price = new Decimal(rewarder_0_price_str)
76
+ const rewarder_1_price = new Decimal(rewarder_1_price_str)
77
+ const rewarder_2_price = new Decimal(rewarder_2_price_str)
78
+
79
+ const lower_sqrt_price_x64 = TickMath.tickIndexToSqrtPriceX64(lower_tick_index)
80
+ const upper_sqrt_price_x64 = TickMath.tickIndexToSqrtPriceX64(upper_tick_index)
81
+ const lower_sqrt_price_d = MathUtil.toX64Decimal(MathUtil.fromX64(lower_sqrt_price_x64)).round()
82
+ const upper_sqrt_price_d = MathUtil.toX64Decimal(MathUtil.fromX64(upper_sqrt_price_x64)).round()
83
+ const current_sqrt_price_d = MathUtil.toX64Decimal(MathUtil.fromX64(current_sqrt_price_x64)).round()
84
+ let delta_liquidity
85
+ const liquidity_amount_0 = amount_a
86
+ .mul(new Decimal(10 ** decimals_a))
87
+ .mul(upper_sqrt_price_d.mul(lower_sqrt_price_d))
88
+ .div(upper_sqrt_price_d.sub(lower_sqrt_price_d))
89
+ .round()
90
+ const liquidity_amount_1 = amount_b
91
+ .mul(new Decimal(10 ** decimals_b))
92
+ .div(upper_sqrt_price_d.sub(lower_sqrt_price_d))
93
+ .round()
94
+ if (current_tick_index < lower_tick_index) {
95
+ delta_liquidity = liquidity_amount_0
96
+ } else if (current_tick_index > upper_tick_index) {
97
+ delta_liquidity = liquidity_amount_1
98
+ } else {
99
+ delta_liquidity = Decimal.min(liquidity_amount_0, liquidity_amount_1)
100
+ }
101
+ const delta_y = delta_liquidity.mul(current_sqrt_price_d.sub(lower_sqrt_price_d))
102
+ const delta_x = delta_liquidity.mul(upper_sqrt_price_d.sub(current_sqrt_price_d)).div(current_sqrt_price_d.mul(upper_sqrt_price_d))
103
+ const pos_valid_tvl = delta_x
104
+ .div(new Decimal(10 ** decimals_a))
105
+ .mul(coin_a_price)
106
+ .add(delta_y.div(new Decimal(10 ** decimals_b).mul(coin_b_price)))
107
+ const pool_valid_tvl = calculatePoolValidTVL(pool_amount_a, pool_amount_b, decimals_a, decimals_b, coin_a_price, coin_b_price)
108
+ const pos_valid_rate = pos_valid_tvl.div(pool_valid_tvl)
109
+
110
+ const fee_apr = delta_liquidity.eq(new Decimal(0))
111
+ ? new Decimal(0)
112
+ : new Decimal(fee_rate / 10000)
113
+ .mul(swap_volume)
114
+ .mul(
115
+ new Decimal(delta_liquidity.toString()).div(new Decimal(pool_liquidity.toString()).add(new Decimal(delta_liquidity.toString())))
116
+ )
117
+ .div(pos_valid_tvl)
118
+
119
+ const apr_coe = pos_valid_rate.eq(new Decimal(0)) ? new Decimal(0) : pos_valid_rate.mul(new Decimal(36500 / 7)).div(pos_valid_tvl)
120
+ const pos_rewarder_0_apr = pool_rewarders_0
121
+ .div(new Decimal(10 ** decimals_rewarder_0))
122
+ .mul(rewarder_0_price)
123
+ .mul(apr_coe)
124
+ const pos_rewarder_1_apr = pool_rewarders_1
125
+ .div(new Decimal(10 ** decimals_rewarder_1))
126
+ .mul(rewarder_1_price)
127
+ .mul(apr_coe)
128
+ const pos_rewarder_2_apr = pool_rewarders_2
129
+ .div(new Decimal(10 ** decimals_rewarder_2))
130
+ .mul(rewarder_2_price)
131
+ .mul(apr_coe)
132
+ return {
133
+ fee_apr,
134
+ pos_rewarder_0_apr,
135
+ pos_rewarder_1_apr,
136
+ pos_rewarder_2_apr,
137
+ }
138
+ }
139
+
140
+ export function estPositionAPRWithMultiMethod(
141
+ lower_user_price: number,
142
+ upper_user_price: number,
143
+ lower_hist_price: number,
144
+ upper_hist_price: number
145
+ ): Decimal {
146
+ const retro_lower = Math.max(lower_user_price, lower_hist_price)
147
+ const retro_upper = Math.min(upper_user_price, upper_hist_price)
148
+ const retro_range = retro_upper - retro_lower
149
+ const user_range = upper_user_price - lower_user_price
150
+ const hist_range = upper_hist_price - lower_hist_price
151
+ const user_range_d = new Decimal(user_range.toString())
152
+ const hist_range_d = new Decimal(hist_range.toString())
153
+ const retro_range_d = new Decimal(retro_range.toString())
154
+
155
+ let m = new Decimal('0')
156
+ if (retro_range < 0) {
157
+ m = new Decimal('0')
158
+ } else if (user_range === retro_range) {
159
+ m = hist_range_d.div(retro_range_d)
160
+ } else if (hist_range === retro_range) {
161
+ m = retro_range_d.div(user_range_d)
162
+ } else {
163
+ m = retro_range_d.mul(retro_range_d).div(hist_range_d).div(user_range_d)
164
+ }
165
+
166
+ return m
167
+ }
@@ -0,0 +1 @@
1
+ export * from './apr'