@cetusprotocol/aggregator-sdk 0.0.8 → 0.1.1

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 (57) hide show
  1. package/dist/index.d.mts +98 -161
  2. package/dist/index.d.ts +98 -161
  3. package/dist/index.js +1128 -1550
  4. package/dist/index.mjs +1116 -1488
  5. package/dist/src/api.d.ts +53 -0
  6. package/dist/src/client.d.ts +38 -65
  7. package/dist/src/const.d.ts +0 -68
  8. package/dist/src/index.d.ts +9 -5
  9. package/dist/src/transaction/afsui.d.ts +10 -0
  10. package/dist/src/transaction/aftermath.d.ts +13 -24
  11. package/dist/src/transaction/cetus.d.ts +9 -33
  12. package/dist/src/transaction/deepbook_v2.d.ts +14 -0
  13. package/dist/src/transaction/flowx_v2.d.ts +7 -0
  14. package/dist/src/transaction/haedal.d.ts +6 -0
  15. package/dist/src/transaction/index.d.ts +6 -1
  16. package/dist/src/transaction/kriya_v2.d.ts +6 -0
  17. package/dist/src/transaction/kriya_v3.d.ts +7 -0
  18. package/dist/src/transaction/swap.d.ts +1 -2
  19. package/dist/src/transaction/turbos.d.ts +7 -22
  20. package/dist/src/transaction/volo.d.ts +8 -0
  21. package/dist/src/utils/coin.d.ts +9 -0
  22. package/dist/{src → tests}/test_data.test.d.ts +1 -0
  23. package/package.json +2 -2
  24. package/src/api.ts +144 -0
  25. package/src/client.ts +295 -239
  26. package/src/const.ts +0 -113
  27. package/src/index.ts +10 -5
  28. package/src/transaction/afsui.ts +60 -0
  29. package/src/transaction/aftermath.ts +71 -124
  30. package/src/transaction/cetus.ts +87 -258
  31. package/src/transaction/deepbook_v2.ts +122 -0
  32. package/src/transaction/flowx_v2.ts +42 -0
  33. package/src/transaction/haedal.ts +41 -0
  34. package/src/transaction/index.ts +17 -1
  35. package/src/transaction/kriya_v2.ts +38 -0
  36. package/src/transaction/kriya_v3.ts +46 -0
  37. package/src/transaction/swap.ts +17 -24
  38. package/src/transaction/turbos.ts +40 -99
  39. package/src/transaction/volo.ts +52 -0
  40. package/src/utils/coin.ts +91 -6
  41. package/src/utils/transaction.ts +1 -1
  42. package/tests/router.test.ts +123 -73
  43. package/{src → tests}/test_data.test.ts +2 -0
  44. package/dist/src/config.d.ts +0 -26
  45. package/dist/src/transaction/common.d.ts +0 -12
  46. package/dist/src/transaction/deepbook.d.ts +0 -21
  47. package/dist/src/transaction/flowx.d.ts +0 -20
  48. package/dist/src/transaction/kriya.d.ts +0 -21
  49. package/dist/src/transaction/router.d.ts +0 -6
  50. package/dist/src/utils/account_cap.d.ts +0 -7
  51. package/src/config.ts +0 -65
  52. package/src/transaction/common.ts +0 -169
  53. package/src/transaction/deepbook.ts +0 -126
  54. package/src/transaction/flowx.ts +0 -97
  55. package/src/transaction/kriya.ts +0 -77
  56. package/src/transaction/router.ts +0 -339
  57. package/src/utils/account_cap.ts +0 -62
@@ -1,8 +1,7 @@
1
1
  import { Transaction } from "@mysten/sui/transactions"
2
2
  import { SwapInPoolsParams } from "~/client"
3
- import { AggregatorConfig } from "~/config"
4
3
  import { compareCoins, completionCoin } from "~/utils/coin"
5
- import { CETUS_DEX, INTEGRATE, SwapInPoolsResult, U64_MAX_BN, ZERO } from ".."
4
+ import { SwapInPoolsResult, U64_MAX_BN, ZERO } from ".."
6
5
  import { ConfigErrorCode, TransactionErrorCode } from "~/errors"
