@cetusprotocol/dlmm-sdk 0.0.2 → 0.0.3
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 +1025 -963
- package/README.md +9 -1
- package/dist/index.d.mts +39 -11
- package/dist/index.d.ts +39 -11
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -3
- package/src/config/mainnet.ts +10 -10
- package/src/config/testnet.ts +3 -3
- package/src/modules/poolModule.ts +59 -12
- package/src/modules/positionModule.ts +35 -16
- package/src/types/dlmm.ts +25 -4
- package/src/utils/feeUtils.ts +13 -13
- package/src/utils/parseData.ts +39 -2
- package/src/utils/strategyUtils.ts +133 -52
- package/src/utils/weightUtils.ts +167 -6
- package/tests/add_liquidity_bidask.test.ts +26 -14
- package/tests/add_liquidity_curve.test.ts +16 -16
- package/tests/add_liquidity_spot.test.ts +74 -22
- package/tests/config.test.ts +23 -1
- package/tests/pool.test.ts +12 -2
- package/tests/position.test.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cetusprotocol/dlmm-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "SDK for cetus dlmm",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,10 +26,12 @@
|
|
|
26
26
|
"license": "Apache-2.0",
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@cetusprotocol/common-sdk": "workspace:*",
|
|
29
|
-
"@cetusprotocol/test-utils": "workspace:*"
|
|
29
|
+
"@cetusprotocol/test-utils": "workspace:*",
|
|
30
|
+
"blakejs": "^1.2.1"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
33
|
"@cetusprotocol/common-sdk": "*",
|
|
33
|
-
"@mysten/sui": "*"
|
|
34
|
+
"@mysten/sui": "*",
|
|
35
|
+
"blakejs": "*"
|
|
34
36
|
}
|
|
35
37
|
}
|
package/src/config/mainnet.ts
CHANGED
|
@@ -5,21 +5,21 @@ export const dlmmMainnet: SdkOptions = {
|
|
|
5
5
|
env: 'mainnet',
|
|
6
6
|
full_rpc_url: FullRpcUrlMainnet,
|
|
7
7
|
dlmm_pool: {
|
|
8
|
-
package_id: '
|
|
9
|
-
published_at: '
|
|
8
|
+
package_id: '0x5664f9d3fd82c84023870cfbda8ea84e14c8dd56ce557ad2116e0668581a682b',
|
|
9
|
+
published_at: '0x5664f9d3fd82c84023870cfbda8ea84e14c8dd56ce557ad2116e0668581a682b',
|
|
10
10
|
version: 1,
|
|
11
11
|
config: {
|
|
12
|
-
registry_id: '
|
|
13
|
-
pools_id: '
|
|
14
|
-
global_config_id: '
|
|
15
|
-
versioned_id: '
|
|
16
|
-
admin_cap_id: '
|
|
17
|
-
partners_id: '
|
|
12
|
+
registry_id: '0xb1d55e7d895823c65f98d99b81a69436cf7d1638629c9ccb921326039cda1f1b',
|
|
13
|
+
pools_id: '0xc3683b2356cac6423e9ecaea20955c7cc193998b016e5b884730ed1192174991',
|
|
14
|
+
global_config_id: '0xf31b605d117f959b9730e8c07b08b856cb05143c5e81d5751c90d2979e82f599',
|
|
15
|
+
versioned_id: '0x05370b2d656612dd5759cbe80463de301e3b94a921dfc72dd9daa2ecdeb2d0a8',
|
|
16
|
+
admin_cap_id: '0xc4c42bc31cb54beb679dccd547f8bdb970cb6dc989bd1f85a4fed4812ed95d6e',
|
|
17
|
+
partners_id: '0x5c0affc8d363b6abb1f32790c229165215f4edead89a9bc7cd95dad717b4296a',
|
|
18
18
|
},
|
|
19
19
|
},
|
|
20
20
|
dlmm_router: {
|
|
21
|
-
package_id: '
|
|
22
|
-
published_at: '
|
|
21
|
+
package_id: '0xc65d59c4aa7c9d53836bdbbb2a1418b02be6a351a767c64d6e4b7e96d26356d2',
|
|
22
|
+
published_at: '0xda28da84b5b1fef0ca053a2373e80ddb3a75f45e891e825fb06c2a53f838067d',
|
|
23
23
|
version: 1,
|
|
24
24
|
},
|
|
25
25
|
}
|
package/src/config/testnet.ts
CHANGED
|
@@ -6,7 +6,7 @@ export const dlmmTestnet: SdkOptions = {
|
|
|
6
6
|
full_rpc_url: FullRpcUrlTestnet,
|
|
7
7
|
dlmm_pool: {
|
|
8
8
|
package_id: '0x17a1f5a8779461ff44e942adf33325cce112c693d6a177ed77f035ca86d1fdb6',
|
|
9
|
-
published_at: '
|
|
9
|
+
published_at: '0x6d32c1be32eefcea933c03dd5cb7c783d1d83f6b30c4d1131d955933747b1701',
|
|
10
10
|
version: 1,
|
|
11
11
|
config: {
|
|
12
12
|
registry_id: '0x319070e26a6809f439d3c4a45e63bf74939c5fe3165de7b65968ee8547f71bd0',
|
|
@@ -18,8 +18,8 @@ export const dlmmTestnet: SdkOptions = {
|
|
|
18
18
|
},
|
|
19
19
|
},
|
|
20
20
|
dlmm_router: {
|
|
21
|
-
package_id: '
|
|
22
|
-
published_at: '
|
|
21
|
+
package_id: '0xba3059875c8980ac171fc2bac81b9df172fb77fa0cb5a267636df701225b93ef',
|
|
22
|
+
published_at: '0x59b7a2da6db8f9245a1db6169018af7124c0714fa77a84224967ead6be125127',
|
|
23
23
|
version: 1,
|
|
24
24
|
},
|
|
25
25
|
faucet: {
|
|
@@ -14,9 +14,18 @@ import {
|
|
|
14
14
|
isSortedSymbols,
|
|
15
15
|
PageQuery,
|
|
16
16
|
PaginationArgs,
|
|
17
|
+
printTransaction,
|
|
17
18
|
} from '@cetusprotocol/common-sdk'
|
|
18
19
|
import { DlmmErrorCode, handleError } from '../errors/errors'
|
|
19
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
BinUtils,
|
|
22
|
+
buildPoolKey,
|
|
23
|
+
parseBinInfo,
|
|
24
|
+
parseBinInfoList,
|
|
25
|
+
parseDlmmBasePool,
|
|
26
|
+
parseDlmmPool,
|
|
27
|
+
parsePoolTransactionInfo,
|
|
28
|
+
} from '../utils'
|
|
20
29
|
import { CetusDlmmSDK } from '../sdk'
|
|
21
30
|
import {
|
|
22
31
|
BinAmount,
|
|
@@ -50,6 +59,35 @@ export class PoolModule implements IModule<CetusDlmmSDK> {
|
|
|
50
59
|
return this._sdk
|
|
51
60
|
}
|
|
52
61
|
|
|
62
|
+
async getPoolAddress(coin_type_a: string, coin_type_b: string, bin_step: number, base_factor: number): Promise<string | undefined> {
|
|
63
|
+
try {
|
|
64
|
+
const poolKey = buildPoolKey(coin_type_a, coin_type_b, bin_step, base_factor)
|
|
65
|
+
const { dlmm_pool } = this._sdk.sdkOptions
|
|
66
|
+
const { pools_id } = getPackagerConfigs(dlmm_pool)
|
|
67
|
+
const res = await this._sdk.FullClient.getDynamicFieldObject({
|
|
68
|
+
parentId: pools_id,
|
|
69
|
+
name: {
|
|
70
|
+
type: '0x2::object::ID',
|
|
71
|
+
value: poolKey,
|
|
72
|
+
},
|
|
73
|
+
})
|
|
74
|
+
const fields = getObjectFields(res)
|
|
75
|
+
return fields.value.fields.value.fields.pool_id
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return handleError(DlmmErrorCode.FetchError, error as Error, {
|
|
78
|
+
[DETAILS_KEYS.METHOD_NAME]: 'getPoolAddress',
|
|
79
|
+
[DETAILS_KEYS.REQUEST_PARAMS]: {
|
|
80
|
+
coin_type_a,
|
|
81
|
+
coin_type_b,
|
|
82
|
+
bin_step,
|
|
83
|
+
base_factor,
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return undefined
|
|
89
|
+
}
|
|
90
|
+
|
|
53
91
|
/**
|
|
54
92
|
* Get the list of DLMM base pools
|
|
55
93
|
* @param pagination_args - The pagination arguments
|
|
@@ -205,19 +243,27 @@ export class PoolModule implements IModule<CetusDlmmSDK> {
|
|
|
205
243
|
const bin_infos: BinAmount[] = []
|
|
206
244
|
let start_bin_id: number | undefined = undefined
|
|
207
245
|
let hasNext = true
|
|
208
|
-
|
|
209
246
|
while (hasNext) {
|
|
210
247
|
const tx: Transaction = new Transaction()
|
|
248
|
+
let start_bin
|
|
249
|
+
if (start_bin_id !== undefined) {
|
|
250
|
+
start_bin = tx.moveCall({
|
|
251
|
+
target: `0x1::option::some`,
|
|
252
|
+
arguments: [tx.pure.u32(Number(asUintN(BigInt(start_bin_id))))],
|
|
253
|
+
typeArguments: ['u32'],
|
|
254
|
+
})
|
|
255
|
+
} else {
|
|
256
|
+
start_bin = tx.moveCall({
|
|
257
|
+
target: `0x1::option::none`,
|
|
258
|
+
typeArguments: ['u32'],
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
|
|
211
262
|
tx.moveCall({
|
|
212
263
|
target: `${dlmm_pool.published_at}::pool::fetch_bins`,
|
|
213
|
-
arguments: [
|
|
214
|
-
tx.object(pool_id),
|
|
215
|
-
tx.pure.vector('u32', start_bin_id ? [Number(asUintN(BigInt(start_bin_id)))] : []),
|
|
216
|
-
tx.pure.u64(limit),
|
|
217
|
-
],
|
|
264
|
+
arguments: [tx.object(pool_id), start_bin, tx.pure.u64(limit)],
|
|
218
265
|
typeArguments: [coin_type_a, coin_type_b],
|
|
219
266
|
})
|
|
220
|
-
|
|
221
267
|
const res = await this._sdk.FullClient.devInspectTransactionBlock({
|
|
222
268
|
transactionBlock: tx,
|
|
223
269
|
sender: normalizeSuiAddress('0x0'),
|
|
@@ -225,7 +271,7 @@ export class PoolModule implements IModule<CetusDlmmSDK> {
|
|
|
225
271
|
|
|
226
272
|
const list = parseBinInfoList(res)
|
|
227
273
|
bin_infos.push(...list)
|
|
228
|
-
start_bin_id = list.length > 0 ? list[list.length - 1].bin_id : undefined
|
|
274
|
+
start_bin_id = list.length > 0 ? list[list.length - 1].bin_id + 1 : undefined
|
|
229
275
|
hasNext = list.length === limit
|
|
230
276
|
}
|
|
231
277
|
|
|
@@ -381,6 +427,7 @@ export class PoolModule implements IModule<CetusDlmmSDK> {
|
|
|
381
427
|
strategy_type,
|
|
382
428
|
use_bin_infos,
|
|
383
429
|
base_factor,
|
|
430
|
+
pool_id,
|
|
384
431
|
} = option
|
|
385
432
|
|
|
386
433
|
let lower_bin_id
|
|
@@ -400,18 +447,18 @@ export class PoolModule implements IModule<CetusDlmmSDK> {
|
|
|
400
447
|
active_id = BinUtils.getBinIdFromPrice(d(1).div(price).toString(), bin_step, false, decimals_a, decimals_b)
|
|
401
448
|
|
|
402
449
|
const calculateOption: CalculateAddLiquidityOption = {
|
|
450
|
+
pool_id,
|
|
403
451
|
amount_a: bin_infos.amount_b,
|
|
404
452
|
amount_b: bin_infos.amount_a,
|
|
405
453
|
active_id,
|
|
406
454
|
bin_step,
|
|
407
455
|
lower_bin_id,
|
|
408
456
|
upper_bin_id,
|
|
409
|
-
|
|
410
|
-
amount_b_in_active_bin: '0',
|
|
457
|
+
active_bin_of_pool: undefined,
|
|
411
458
|
strategy_type: option.strategy_type,
|
|
412
459
|
}
|
|
413
460
|
|
|
414
|
-
new_bin_infos = this.sdk.Position.calculateAddLiquidityInfo(calculateOption)
|
|
461
|
+
new_bin_infos = await this.sdk.Position.calculateAddLiquidityInfo(calculateOption)
|
|
415
462
|
}
|
|
416
463
|
|
|
417
464
|
const createPoolAndAddOption: CreatePoolAndAddOption = {
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
} from '../types/dlmm'
|
|
29
29
|
import {
|
|
30
30
|
BinUtils,
|
|
31
|
+
FeeUtils,
|
|
31
32
|
getRouterModule,
|
|
32
33
|
parsedDlmmPosFeeData,
|
|
33
34
|
parsedDlmmPosRewardData,
|
|
@@ -354,36 +355,56 @@ export class PositionModule implements IModule<CetusDlmmSDK> {
|
|
|
354
355
|
* @param option - The option for calculating the result of adding liquidity
|
|
355
356
|
* @returns The result of adding liquidity
|
|
356
357
|
*/
|
|
357
|
-
calculateAddLiquidityInfo(option: CalculateAddLiquidityOption | CalculateAddLiquidityAutoFillOption): BinLiquidityInfo {
|
|
358
|
+
async calculateAddLiquidityInfo(option: CalculateAddLiquidityOption | CalculateAddLiquidityAutoFillOption): Promise<BinLiquidityInfo> {
|
|
358
359
|
const isAutoFill = 'fix_amount_a' in option
|
|
359
|
-
const { active_id, bin_step, lower_bin_id, upper_bin_id,
|
|
360
|
+
const { active_id, bin_step, lower_bin_id, upper_bin_id, active_bin_of_pool, strategy_type, pool_id } = option
|
|
360
361
|
|
|
362
|
+
let bin_infos
|
|
361
363
|
if (isAutoFill) {
|
|
362
364
|
const { coin_amount, fix_amount_a } = option
|
|
363
|
-
|
|
365
|
+
bin_infos = StrategyUtils.autoFillCoinByStrategyV2(
|
|
364
366
|
active_id,
|
|
365
367
|
bin_step,
|
|
366
368
|
coin_amount,
|
|
367
369
|
fix_amount_a,
|
|
368
|
-
amount_a_in_active_bin,
|
|
369
|
-
amount_b_in_active_bin,
|
|
370
370
|
lower_bin_id,
|
|
371
371
|
upper_bin_id,
|
|
372
|
-
strategy_type
|
|
372
|
+
strategy_type,
|
|
373
|
+
active_bin_of_pool
|
|
373
374
|
)
|
|
374
375
|
} else {
|
|
375
|
-
|
|
376
|
+
bin_infos = StrategyUtils.toAmountsBothSideByStrategy(
|
|
376
377
|
active_id,
|
|
377
378
|
bin_step,
|
|
378
379
|
lower_bin_id,
|
|
379
380
|
upper_bin_id,
|
|
380
381
|
option.amount_a,
|
|
381
382
|
option.amount_b,
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
strategy_type
|
|
383
|
+
strategy_type,
|
|
384
|
+
active_bin_of_pool
|
|
385
385
|
)
|
|
386
386
|
}
|
|
387
|
+
if (active_bin_of_pool && pool_id) {
|
|
388
|
+
const active_bin_index = bin_infos.bins.findIndex((bin) => bin.bin_id === active_id)
|
|
389
|
+
if (active_bin_index !== -1) {
|
|
390
|
+
const pool = await this._sdk.Pool.getPool(pool_id, false)
|
|
391
|
+
if (pool) {
|
|
392
|
+
const { fees_a, fees_b } = FeeUtils.getCompositionFees(
|
|
393
|
+
active_bin_of_pool,
|
|
394
|
+
bin_infos.bins[active_bin_index],
|
|
395
|
+
pool.variable_parameters
|
|
396
|
+
)
|
|
397
|
+
const active_bin = bin_infos.bins[active_bin_index]
|
|
398
|
+
active_bin.amount_a = d(active_bin.amount_a).sub(fees_a).toFixed(0)
|
|
399
|
+
active_bin.amount_b = d(active_bin.amount_b).sub(fees_b).toFixed(0)
|
|
400
|
+
bin_infos.bins[active_bin_index] = active_bin
|
|
401
|
+
console.log('🚀 ~ PositionModule ~ calculateAddLiquidityInfo ~ fees_a:', fees_a)
|
|
402
|
+
console.log('🚀 ~ PositionModule ~ calculateAddLiquidityInfo ~ fees_b:', fees_b)
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
return bin_infos
|
|
387
408
|
}
|
|
388
409
|
|
|
389
410
|
/**
|
|
@@ -480,7 +501,7 @@ export class PositionModule implements IModule<CetusDlmmSDK> {
|
|
|
480
501
|
* @param option - The option for adding liquidity with price
|
|
481
502
|
* @returns The transaction
|
|
482
503
|
*/
|
|
483
|
-
addLiquidityWithPricePayload(option: OpenAndAddLiquidityWithPriceOption): Transaction {
|
|
504
|
+
async addLiquidityWithPricePayload(option: OpenAndAddLiquidityWithPriceOption): Promise<Transaction> {
|
|
484
505
|
const {
|
|
485
506
|
pool_id,
|
|
486
507
|
bin_infos,
|
|
@@ -492,8 +513,7 @@ export class PositionModule implements IModule<CetusDlmmSDK> {
|
|
|
492
513
|
upper_price,
|
|
493
514
|
bin_step,
|
|
494
515
|
strategy_type,
|
|
495
|
-
|
|
496
|
-
amount_b_in_active_bin,
|
|
516
|
+
active_bin_of_pool,
|
|
497
517
|
decimals_a,
|
|
498
518
|
decimals_b,
|
|
499
519
|
use_bin_infos,
|
|
@@ -522,12 +542,11 @@ export class PositionModule implements IModule<CetusDlmmSDK> {
|
|
|
522
542
|
bin_step,
|
|
523
543
|
lower_bin_id,
|
|
524
544
|
upper_bin_id,
|
|
525
|
-
|
|
526
|
-
amount_b_in_active_bin,
|
|
545
|
+
active_bin_of_pool,
|
|
527
546
|
strategy_type: strategy_type,
|
|
528
547
|
}
|
|
529
548
|
|
|
530
|
-
new_bin_infos = this.sdk.Position.calculateAddLiquidityInfo(calculateOption)
|
|
549
|
+
new_bin_infos = await this.sdk.Position.calculateAddLiquidityInfo(calculateOption)
|
|
531
550
|
}
|
|
532
551
|
|
|
533
552
|
const openAndAddLiquidityOption: OpenAndAddLiquidityOption = {
|
package/src/types/dlmm.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CoinPairType, TableHandle } from '@cetusprotocol/common-sdk'
|
|
2
2
|
import { TransactionObjectArgument } from '@mysten/sui/transactions'
|
|
3
|
+
import Decimal from 'decimal.js'
|
|
3
4
|
export type DlmmConfigs = {
|
|
4
5
|
registry_id: string
|
|
5
6
|
pools_id: string
|
|
@@ -152,6 +153,7 @@ export type CreatePoolOption = {
|
|
|
152
153
|
} & BaseCreatePoolOption
|
|
153
154
|
|
|
154
155
|
export type CreatePoolAndAddWithPriceOption = {
|
|
156
|
+
pool_id: string
|
|
155
157
|
price_base_coin: 'coin_a' | 'coin_b'
|
|
156
158
|
price: string
|
|
157
159
|
lower_price: string
|
|
@@ -177,12 +179,12 @@ export type BaseAddLiquidityOption = {
|
|
|
177
179
|
} & CoinPairType
|
|
178
180
|
|
|
179
181
|
export type BaseCalculateAddLiquidityOption = {
|
|
182
|
+
pool_id?: string
|
|
180
183
|
active_id: number
|
|
181
184
|
bin_step: number
|
|
182
185
|
lower_bin_id: number
|
|
183
186
|
upper_bin_id: number
|
|
184
|
-
|
|
185
|
-
amount_b_in_active_bin: string
|
|
187
|
+
active_bin_of_pool?: BinAmount
|
|
186
188
|
strategy_type: StrategyType
|
|
187
189
|
}
|
|
188
190
|
|
|
@@ -212,8 +214,7 @@ export type OpenAndAddLiquidityWithPriceOption = BaseAddLiquidityOption & {
|
|
|
212
214
|
price: string
|
|
213
215
|
lower_price: string
|
|
214
216
|
upper_price: string
|
|
215
|
-
|
|
216
|
-
amount_b_in_active_bin: string
|
|
217
|
+
active_bin_of_pool?: BinAmount
|
|
217
218
|
strategy_type: StrategyType
|
|
218
219
|
decimals_a: number
|
|
219
220
|
decimals_b: number
|
|
@@ -443,3 +444,23 @@ export type FeeRate = {
|
|
|
443
444
|
var_fee_rate: string
|
|
444
445
|
total_fee_rate: string
|
|
445
446
|
}
|
|
447
|
+
|
|
448
|
+
export type WeightsOptions = {
|
|
449
|
+
strategy_type: StrategyType
|
|
450
|
+
active_id: number
|
|
451
|
+
bin_step: number
|
|
452
|
+
lower_bin_id: number
|
|
453
|
+
upper_bin_id: number
|
|
454
|
+
total_amount_a: string
|
|
455
|
+
total_amount_b: string
|
|
456
|
+
active_bin_of_pool?: BinAmount
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export type WeightsInfo = {
|
|
460
|
+
total_weight_a: Decimal
|
|
461
|
+
total_weight_b: Decimal
|
|
462
|
+
weights: Decimal[]
|
|
463
|
+
weight_per_prices: Decimal[]
|
|
464
|
+
active_weight_a: Decimal
|
|
465
|
+
active_weight_b: Decimal
|
|
466
|
+
} & WeightsOptions
|
package/src/utils/feeUtils.ts
CHANGED
|
@@ -20,7 +20,7 @@ export class FeeUtils {
|
|
|
20
20
|
static calculateCompositionFee(amount: string, total_fee_rate: string) {
|
|
21
21
|
const fee_amount = d(amount).mul(total_fee_rate)
|
|
22
22
|
const composition_fee = d(fee_amount).mul(d(FEE_PRECISION).add(total_fee_rate))
|
|
23
|
-
return composition_fee.div(
|
|
23
|
+
return composition_fee.div(1000000000000000000).toFixed(0)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
static calculateProtocolFee(fee_amount: string, protocol_fee_rate: string) {
|
|
@@ -40,31 +40,33 @@ export class FeeUtils {
|
|
|
40
40
|
static getCompositionFees(
|
|
41
41
|
active_bin: BinAmount,
|
|
42
42
|
used_bin: BinAmount,
|
|
43
|
-
binStepConfig: BinStepConfig,
|
|
44
43
|
variableParameters: VariableParameters
|
|
45
44
|
): { fees_a: string; fees_b: string } {
|
|
45
|
+
const { bin_step_config } = variableParameters
|
|
46
46
|
if (d(active_bin.liquidity || '0').eq(d(0))) {
|
|
47
47
|
return {
|
|
48
48
|
fees_a: '0',
|
|
49
49
|
fees_b: '0',
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
const { bin_step, base_factor } =
|
|
52
|
+
const { bin_step, base_factor } = bin_step_config
|
|
53
53
|
const qPrice = BinUtils.getQPriceFromId(active_bin.bin_id, bin_step)
|
|
54
|
-
const
|
|
54
|
+
const bin_liquidity = BinUtils.getLiquidity(active_bin.amount_a, active_bin.amount_b, qPrice)
|
|
55
|
+
const delta_liquidity = BinUtils.getLiquidity(used_bin.amount_a, used_bin.amount_b, qPrice)
|
|
56
|
+
const delta_liquidity_share = d(active_bin.liquidity).mul(delta_liquidity).div(bin_liquidity).toFixed(0)
|
|
55
57
|
|
|
56
58
|
const { amount_a: amount_a_out, amount_b: amount_b_out } = BinUtils.calculateOutByShare(
|
|
57
59
|
{
|
|
58
60
|
bin_id: active_bin.bin_id,
|
|
59
|
-
liquidity: d(active_bin.liquidity).add(
|
|
61
|
+
liquidity: d(active_bin.liquidity).add(delta_liquidity_share).toFixed(0),
|
|
60
62
|
amount_a: d(active_bin.amount_a).add(used_bin.amount_a).toFixed(0),
|
|
61
63
|
amount_b: d(active_bin.amount_b).add(used_bin.amount_b).toFixed(0),
|
|
62
64
|
price_per_lamport: active_bin.price_per_lamport,
|
|
63
65
|
},
|
|
64
|
-
|
|
66
|
+
delta_liquidity_share
|
|
65
67
|
)
|
|
66
68
|
|
|
67
|
-
const base_fee = d(bin_step).mul(base_factor)
|
|
69
|
+
const base_fee = d(bin_step).mul(base_factor).mul(10)
|
|
68
70
|
const variable_fee = FeeUtils.getVariableFee(variableParameters)
|
|
69
71
|
|
|
70
72
|
let total_fee_rate = d(base_fee).add(variable_fee).toFixed(0)
|
|
@@ -76,12 +78,10 @@ export class FeeUtils {
|
|
|
76
78
|
let fees_a = '0'
|
|
77
79
|
let fees_b = '0'
|
|
78
80
|
|
|
79
|
-
if (d(amount_a_out).gt(used_bin.amount_a)) {
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (d(amount_b_out).gt(used_bin.amount_b)) {
|
|
84
|
-
fees_b = FeeUtils.calculateCompositionFee(amount_b_out, total_fee_rate)
|
|
81
|
+
if (d(amount_a_out).gt(used_bin.amount_a) && d(used_bin.amount_b).gt(amount_b_out)) {
|
|
82
|
+
fees_b = FeeUtils.calculateCompositionFee(d(used_bin.amount_b).sub(amount_b_out).toFixed(0), total_fee_rate)
|
|
83
|
+
} else if (d(amount_b_out).gt(used_bin.amount_b) && d(used_bin.amount_a).gt(amount_a_out)) {
|
|
84
|
+
fees_a = FeeUtils.calculateCompositionFee(d(used_bin.amount_a).sub(amount_a_out).toFixed(0), total_fee_rate)
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
return {
|
package/src/utils/parseData.ts
CHANGED
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
import { BinUtils } from './binUtils'
|
|
38
38
|
import { BASIS_POINT } from '../types/constants'
|
|
39
39
|
import { bcs } from '@mysten/sui/bcs'
|
|
40
|
+
import { blake2b } from 'blakejs'
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
43
|
* Parse the DLMM base pool data
|
|
@@ -278,7 +279,7 @@ export function parseBinInfoList(res: DevInspectResults): BinAmount[] {
|
|
|
278
279
|
fee_b_growth_global: bcs.u128(),
|
|
279
280
|
})
|
|
280
281
|
|
|
281
|
-
const bin_amounts = bcs.vector(bcsCoinAmount).parse(Uint8Array.from(res.results![
|
|
282
|
+
const bin_amounts = bcs.vector(bcsCoinAmount).parse(Uint8Array.from(res.results![1].returnValues![0][0]))
|
|
282
283
|
|
|
283
284
|
return bin_amounts.map((bin_amount) => {
|
|
284
285
|
const bin_id = asIntN(BigInt(bin_amount.id.bits))
|
|
@@ -303,7 +304,7 @@ export function parseBinInfo(fields: any): BinAmount {
|
|
|
303
304
|
bin_id,
|
|
304
305
|
amount_a: fields.amount_a,
|
|
305
306
|
amount_b: fields.amount_b,
|
|
306
|
-
liquidity: fields.
|
|
307
|
+
liquidity: fields.liquidity_share,
|
|
307
308
|
price_per_lamport: BinUtils.getPricePerLamportFromQPrice(fields.price),
|
|
308
309
|
}
|
|
309
310
|
|
|
@@ -507,6 +508,13 @@ export function safeMulAmount(amount: Decimal, rate: Decimal): Decimal {
|
|
|
507
508
|
return result.floor()
|
|
508
509
|
}
|
|
509
510
|
|
|
511
|
+
export function safeAmount(amount: Decimal): Decimal {
|
|
512
|
+
if (amount.gt(0) && amount.lt(1)) {
|
|
513
|
+
throw new DlmmError(`Multiplication ${amount.toString()} is less than 1`, DlmmErrorCode.AmountTooSmall)
|
|
514
|
+
}
|
|
515
|
+
return amount.floor()
|
|
516
|
+
}
|
|
517
|
+
|
|
510
518
|
export function getRouterModule(strategy_type: StrategyType) {
|
|
511
519
|
switch (strategy_type) {
|
|
512
520
|
case StrategyType.Spot:
|
|
@@ -517,3 +525,32 @@ export function getRouterModule(strategy_type: StrategyType) {
|
|
|
517
525
|
return 'bid_ask'
|
|
518
526
|
}
|
|
519
527
|
}
|
|
528
|
+
|
|
529
|
+
export function buildPoolKey(coin_type_a: string, coin_type_b: string, bin_step: number, base_factor: number) {
|
|
530
|
+
// Convert coin types to bytes
|
|
531
|
+
let coinABytes = Buffer.from(coin_type_a, 'utf8')
|
|
532
|
+
const coinBBytes = Buffer.from(coin_type_b, 'utf8')
|
|
533
|
+
|
|
534
|
+
const lenB = coinBBytes.length
|
|
535
|
+
|
|
536
|
+
let i = 0
|
|
537
|
+
|
|
538
|
+
// Append coinB bytes to coinA (without validation)
|
|
539
|
+
while (i < lenB) {
|
|
540
|
+
const byteB = coinBBytes[i]
|
|
541
|
+
coinABytes = Buffer.concat([coinABytes, Buffer.from([byteB])])
|
|
542
|
+
i++
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Serialize bin_step and base_factor using BCS
|
|
546
|
+
const binStepBytes = bcs.u16().serialize(bin_step).toBytes()
|
|
547
|
+
const baseFactorBytes = bcs.u16().serialize(base_factor).toBytes()
|
|
548
|
+
|
|
549
|
+
// Concatenate all bytes
|
|
550
|
+
const combinedBytes = Buffer.concat([coinABytes, binStepBytes, baseFactorBytes])
|
|
551
|
+
|
|
552
|
+
// Hash with blake2b256
|
|
553
|
+
const hash = blake2b(combinedBytes, undefined, 32)
|
|
554
|
+
|
|
555
|
+
return `0x${Buffer.from(hash).toString('hex')}`
|
|
556
|
+
}
|