@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.
- package/.turbo/turbo-build.log +11100 -0
- package/README.md +108 -0
- package/dist/index.d.mts +2251 -0
- package/dist/index.d.ts +2251 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +13 -0
- package/dist/index.mjs.map +1 -0
- package/docs/add_liquidity.md +145 -0
- package/docs/close_position.md +57 -0
- package/docs/collect_fees.md +37 -0
- package/docs/create_clmm_pool.md +228 -0
- package/docs/error_code.md +69 -0
- package/docs/get_clmm_pools.md +92 -0
- package/docs/get_positions.md +70 -0
- package/docs/get_reward.md +53 -0
- package/docs/get_ticks.md +39 -0
- package/docs/migrate_to_version_6.0.md +143 -0
- package/docs/open_position.md +224 -0
- package/docs/partner_swap.md +60 -0
- package/docs/pre_swap.md +136 -0
- package/docs/remove_liquidity.md +124 -0
- package/docs/swap.md +153 -0
- package/docs/utils.md +85 -0
- package/package.json +37 -0
- package/src/config/index.ts +2 -0
- package/src/config/mainnet.ts +41 -0
- package/src/config/testnet.ts +40 -0
- package/src/errors/errors.ts +93 -0
- package/src/errors/index.ts +1 -0
- package/src/index.ts +10 -0
- package/src/math/apr.ts +167 -0
- package/src/math/index.ts +1 -0
- package/src/modules/configModule.ts +540 -0
- package/src/modules/index.ts +5 -0
- package/src/modules/poolModule.ts +1066 -0
- package/src/modules/positionModule.ts +932 -0
- package/src/modules/rewarderModule.ts +430 -0
- package/src/modules/swapModule.ts +389 -0
- package/src/sdk.ts +131 -0
- package/src/types/clmm_type.ts +1002 -0
- package/src/types/clmmpool.ts +366 -0
- package/src/types/config_type.ts +241 -0
- package/src/types/index.ts +8 -0
- package/src/types/sui.ts +124 -0
- package/src/types/token_type.ts +189 -0
- package/src/utils/common.ts +426 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/positionUtils.ts +434 -0
- package/src/utils/swapUtils.ts +499 -0
- package/tests/add_liquidity.test.ts +121 -0
- package/tests/add_liquidity_fix_token.test.ts +182 -0
- package/tests/apr.test.ts +71 -0
- package/tests/cetus_config.test.ts +26 -0
- package/tests/collect_fees.test.ts +11 -0
- package/tests/pool.test.ts +267 -0
- package/tests/position.test.ts +145 -0
- package/tests/remove_liquidity.test.ts +119 -0
- package/tests/rewarder.test.ts +60 -0
- package/tests/sdk_config.test.ts +49 -0
- package/tests/swap.test.ts +254 -0
- package/tests/tsconfig.json +26 -0
- package/tsconfig.json +5 -0
- 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