7
6
  import { checkInvalidSuiAddress } from "~/utils/transaction"
8
7
  import { SuiClient } from "@mysten/sui/client"
@@ -12,32 +11,24 @@ import { sqrtPriceX64ToPrice } from "~/math"
12
11
  export async function swapInPools(
13
12
  client: SuiClient,
14
13
  params: SwapInPoolsParams,
15
- config: AggregatorConfig
14
+ sender: string
16
15
  ): Promise<SwapInPoolsResult> {
17
16
  const { from, target, amount, byAmountIn, pools } = params
18
17
  const fromCoin = completionCoin(from)
19
18
  const targetCoin = completionCoin(target)
20
19
 
21
20
  const tx = new Transaction()
22
- const a2b = compareCoins(fromCoin, targetCoin)
23
-
24
- const integratePackage = config.getPackage(INTEGRATE)
25
- if (integratePackage == null) {
26
- throw new AggregateError(
27
- "Aggregator package not set",
28
- ConfigErrorCode.MissAggregatorPackage
29
- )
30
- }
31
- const integratePublishedAt = integratePackage.publishedAt
32
-
33
- const coinA = a2b ? fromCoin : targetCoin
34
- const coinB = a2b ? targetCoin : fromCoin
21
+ const direction = compareCoins(fromCoin, targetCoin)
22
+ const integratePublishedAt =
23
+ "0x8faab90228e4c4df91c41626bbaefa19fc25c514405ac64de54578dec9e6f5ee"
24
+ const coinA = direction ? fromCoin : targetCoin
25
+ const coinB = direction ? targetCoin : fromCoin
35
26
 
36
27
  const typeArguments = [coinA, coinB]
37
28
  for (let i = 0; i < pools.length; i++) {
38
29
  const args = [
39
30
  tx.object(pools[i]),
40
- tx.pure.bool(a2b),
31
+ tx.pure.bool(direction),
41
32
  tx.pure.bool(byAmountIn),
42
33
  tx.pure.u64(amount.toString()),
43
34
  ]
@@ -48,7 +39,7 @@ export async function swapInPools(
48
39
  })
49
40
  }
50
41
 
