@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,145 @@
1
+ import BN from 'bn.js'
2
+ import { adjustForCoinSlippage, ClmmPoolUtil, Percentage, printTransaction, TickMath } from '@cetusprotocol/common-sdk'
3
+ import { buildTestAccount } from '@cetusprotocol/test-utils'
4
+ import 'isomorphic-fetch'
5
+ import CetusClmmSDK from '../src'
6
+
7
+ const poolId = '0xb8d7d9e66a60c239e7a60110efcf8de6c705580ed924d0dde141f4a0e2c90105'
8
+ const position_nft_id = '0xcf995f40b0f9c40a8b03e0b9d9554fea2bc12a18fe63db3a04c59c46be5c10be'
9
+ describe('Position add Liquidity Module', () => {
10
+ let send_key_pair = buildTestAccount()
11
+ const sdk = CetusClmmSDK.createSDK({ env: 'mainnet' })
12
+ sdk.setSenderAddress(send_key_pair.getPublicKey().toSuiAddress())
13
+
14
+ beforeEach(async () => {
15
+ send_key_pair = buildTestAccount()
16
+ })
17
+
18
+ test('get owner position list', async () => {
19
+ const res = await sdk.Position.getPositionList(sdk.getSenderAddress(), [])
20
+ console.log('getPositionList####', res)
21
+ expect(res.length).toBeGreaterThan(0)
22
+ })
23
+
24
+ test('get position event list', async () => {
25
+ const res = await sdk.Position.getPositionTransactionList({
26
+ pos_id: '0x568e0062a77626312e18fde331750cd8743245877ec75562b1c5165ab87f4a8f',
27
+ })
28
+ console.log('getPositionList####', res.data)
29
+ expect(res.data.length).toBeGreaterThan(0)
30
+ })
31
+
32
+ test('get pool position list', async () => {
33
+ const pool = await sdk.Pool.getPool('0xd4573bdd25c629127d54c5671d72a0754ef47767e6c01758d6dc651f57951e7d')
34
+ console.log('pool', pool)
35
+ const res = await sdk.Pool.getPositionList(pool.position_manager.positions_handle)
36
+ console.log('getPositionList####', res)
37
+ })
38
+
39
+ test('getPositionById', async () => {
40
+ const res = await sdk.Position.getPositionById('0x7cea8359f50318d88026d702462df7ce9d96a5b12f3efe9dce6d6450fba779a0')
41
+ console.log('getPositionById###', res)
42
+ })
43
+
44
+ test('getSimplePosition', async () => {
45
+ const res = await sdk.Position.getSimplePosition(position_nft_id)
46
+ console.log('getSimplePosition####', res)
47
+ })
48
+
49
+ test('getPositionInfo', async () => {
50
+ const pool = await sdk.Pool.getPool(poolId)
51
+ const res = await sdk.Position.getPosition(pool.position_manager.positions_handle, position_nft_id)
52
+ console.log('getPositionInfo####', res)
53
+ })
54
+
55
+ test('calculateFee', async () => {
56
+ const res = await sdk.Position.fetchPosFeeAmount([
57
+ {
58
+ pool_id: '0xb8d7d9e66a60c239e7a60110efcf8de6c705580ed924d0dde141f4a0e2c90105',
59
+ position_id: '0xcf995f40b0f9c40a8b03e0b9d9554fea2bc12a18fe63db3a04c59c46be5c10be',
60
+ coin_type_a: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',
61
+ coin_type_b: '0x2::sui::SUI',
62
+ },
63
+ ])
64
+ console.log('calculateFee####', res)
65
+ })
66
+
67
+ test('fetchPositionRewardList', async () => {
68
+ const pool = await sdk.Pool.getPool('0xb8d7d9e66a60c239e7a60110efcf8de6c705580ed924d0dde141f4a0e2c90105')
69
+ const res = await sdk.Pool.fetchPositionRewardList({
70
+ pool_id: '0xb8d7d9e66a60c239e7a60110efcf8de6c705580ed924d0dde141f4a0e2c90105',
71
+ coin_type_a: pool.coin_type_a,
72
+ coin_type_b: pool.coin_type_b,
73
+ })
74
+
75
+ console.log('getPosition####', res)
76
+ })
77
+
78
+ test('open position', async () => {
79
+ const pool = await sdk.Pool.getPool(poolId)
80
+ const lowerTick = TickMath.getPrevInitializeTickIndex(new BN(pool.current_tick_index).toNumber(), new BN(pool.tick_spacing).toNumber())
81
+ const upperTick = TickMath.getNextInitializeTickIndex(new BN(pool.current_tick_index).toNumber(), new BN(pool.tick_spacing).toNumber())
82
+
83
+ const openPositionPayload = sdk.Position.openPositionPayload({
84
+ coin_type_a: pool.coin_type_a,
85
+ coin_type_b: pool.coin_type_b,
86
+ tick_lower: lowerTick.toString(),
87
+ tick_upper: upperTick.toString(),
88
+ pool_id: pool.id,
89
+ })
90
+
91
+ printTransaction(openPositionPayload)
92
+
93
+ const transferTxn = await sdk.FullClient.executeTx(send_key_pair, openPositionPayload, true)
94
+ console.log('open position: ', JSON.stringify(transferTxn, null, 2))
95
+ })
96
+
97
+ test('close position', async () => {
98
+ const pool = await sdk.Pool.getPool(poolId)
99
+ const position = await sdk.Position.getPositionById(position_nft_id)
100
+
101
+ const lowerTick = Number(position.tick_lower_index)
102
+ const upperTick = Number(position.tick_upper_index)
103
+
104
+ const lowerSqrtPrice = TickMath.tickIndexToSqrtPriceX64(lowerTick)
105
+ const upperSqrtPrice = TickMath.tickIndexToSqrtPriceX64(upperTick)
106
+
107
+ const liquidity = new BN(position.liquidity)
108
+ const slippageTolerance = new Percentage(new BN(5), new BN(100))
109
+ const curSqrtPrice = new BN(pool.current_sqrt_price)
110
+
111
+ const coinAmounts = ClmmPoolUtil.getCoinAmountFromLiquidity(liquidity, curSqrtPrice, lowerSqrtPrice, upperSqrtPrice, false)
112
+ const { coin_amount_limit_a, coin_amount_limit_b } = adjustForCoinSlippage(coinAmounts, slippageTolerance, false)
113
+
114
+ const rewardCoinTypes = pool.rewarder_infos.map((rewarder) => rewarder.coin_type)
115
+
116
+ const closePositionPayload = await sdk.Position.closePositionPayload({
117
+ coin_type_a: pool.coin_type_a,
118
+ coin_type_b: pool.coin_type_b,
119
+ min_amount_a: coin_amount_limit_a.toString(),
120
+ min_amount_b: coin_amount_limit_b.toString(),
121
+ rewarder_coin_types: [...rewardCoinTypes],
122
+ pool_id: pool.id,
123
+ pos_id: position_nft_id,
124
+ collect_fee: true,
125
+ })
126
+
127
+ printTransaction(closePositionPayload)
128
+
129
+ const transferTxn = await sdk.FullClient.executeTx(send_key_pair, closePositionPayload, true)
130
+ console.log('close position: ', transferTxn)
131
+ })
132
+
133
+ test('collect_fee', async () => {
134
+ const pool = await sdk.Pool.getPool(poolId)
135
+ const collectFeePayload = await sdk.Position.collectFeePayload({
136
+ coin_type_a: pool.coin_type_a,
137
+ coin_type_b: pool.coin_type_b,
138
+ pool_id: pool.id,
139
+ pos_id: position_nft_id,
140
+ })
141
+
142
+ const transferTxn = await sdk.FullClient.executeTx(send_key_pair, collectFeePayload, true)
143
+ console.log('collect_fee: ', transferTxn)
144
+ })
145
+ })
@@ -0,0 +1,119 @@
1
+ import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519'
2
+ import BN from 'bn.js'
3
+ import { adjustForCoinSlippage, ClmmPoolUtil, d, Percentage, printTransaction, TickMath } from '@cetusprotocol/common-sdk'
4
+ import { buildTestAccount } from '@cetusprotocol/test-utils'
5
+ import 'isomorphic-fetch'
6
+ import CetusClmmSDK, { RemoveLiquidityParams } from '../src'
7
+
8
+ let send_key_pair: Ed25519Keypair
9
+
10
+ const poolId = '0xb8d7d9e66a60c239e7a60110efcf8de6c705580ed924d0dde141f4a0e2c90105'
11
+ const position_nft_id = '0xcf995f40b0f9c40a8b03e0b9d9554fea2bc12a18fe63db3a04c59c46be5c10be'
12
+
13
+ describe('remove liquidity', () => {
14
+ const sdk = CetusClmmSDK.createSDK({ env: 'mainnet' })
15
+
16
+ beforeEach(async () => {
17
+ send_key_pair = buildTestAccount()
18
+ sdk.setSenderAddress(send_key_pair.getPublicKey().toSuiAddress())
19
+ })
20
+
21
+ test('getCoinAmountFromLiquidity', async () => {
22
+ const pool = await sdk.Pool.getPool(poolId)
23
+ const position = await sdk.Position.getPositionById(position_nft_id)
24
+ const curSqrtPrice = new BN(pool.current_sqrt_price)
25
+
26
+ const lowerSqrtPrice = TickMath.tickIndexToSqrtPriceX64(position.tick_lower_index)
27
+ const upperSqrtPrice = TickMath.tickIndexToSqrtPriceX64(position.tick_upper_index)
28
+ const coinAmounts = ClmmPoolUtil.getCoinAmountFromLiquidity(
29
+ new BN(Number(d(position.liquidity))),
30
+ curSqrtPrice,
31
+ lowerSqrtPrice,
32
+ upperSqrtPrice,
33
+ true
34
+ )
35
+
36
+ console.log('coinA: ', coinAmounts.coin_amount_a.toString())
37
+ console.log('coinB: ', coinAmounts.coin_amount_b.toString())
38
+ })
39
+
40
+ test('remove liquidity for input one token', async () => {
41
+ const pool = await sdk.Pool.getPool(poolId)
42
+ const position = await sdk.Position.getPositionById(position_nft_id)
43
+ const lowerTick = position.tick_lower_index
44
+ const upperTick = position.tick_upper_index
45
+ const coinAmount = new BN(592)
46
+ const fix_amount_a = true
47
+ const slippage = 0.05
48
+ const curSqrtPrice = new BN(pool.current_sqrt_price)
49
+
50
+ const liquidityInput = ClmmPoolUtil.estLiquidityAndCoinAmountFromOneAmounts(
51
+ lowerTick,
52
+ upperTick,
53
+ coinAmount,
54
+ fix_amount_a,
55
+ false,
56
+ slippage,
57
+ curSqrtPrice
58
+ )
59
+
60
+ const liquidity = liquidityInput.liquidity_amount.toString()
61
+
62
+ const removeLiquidityParams: RemoveLiquidityParams = {
63
+ coin_type_a: pool.coin_type_a,
64
+ coin_type_b: pool.coin_type_b,
65
+ delta_liquidity: liquidity,
66
+ min_amount_a: liquidityInput.coin_amount_limit_a,
67
+ min_amount_b: liquidityInput.coin_amount_limit_b,
68
+ pool_id: pool.id,
69
+ pos_id: position.pos_object_id,
70
+ rewarder_coin_types: [],
71
+ collect_fee: true,
72
+ }
73
+
74
+ const payload = await sdk.Position.removeLiquidityPayload(removeLiquidityParams)
75
+
76
+ printTransaction(payload)
77
+
78
+ const transferTxn = await sdk.FullClient.executeTx(send_key_pair, payload, true)
79
+ console.log('removeLiquidity: ', transferTxn)
80
+ })
81
+ test('remove liquidity for input liquidity', async () => {
82
+ const pool = await sdk.Pool.getPool(poolId)
83
+ const position = await sdk.Position.getPositionById(position_nft_id)
84
+
85
+ const lowerTick = Number(position.tick_lower_index)
86
+ const upperTick = Number(position.tick_upper_index)
87
+
88
+ const lowerSqrtPrice = TickMath.tickIndexToSqrtPriceX64(lowerTick)
89
+ const upperSqrtPrice = TickMath.tickIndexToSqrtPriceX64(upperTick)
90
+
91
+ const liquidity = new BN(position.liquidity)
92
+ const slippageTolerance = new Percentage(new BN(5), new BN(100))
93
+ const curSqrtPrice = new BN(pool.current_sqrt_price)
94
+
95
+ const coinAmounts = ClmmPoolUtil.getCoinAmountFromLiquidity(liquidity, curSqrtPrice, lowerSqrtPrice, upperSqrtPrice, false)
96
+ const { coin_amount_limit_a, coin_amount_limit_b } = adjustForCoinSlippage(coinAmounts, slippageTolerance, false)
97
+
98
+ const rewardCoinTypes = pool.rewarder_infos.map((rewarder) => rewarder.coin_type)
99
+
100
+ const removeLiquidityParams: RemoveLiquidityParams = {
101
+ coin_type_a: pool.coin_type_a,
102
+ coin_type_b: pool.coin_type_b,
103
+ delta_liquidity: liquidity.toString(),
104
+ min_amount_a: coin_amount_limit_a.toString(),
105
+ min_amount_b: coin_amount_limit_b.toString(),
106
+ pool_id: pool.id,
107
+ pos_id: position.pos_object_id,
108
+ rewarder_coin_types: [...rewardCoinTypes],
109
+ collect_fee: true,
110
+ }
111
+
112
+ const removeLiquidityTransactionPayload = await sdk.Position.removeLiquidityPayload(removeLiquidityParams)
113
+
114
+ printTransaction(removeLiquidityTransactionPayload)
115
+
116
+ const transferTxn = await sdk.FullClient.executeTx(send_key_pair, removeLiquidityTransactionPayload, true)
117
+ console.log('removeLiquidity: ', transferTxn)
118
+ })
119
+ })
@@ -0,0 +1,60 @@
1
+ import { buildTestAccount } from '@cetusprotocol/test-utils'
2
+ import 'isomorphic-fetch'
3
+ import CetusClmmSDK, { CollectRewarderParams } from '../src'
4
+
5
+ const poolId = '0xb8d7d9e66a60c239e7a60110efcf8de6c705580ed924d0dde141f4a0e2c90105'
6
+ const position_nft_id = '0xcf995f40b0f9c40a8b03e0b9d9554fea2bc12a18fe63db3a04c59c46be5c10be'
7
+ describe('Rewarder Module', () => {
8
+ const sdk = CetusClmmSDK.createSDK({ env: 'mainnet' })
9
+
10
+ test('emissionsEveryDay', async () => {
11
+ const emissionsEveryDay = await sdk.Rewarder.emissionsEveryDay(poolId)
12
+ console.log(emissionsEveryDay)
13
+ })
14
+
15
+ test('posRewardersAmount', async () => {
16
+ const pool = await sdk.Pool.getPool(poolId)
17
+ console.log('pool', pool)
18
+
19
+ const rewardCoinTypes = pool.rewarder_infos.map((rewarder) => rewarder.coin_type)
20
+
21
+ const res = await sdk.Rewarder.fetchPosRewardersAmount([
22
+ {
23
+ coin_type_a: pool?.coin_type_a,
24
+ coin_type_b: pool?.coin_type_b,
25
+ rewarder_types: rewardCoinTypes,
26
+ pool_id: pool.id,
27
+ position_id: position_nft_id,
28
+ },
29
+ ])
30
+ console.log('posRewardersAmount-res:', res)
31
+ })
32
+
33
+ test('batchFetchPositionRewarders', async () => {
34
+ const res = await sdk.Rewarder.batchFetchPositionRewarders([position_nft_id])
35
+ console.log('batchFetchPositionRewarders-res:', res)
36
+ })
37
+
38
+ test('collectPoolRewarderTransactionPayload', async () => {
39
+ const send_key_pair = buildTestAccount()
40
+ sdk.setSenderAddress(send_key_pair.getPublicKey().toSuiAddress())
41
+
42
+ const pool = await sdk.Pool.getPool(poolId)
43
+
44
+ const rewardCoinTypes = pool.rewarder_infos.map((rewarder) => rewarder.coin_type)
45
+
46
+ const collectRewarderParams: CollectRewarderParams = {
47
+ pool_id: pool.id,
48
+ pos_id: position_nft_id,
49
+ rewarder_coin_types: [...rewardCoinTypes],
50
+ coin_type_a: pool.coin_type_a,
51
+ coin_type_b: pool.coin_type_b,
52
+ collect_fee: true,
53
+ }
54
+
55
+ const collectRewarderPayload = await sdk.Rewarder.collectRewarderPayload(collectRewarderParams)
56
+
57
+ const transferTxn = await sdk.FullClient.executeTx(send_key_pair, collectRewarderPayload, true)
58
+ console.log('collectRewarderPayload: ', JSON.stringify(transferTxn, null, 2))
59
+ })
60
+ })
@@ -0,0 +1,49 @@
1
+ import 'isomorphic-fetch'
2
+ import { CetusClmmSDK } from '../src/sdk'
3
+
4
+ const sdk = CetusClmmSDK.createSDK({ env: 'mainnet' })
5
+
6
+ describe('sdk config', () => {
7
+ test('clmmConfig', async () => {
8
+ try {
9
+ const clmmConfig = await sdk.Pool.getClmmConfigs()
10
+ console.log('clmmConfig ', clmmConfig)
11
+ } catch (error) {
12
+ console.log(error)
13
+ }
14
+ })
15
+
16
+ test('cetusConfig', async () => {
17
+ try {
18
+ const cetusConfig = await sdk.CetusConfig.getCetusConfig()
19
+ console.log('cetusConfig: ', cetusConfig)
20
+ } catch (error) {
21
+ console.log(error)
22
+ }
23
+ })
24
+ })
25
+
26
+ describe('warp sdk config', () => {
27
+ const config = sdk.sdkOptions
28
+ test('sdk Config', async () => {
29
+ const sdkOptions = sdk.sdkOptions
30
+ try {
31
+ if (sdkOptions.clmm_pool.package_id.length > 0) {
32
+ const initEvent = await sdk.Pool.getClmmConfigs()
33
+ config.clmm_pool.config = initEvent
34
+ }
35
+ } catch (error) {
36
+ console.log('clmmConfig', error)
37
+ }
38
+
39
+ try {
40
+ if (sdkOptions.cetus_config.package_id.length > 0) {
41
+ const cetusConfig = await sdk.CetusConfig.getCetusConfig()
42
+ config.cetus_config.config = cetusConfig
43
+ }
44
+ } catch (error) {
45
+ console.log('tokenConfig', error)
46
+ }
47
+ console.log(config)
48
+ })
49
+ })
@@ -0,0 +1,254 @@
1
+ import BN from 'bn.js'
2
+ import { assert } from 'console'
3
+ import { adjustForSlippage, d, Percentage, printTransaction } from '@cetusprotocol/common-sdk'
4
+ import { buildTestAccount } from '@cetusprotocol/test-utils'
5
+ import 'isomorphic-fetch'
6
+ import { buildTransferCoinToSender, CetusClmmSDK } from '../src'
7
+ describe('Swap calculate Module', () => {
8
+ const sdk = CetusClmmSDK.createSDK({ env: 'mainnet' })
9
+
10
+ test('fetchTicksByContract', async () => {
11
+ const tickdatas = await sdk.Pool.fetchTicks({
12
+ pool_id: '0xcf994611fd4c48e277ce3ffd4d4364c914af2c3cbb05f7bf6facd371de688630',
13
+ coin_type_a: '0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN',
14
+ coin_type_b: '0x2::sui::SUI',
15
+ })
16
+ console.log('fetchTicks: ', tickdatas)
17
+ })
18
+
19
+ test('fetchTicksByRpc', async () => {
20
+ const tickdatas = await sdk.Pool.fetchTicksByRpc('0x0a46b7e6de173f9e48b56ec7bd3300c6a55c6fd4cabd3e2fbe7181014a796e40')
21
+ console.log('fetchTicks length: ', tickdatas.length)
22
+ })
23
+
24
+ test('getTickDataByIndex', async () => {
25
+ const tickData = await sdk.Pool.getTickDataByIndex('0x79696ca8bcdc45b9e15ef7da074a9c9a6f94739021590d7f57a3ed4055b93532', -443636)
26
+ console.log('tickData: ', tickData)
27
+ })
28
+
29
+ test('preSwapWithMultiPool', async () => {
30
+ const a2b = true
31
+ const pool_ids = [
32
+ '0x53d70570db4f4d8ebc20aa1b67dc6f5d061d318d371e5de50ff64525d7dd5bca',
33
+ '0x4038aea2341070550e9c1f723315624c539788d0ca9212dca7eb4b36147c0fcb',
34
+ '0x6fd4915e6d8d3e2ba6d81787046eb948ae36fdfc75dad2e24f0d4aaa2417a416',
35
+ ]
36
+ const pool0 = await sdk.Pool.getPool(pool_ids[0])
37
+ const pool1 = await sdk.Pool.getPool(pool_ids[1])
38
+ const pool2 = await sdk.Pool.getPool(pool_ids[2])
39
+ const byAmountIn = true
40
+ const amount = '10000000'
41
+
42
+ const resWithMultiPool = await sdk.Swap.preSwapWithMultiPool({
43
+ pool_ids: pool_ids,
44
+ coin_type_a: pool0.coin_type_a,
45
+ coin_type_b: pool0.coin_type_b,
46
+ a2b,
47
+ by_amount_in: byAmountIn,
48
+ amount,
49
+ })
50
+
51
+ for (const pool of [pool0, pool1, pool2]) {
52
+ const res: any = await sdk.Swap.preSwap({
53
+ pool: pool,
54
+ current_sqrt_price: pool.current_sqrt_price,
55
+ coin_type_a: pool.coin_type_a,
56
+ coin_type_b: pool.coin_type_b,
57
+ decimals_a: 6,
58
+ decimals_b: 6,
59
+ a2b,
60
+ by_amount_in: byAmountIn,
61
+ amount,
62
+ })
63
+ console.log('preSwap###res###', res)
64
+ }
65
+
66
+ console.log('preSwap###res###', resWithMultiPool)
67
+ })
68
+
69
+ test('preSwap', async () => {
70
+ const a2b = false
71
+ const pool = await sdk.Pool.getPool('0x0fea99ed9c65068638963a81587c3b8cafb71dc38c545319f008f7e9feb2b5f8')
72
+ const byAmountIn = false
73
+ const amount = '800000'
74
+
75
+ const res: any = await sdk.Swap.preSwap({
76
+ pool: pool,
77
+ current_sqrt_price: pool.current_sqrt_price,
78
+ coin_type_a: pool.coin_type_a,
79
+ coin_type_b: pool.coin_type_b,
80
+ decimals_a: 6,
81
+ decimals_b: 6,
82
+ a2b,
83
+ by_amount_in: byAmountIn,
84
+ amount,
85
+ })
86
+
87
+ console.log('preSwap###res###', res)
88
+ })
89
+
90
+ test('calculateRates', async () => {
91
+ const a2b = false
92
+ const pool = await sdk.Pool.getPool('0xc8d7a1503dc2f9f5b05449a87d8733593e2f0f3e7bffd90541252782e4d2ca20')
93
+ const byAmountIn = false
94
+ const amount = '80000000000000'
95
+
96
+ const swapTicks = await sdk.Pool.fetchTicks({
97
+ pool_id: pool.id,
98
+ coin_type_a: pool.coin_type_a,
99
+ coin_type_b: pool.coin_type_b,
100
+ })
101
+ // const swapTicks = await sdk.Pool.fetchTicksByRpc(pool.ticks_handle)
102
+ console.log('swapTicks: ', swapTicks.length)
103
+
104
+ const res = sdk.Swap.calculateRates({
105
+ decimals_a: 6,
106
+ decimals_b: 6,
107
+ a2b,
108
+ by_amount_in: byAmountIn,
109
+ amount: new BN(amount),
110
+ swap_ticks: swapTicks,
111
+ current_pool: pool,
112
+ })
113
+
114
+ console.log('preSwap###res###', {
115
+ estimated_amount_in: res.estimated_amount_in.toString(),
116
+ estimated_amount_out: res.estimated_amount_out.toString(),
117
+ estimated_end_sqrt_price: res.estimated_end_sqrt_price.toString(),
118
+ estimated_fee_amount: res.estimated_fee_amount.toString(),
119
+ is_exceed: res.is_exceed,
120
+ extra_compute_limit: res.extra_compute_limit,
121
+ amount: res.amount.toString(),
122
+ a2b: res.a2b,
123
+ by_amount_in: res.by_amount_in,
124
+ })
125
+ })
126
+ })
127
+
128
+ describe('Swap Module', () => {
129
+ const sdk = CetusClmmSDK.createSDK({ env: 'mainnet' })
130
+ let send_key_pair = buildTestAccount()
131
+
132
+ beforeEach(async () => {
133
+ sdk.setSenderAddress(send_key_pair.getPublicKey().toSuiAddress())
134
+ })
135
+
136
+ test('swap', async () => {
137
+ const a2b = true
138
+ const byAmountIn = true
139
+ const amount = '10000000'
140
+ const slippage = Percentage.fromDecimal(d(0.1))
141
+
142
+ const currentPool = await sdk.Pool.getPool('0x6fd4915e6d8d3e2ba6d81787046eb948ae36fdfc75dad2e24f0d4aaa2417a416')
143
+ console.log('currentPool: ', currentPool)
144
+
145
+ const res = await sdk.Swap.preSwap({
146
+ pool: currentPool,
147
+ current_sqrt_price: currentPool.current_sqrt_price,
148
+ coin_type_a: currentPool.coin_type_a,
149
+ coin_type_b: currentPool.coin_type_b,
150
+ decimals_a: 6,
151
+ decimals_b: 6,
152
+ a2b,
153
+ by_amount_in: byAmountIn,
154
+ amount,
155
+ })
156
+
157
+ console.log('res', {
158
+ estimated_amount_in: res.estimated_amount_in.toString(),
159
+ estimated_amount_out: res.estimated_amount_out.toString(),
160
+ estimated_end_sqrt_price: res.estimated_end_sqrt_price.toString(),
161
+ estimated_fee_amount: res.estimated_fee_amount.toString(),
162
+ is_exceed: res.is_exceed,
163
+ a2b,
164
+ by_amount_in: res.by_amount_in,
165
+ })
166
+
167
+ const toAmount = byAmountIn ? new BN(res.estimated_amount_out) : new BN(res.estimated_amount_in)
168
+
169
+ const amountLimit = adjustForSlippage(toAmount, slippage, !byAmountIn)
170
+
171
+ let swapPayload = await sdk.Swap.createSwapWithoutTransferCoinsPayload({
172
+ pool_id: currentPool.id,
173
+ a2b,
174
+ by_amount_in: byAmountIn,
175
+ amount: amount.toString(),
176
+ amount_limit: amountLimit.toString(),
177
+ coin_type_a: currentPool.coin_type_a,
178
+ coin_type_b: currentPool.coin_type_b,
179
+ })
180
+
181
+ buildTransferCoinToSender(sdk, swapPayload.tx, swapPayload.coin_ab_s[0], currentPool.coin_type_a)
182
+ buildTransferCoinToSender(sdk, swapPayload.tx, swapPayload.coin_ab_s[1], currentPool.coin_type_b)
183
+
184
+ printTransaction(swapPayload.tx)
185
+ const transferTxn = await sdk.FullClient.sendTransaction(send_key_pair, swapPayload.tx)
186
+ console.log('swap: ', transferTxn)
187
+ })
188
+ })
189
+
190
+ describe('Swap Module: assert preSwap and calculateRates', () => {
191
+ const sdk = CetusClmmSDK.createSDK({ env: 'mainnet' })
192
+ let send_key_pair = buildTestAccount()
193
+
194
+ beforeEach(async () => {
195
+ sdk.setSenderAddress(send_key_pair.getPublicKey().toSuiAddress())
196
+ })
197
+
198
+ test('swap', async () => {
199
+ const a2b = true
200
+ const byAmountIn = true
201
+ const amount = '120000000000000000'
202
+
203
+ const currentPool = await sdk.Pool.getPool('0x6fd4915e6d8d3e2ba6d81787046eb948ae36fdfc75dad2e24f0d4aaa2417a416')
204
+
205
+ const decimalsA = 6
206
+ const decimalsB = 6
207
+ const preSwapRes: any = await sdk.Swap.preSwap({
208
+ pool: currentPool,
209
+ current_sqrt_price: currentPool.current_sqrt_price,
210
+ coin_type_a: currentPool.coin_type_a,
211
+ coin_type_b: currentPool.coin_type_b,
212
+ decimals_a: decimalsA,
213
+ decimals_b: decimalsB,
214
+ a2b,
215
+ by_amount_in: byAmountIn,
216
+ amount,
217
+ })
218
+
219
+ console.log('preSwap###res###', preSwapRes)
220
+
221
+ const swapTicks = await sdk.Pool.fetchTicks({
222
+ pool_id: currentPool.id,
223
+ coin_type_a: currentPool.coin_type_a,
224
+ coin_type_b: currentPool.coin_type_b,
225
+ })
226
+ // const swapTicks = await sdk.Pool.fetchTicksByRpc(pool.ticks_handle)
227
+ console.log('swapTicks: ', swapTicks.length)
228
+
229
+ const calculateRatesRes = sdk.Swap.calculateRates({
230
+ decimals_a: decimalsA,
231
+ decimals_b: decimalsB,
232
+ a2b,
233
+ by_amount_in: byAmountIn,
234
+ amount: new BN(amount),
235
+ swap_ticks: swapTicks,
236
+ current_pool: currentPool,
237
+ })
238
+
239
+ console.log('preSwap###res###', {
240
+ estimated_amount_in: calculateRatesRes.estimated_amount_in.toString(),
241
+ estimated_amount_out: calculateRatesRes.estimated_amount_out.toString(),
242
+ estimated_end_sqrt_price: calculateRatesRes.estimated_end_sqrt_price.toString(),
243
+ estimated_fee_amount: calculateRatesRes.estimated_fee_amount.toString(),
244
+ is_exceed: calculateRatesRes.is_exceed,
245
+ extra_compute_limit: calculateRatesRes.extra_compute_limit,
246
+ amount: calculateRatesRes.amount.toString(),
247
+ a2b: calculateRatesRes.a2b,
248
+ by_amount_in: calculateRatesRes.by_amount_in,
249
+ })
250
+
251
+ assert(preSwapRes.estimated_amount_in.toString() == calculateRatesRes.estimated_amount_in.toString())
252
+ assert(preSwapRes.estimated_amount_out.toString() == calculateRatesRes.estimated_amount_out.toString())
253
+ })
254
+ })
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "allowJs": false,
6
+ "declaration": true,
7
+ "lib": [
8
+ "DOM",
9
+ "ES6",
10
+ "DOM.Iterable",
11
+ "ScriptHost",
12
+ "ES2016.Array.Include"
13
+ ],
14
+ "outDir": "./dist",
15
+ "strict": true,
16
+ "esModuleInterop": true,
17
+ "skipLibCheck": true,
18
+ "forceConsistentCasingInFileNames": true,
19
+ "resolveJsonModule": true,
20
+ "experimentalDecorators": true
21
+ },
22
+ "filesGlob": [
23
+ "src/**/*",
24
+ "tests/**/*"
25
+ ]
26
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["src/**/*"],
4
+ "exclude": ["node_modules", "dist"]
5
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ splitting: false,
6
+ sourcemap: true,
7
+ minify: true,
8
+ target: 'esnext',
9
+ clean: true,
10
+ })