51
- if (!checkInvalidSuiAddress(config.getWallet())) {
42
+ if (!checkInvalidSuiAddress(sender)) {
52
43
  throw new AggregateError(
53
44
  "Aggregator package not set",
54
45
  ConfigErrorCode.InvalidWallet
@@ -57,7 +48,7 @@ export async function swapInPools(
57
48
 
58
49
  const simulateRes = await client.devInspectTransactionBlock({
59
50
  transactionBlock: tx,
60
- sender: config.getWallet(),
51
+ sender,
61
52
  })
62
53
  if (simulateRes.error != null) {
63
54
  throw new AggregateError(
@@ -100,6 +91,8 @@ export async function swapInPools(
100
91
  }
101
92
 
102
93
  const event = valueData[tempIndex].parsedJson.data
94
+ console.log("event", JSON.stringify(event, null, 2))
95
+
103
96
  const currentSqrtPrice = event.step_results[0].current_sqrt_price
104
97
 
105
98
  const [decimalA, decimalB] = await Promise.all([
@@ -131,13 +124,13 @@ export async function swapInPools(
131
124
  path: [
132
125
  {
133
126
  id: pools[tempIndex],
134
- a2b,
135
- provider: CETUS_DEX,
127
+ direction,
128
+ provider: "CETUS",
136
129
  from: fromCoin,
137
130
  target: targetCoin,
138
- feeRate: 0,
139
- amountIn: 0,
140
- amountOut: 0,
131
+ feeRate: event.fee_rate,
132
+ amountIn: event.amount_in,
133
+ amountOut: event.amount_out,
141
134
  },
142
135
  ],
143
136
  amountIn: new BN(event.amount_in ?? 0),
@@ -1,114 +1,55 @@
1
1
  import {
2
- TransactionArgument,
3
2
  Transaction,
3
+ TransactionArgument,
4
4
  TransactionObjectArgument,
5
5
  } from "@mysten/sui/transactions"
6
- import { AggregatorConfig } from "../config"
7
- import {
8
- AGGREGATOR,
9
- CLOCK_ADDRESS,
10
- SWAP_A2B_FUNC,
11
- SWAP_B2A_FUNC,
12
- TURBOS_MODULE,
13
- TURBOS_VERSIONED,
14
- } from "../const"
15
- import { ConfigErrorCode, TransactionErrorCode } from "../errors"
16
- import { createTarget } from "../utils"
6
+ import { AggregatorClient, CLOCK_ADDRESS, Dex, Env, Path } from ".."
17
7
 
18
- export type TurbosSwapParams = {
19
- poolId: string
20
- amount: TransactionArgument
21
- amountLimit: number
22
- a2b: boolean
23
- byAmountIn: boolean
24
- coinA?: TransactionObjectArgument
25
- coinB?: TransactionObjectArgument
26
- useFullInputCoinAmount: boolean
27
- coinAType: string
28
- coinBType: string
29
- feeType: string
30
- }
8
+ export class Turbos implements Dex {
9
+ private versioned: string
31
10
 
32
- export type TurbosSwapResult = {
33
- targetCoin: TransactionObjectArgument
34
- amountIn: TransactionArgument
35
- amountOut: TransactionArgument
36
- txb: Transaction
37
- }
11
+ constructor(env: Env) {
12
+ if (env !== Env.Mainnet) {
13
+ throw new Error("Turbos only supported on mainnet")
14
+ }
38
15
 
39
- export async function turbosClmmSwapMovecall(
40
- swapParams: TurbosSwapParams,
41
- txb: Transaction,
42
- config: AggregatorConfig
43
- ): Promise<TurbosSwapResult> {
44
- const aggregatorPackage = config.getPackage(AGGREGATOR)
45
- if (aggregatorPackage == null) {
46
- throw new AggregateError(
47
- "Aggregator package not set",
48
- ConfigErrorCode.MissAggregatorPackage
49
- )
16
+ this.versioned =
17
+ "0xf1cf0e81048df168ebeb1b8030fad24b3e0b53ae827c25053fff0779c1445b6f"
50
18
  }
51
- const aggregatorPublishedAt = aggregatorPackage.publishedAt
52
19
 
53
- if (swapParams.a2b) {
54
- if (swapParams.coinA == null) {
55
- throw new AggregateError(
56
- "coinA is required",
57
- TransactionErrorCode.MissCoinA
58
- )
59
- }
60
- } else {
61
- if (swapParams.coinB == null) {
62
- throw new AggregateError(
63
- "coinB is required",
64
- TransactionErrorCode.MissCoinB
65
- )
20
+ async swap(
21
+ client: AggregatorClient,
22
+ txb: Transaction,
23
+ path: Path,
24
+ inputCoin: TransactionObjectArgument
25
+ ): Promise<TransactionObjectArgument> {
26
+ const { direction, from, target } = path
27
+
28
+ const [func, coinAType, coinBType] = direction
29
+ ? ["swap_a2b", from, target]
30
+ : ["swap_b2a", target, from]
31
+
32
+ if (path.extendedDetails == null) {
33
+ throw new Error("Extended details not supported")
34
+ } else {
35
+ if (path.extendedDetails.turbosFeeType == null) {
36
+ throw new Error("Turbos fee type not supported")
37
+ }
66
38
  }
67
- }
68
-
69
- const sqrtPriceLimit = swapParams.a2b
70
- ? "4295048016"
71
- : "79226673515401279992447579055"
72
-
73
- const args = swapParams.a2b
74
- ? [
75
- txb.object(swapParams.poolId),
76
- swapParams.amount,
77
- txb.pure.u64(swapParams.amountLimit),
78
- swapParams.coinA!,
79
- txb.pure.bool(swapParams.useFullInputCoinAmount),
80
- txb.pure.u128(sqrtPriceLimit),
81
- txb.object(CLOCK_ADDRESS),
82
- txb.object(TURBOS_VERSIONED),
83
- ]
84
- : [
85
- txb.object(swapParams.poolId),
86
- swapParams.amount,
87
- txb.pure.u64(swapParams.amountLimit),
88
- swapParams.coinB!,
89
- txb.pure.bool(swapParams.useFullInputCoinAmount),
90
- txb.pure.u128(sqrtPriceLimit),
91
- txb.object(CLOCK_ADDRESS),
92
- txb.object(TURBOS_VERSIONED),
93
- ]
94
39
 
95
- const func = swapParams.a2b ? SWAP_A2B_FUNC : SWAP_B2A_FUNC
40
+ const args = [
41
+ txb.object(path.id),
42
+ inputCoin,
43
+ txb.object(CLOCK_ADDRESS),
44
+ txb.object(this.versioned),
45
+ ]
96
46
 
97
- const target = createTarget(aggregatorPublishedAt, TURBOS_MODULE, func)
47
+ const res = txb.moveCall({
48
+ target: `${client.publishedAt()}::turbos::${func}`,
49
+ typeArguments: [coinAType, coinBType, path.extendedDetails.turbosFeeType],
50
+ arguments: args,
51
+ }) as TransactionObjectArgument
98
52
 
99
- const res = txb.moveCall({
100
- target,
101
- typeArguments: [
102
- swapParams.coinAType,
103
- swapParams.coinBType,
104
- swapParams.feeType,
105
- ],
106
- arguments: args,
107
- })
108
- return {
109
- targetCoin: res[0],
110
- amountIn: res[1],
111
- amountOut: res[2],
112
- txb,
53
+ return res
113
54
  }
114
55
  }
@@ -0,0 +1,52 @@
1
+ import {
2
+ Transaction,
3
+ TransactionObjectArgument,
4
+ } from "@mysten/sui/transactions"
5
+ import { AggregatorClient, Dex, Env, Path } from ".."
6
+ import { SUI_SYSTEM_ADDRESS } from "@mysten/sui/utils"
7
+
8
+ export class Volo implements Dex {
9
+ private nativePool: string
10
+ private metadata: string
11
+
12
+ constructor(env: Env) {
13
+ if (env !== Env.Mainnet) {
14
+ throw new Error("Volo only supported on mainnet")
15
+ }
16
+
17
+ this.nativePool =
18
+ "0x7fa2faa111b8c65bea48a23049bfd81ca8f971a262d981dcd9a17c3825cb5baf"
19
+ this.metadata =
20
+ "0x680cd26af32b2bde8d3361e804c53ec1d1cfe24c7f039eb7f549e8dfde389a60"
21
+ }
22
+
23
+ async swap(
24
+ client: AggregatorClient,
25
+ txb: Transaction,
26
+ path: Path,
27
+ inputCoin: TransactionObjectArgument
28
+ ): Promise<TransactionObjectArgument> {
29
+ const { direction } = path
30
+
31
+ if (!direction) {
32
+ throw new Error("Volo not support b2a swap")
33
+ }
34
+
35
+ const func = "swap_a2b"
36
+
37
+ const args = [
38
+ txb.object(this.nativePool),
39
+ txb.object(this.metadata),
40
+ txb.object("0x5"),
41
+ inputCoin,
42
+ ]
43
+
44
+ const res = txb.moveCall({
45
+ target: `${client.publishedAt()}::volo::${func}`,
46
+ typeArguments: [],
47
+ arguments: args,
48
+ }) as TransactionObjectArgument
49
+
50
+ return res
51
+ }
52
+ }
package/src/utils/coin.ts CHANGED
@@ -1,24 +1,27 @@
1
+ import { SuiZeroCoinFn } from "../const"
2
+ import { CoinAsset } from "../types/sui"
3
+ import { CoinUtils } from "../types/CoinAssist"
4
+ import { TransactionErrorCode } from "../errors"
5
+ import {
6
+ Transaction,
7
+ TransactionObjectArgument,
8
+ } from "@mysten/sui/transactions"
9
+
1
10
  export function completionCoin(s: string): string {
2
11
  const index = s.indexOf("::")
3
12
  if (index === -1) {
4
13
  return s
5
14
  }
6
-
7
15
  const prefix = s.substring(0, index)
8
16
  const rest = s.substring(index)
9
-
10
17
  if (!prefix.startsWith("0x")) {
11
18
  return s
12
19
  }
13
-
14
20
  const hexStr = prefix.substring(2)
15
-
16
21
  if (hexStr.length > 64) {
17
22
  return s
18
23
  }
19
-
20
24
  const paddedHexStr = hexStr.padStart(64, "0")
21
-
22
25
  return `0x${paddedHexStr}${rest}`
23
26
  }
24
27
 
@@ -38,3 +41,85 @@ export function compareCoins(coinA: string, coinB: string): boolean {
38
41
  // If both strings are the same length and all characters are equal
39
42
  return true // or coinB, they are equal
40
43
  }
44
+
45
+ export function mintZeroCoin(
46
+ txb: Transaction,
47
+ coinType: string
48
+ ): TransactionObjectArgument {
49
+ return txb.moveCall({
50
+ target: "0x2::coin::zero",
51
+ typeArguments: [coinType],
52
+ })
53
+ }
54
+
55
+ export type BuildCoinResult = {
56
+ targetCoin: TransactionObjectArgument
57
+ isMintZeroCoin: boolean
58
+ targetCoinAmount: number
59
+ }
60
+
61
+ export function buildInputCoin(
62
+ txb: Transaction,
63
+ allCoins: CoinAsset[],
64
+ amount: bigint,
65
+ coinType: string
66
+ ): BuildCoinResult {
67
+ const usedCoinAsests = CoinUtils.getCoinAssets(coinType, allCoins)
68
+ if (amount === BigInt(0) && usedCoinAsests.length === 0) {
69
+ const zeroCoin = mintZeroCoin(txb, coinType)
70
+ return {
71
+ targetCoin: zeroCoin,
72
+ isMintZeroCoin: true,
73
+ targetCoinAmount: 0,
74
+ }
75
+ }
76
+
77
+ let totalCoinBalance = CoinUtils.calculateTotalBalance(usedCoinAsests)
78
+ if (totalCoinBalance < amount) {
79
+ throw new AggregateError(
80
+ "Insufficient balance when build merge coin",
81
+ TransactionErrorCode.InsufficientBalance
82
+ )
83
+ }
84
+
85
+ if (CoinUtils.isSuiCoin(coinType)) {
86
+ const resultCoin = txb.splitCoins(txb.gas, [
87
+ txb.pure.u64(amount.toString()),
88
+ ])
89
+ return {
90
+ targetCoin: resultCoin,
91
+ isMintZeroCoin: true,
92
+ targetCoinAmount: Number(amount.toString()),
93
+ }
94
+ }
95
+
96
+ // sort used coin by amount, asc
97
+ let sortCoinAssets = CoinUtils.sortByBalance(usedCoinAsests)
98
+
99
+ // find first three coin if greater than amount
100
+ let totalThreeCoinBalance = sortCoinAssets
101
+ .slice(0, 3)
102
+ .reduce((acc, coin) => acc + coin.balance, BigInt(0))
103
+ if (totalThreeCoinBalance < BigInt(amount)) {
104
+ sortCoinAssets = CoinUtils.sortByBalanceDes(usedCoinAsests)
105
+ }
106
+
107
+ let selectedCoinResult = CoinUtils.selectCoinObjectIdGreaterThanOrEqual(
108
+ sortCoinAssets,
109
+ amount
110
+ )
111
+ const [masterCoin, ...mergedCoin] = selectedCoinResult.objectArray
112
+
113
+ if (mergedCoin.length > 0) {
114
+ txb.mergeCoins(
115
+ masterCoin,
116
+ mergedCoin.map((coin) => txb.object(coin))
117
+ )
118
+ }
119
+
120
+ return {
121
+ targetCoin: txb.object(masterCoin),
122
+ isMintZeroCoin: false,
123
+ targetCoinAmount: Number(amount.toString()),
124
+ }
125
+ }
@@ -5,7 +5,7 @@ export async function printTransaction(tx: Transaction, isPrint = true) {
5
5
  let i = 0
6
6
 
7
7
  tx.getData().commands.forEach((item, index) => {
8
- if (isPrint && i < 15) {
8
+ if (isPrint) {
9
9
  console.log(`transaction ${index}: `, JSON.stringify(item, null, 2))
10
10
  i++
11
11
  }