@cetusprotocol/aggregator-sdk 1.2.0 → 1.3.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/dist/index.d.mts +99 -11
- package/dist/index.d.ts +99 -11
- package/dist/index.js +432 -43
- package/dist/index.mjs +430 -44
- package/examples/mergeSwapExample.ts +142 -0
- package/package.json +1 -1
- package/.github/workflows/test.yml +0 -152
- package/.vscode/settings.json +0 -8
- package/CLAUDE.md +0 -101
- package/docs/Cetus_Aggregator_V3_/346/216/245/345/217/243/346/226/207/346/241/243.md +0 -706
- package/docs/REFACTOR.md +0 -24
- package/docs//350/267/257/345/276/204/346/213/223/346/211/221/346/216/222/345/272/217.md +0 -208
- package/script/copy-to-sui-aggregator.sh +0 -85
- package/test.json +0 -267
package/dist/index.js
CHANGED
|
@@ -2851,37 +2851,61 @@ var TransactionErrorCode = /* @__PURE__ */ ((TransactionErrorCode2) => {
|
|
|
2851
2851
|
TransactionErrorCode2["MissAftermathLpSupplyType"] = `MissAftermathLpSupplyType`;
|
|
2852
2852
|
return TransactionErrorCode2;
|
|
2853
2853
|
})(TransactionErrorCode || {});
|
|
2854
|
+
var AggregatorError = class _AggregatorError extends Error {
|
|
2855
|
+
constructor(message, errorCode) {
|
|
2856
|
+
super(message);
|
|
2857
|
+
this.message = message;
|
|
2858
|
+
this.errorCode = errorCode;
|
|
2859
|
+
}
|
|
2860
|
+
static isAggregatorErrorCode(e, code) {
|
|
2861
|
+
return e instanceof _AggregatorError && e.errorCode === code;
|
|
2862
|
+
}
|
|
2863
|
+
};
|
|
2854
2864
|
var AggregatorServerErrorCode = /* @__PURE__ */ ((AggregatorServerErrorCode2) => {
|
|
2855
2865
|
AggregatorServerErrorCode2[AggregatorServerErrorCode2["NumberTooLarge"] = 1e3] = "NumberTooLarge";
|
|
2856
2866
|
AggregatorServerErrorCode2[AggregatorServerErrorCode2["RateLimitExceeded"] = 1001] = "RateLimitExceeded";
|
|
2857
2867
|
AggregatorServerErrorCode2[AggregatorServerErrorCode2["InsufficientLiquidity"] = 1002] = "InsufficientLiquidity";
|
|
2858
2868
|
AggregatorServerErrorCode2[AggregatorServerErrorCode2["HoneyPot"] = 1003] = "HoneyPot";
|
|
2869
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["BadRequest"] = 1004] = "BadRequest";
|
|
2870
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["Forbidden"] = 1005] = "Forbidden";
|
|
2871
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["InternalServerError"] = 1006] = "InternalServerError";
|
|
2872
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["NotFoundRoute"] = 1007] = "NotFoundRoute";
|
|
2873
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["ServiceUnavailable"] = 1008] = "ServiceUnavailable";
|
|
2874
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["UnsupportedApiVersion"] = 1009] = "UnsupportedApiVersion";
|
|
2875
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["HoneyPotScam"] = 1010] = "HoneyPotScam";
|
|
2876
|
+
AggregatorServerErrorCode2[AggregatorServerErrorCode2["UnknownError"] = 400] = "UnknownError";
|
|
2859
2877
|
return AggregatorServerErrorCode2;
|
|
2860
2878
|
})(AggregatorServerErrorCode || {});
|
|
2861
|
-
function getAggregatorServerErrorMessage(code) {
|
|
2879
|
+
function getAggregatorServerErrorMessage(code, msg) {
|
|
2862
2880
|
switch (code) {
|
|
2863
2881
|
case 1e3 /* NumberTooLarge */:
|
|
2864
|
-
return "Number too large";
|
|
2882
|
+
return "Number too large" + (msg ? `: ${msg}` : "");
|
|
2865
2883
|
case 1001 /* RateLimitExceeded */:
|
|
2866
|
-
return "Rate limit exceeded";
|
|
2884
|
+
return "Rate limit exceeded" + (msg ? `: ${msg}` : "");
|
|
2867
2885
|
case 1002 /* InsufficientLiquidity */:
|
|
2868
|
-
return "Insufficient liquidity";
|
|
2886
|
+
return "Insufficient liquidity" + (msg ? `: ${msg}` : "");
|
|
2869
2887
|
case 1003 /* HoneyPot */:
|
|
2870
|
-
return "HoneyPot scam detected";
|
|
2888
|
+
return "HoneyPot scam detected" + (msg ? `: ${msg}` : "");
|
|
2889
|
+
case 1005 /* Forbidden */:
|
|
2890
|
+
return "Forbidden" + (msg ? `: ${msg}` : "");
|
|
2891
|
+
case 1004 /* BadRequest */:
|
|
2892
|
+
return "Bad request" + (msg ? `: ${msg}` : "");
|
|
2893
|
+
case 1006 /* InternalServerError */:
|
|
2894
|
+
return "Internal server error" + (msg ? `: ${msg}` : "");
|
|
2895
|
+
case 1007 /* NotFoundRoute */:
|
|
2896
|
+
return "Not found route" + (msg ? `: ${msg}` : "");
|
|
2897
|
+
case 1008 /* ServiceUnavailable */:
|
|
2898
|
+
return "Service unavailable" + (msg ? `: ${msg}` : "");
|
|
2899
|
+
case 1009 /* UnsupportedApiVersion */:
|
|
2900
|
+
return "Unsupported API version" + (msg ? `: ${msg}` : "");
|
|
2901
|
+
case 1010 /* HoneyPotScam */:
|
|
2902
|
+
return "Detected HoneyPot Scam" + (msg ? `: ${msg}` : "");
|
|
2903
|
+
case 400 /* UnknownError */:
|
|
2904
|
+
return "Unknown error" + (msg ? `: ${msg}` : "");
|
|
2871
2905
|
default:
|
|
2872
2906
|
return "Unknown error";
|
|
2873
2907
|
}
|
|
2874
2908
|
}
|
|
2875
|
-
var AggregatorError = class _AggregatorError extends Error {
|
|
2876
|
-
constructor(message, errorCode) {
|
|
2877
|
-
super(message);
|
|
2878
|
-
this.message = message;
|
|
2879
|
-
this.errorCode = errorCode;
|
|
2880
|
-
}
|
|
2881
|
-
static isAggregatorErrorCode(e, code) {
|
|
2882
|
-
return e instanceof _AggregatorError && e.errorCode === code;
|
|
2883
|
-
}
|
|
2884
|
-
};
|
|
2885
2909
|
var EQUAL = 0;
|
|
2886
2910
|
var LESS_THAN = 1;
|
|
2887
2911
|
var GREATER_THAN = 2;
|
|
@@ -3429,7 +3453,7 @@ var AGGREGATOR_V3_CONFIG = {
|
|
|
3429
3453
|
};
|
|
3430
3454
|
|
|
3431
3455
|
// src/api.ts
|
|
3432
|
-
var SDK_VERSION =
|
|
3456
|
+
var SDK_VERSION = 1010300;
|
|
3433
3457
|
function parseRouterResponse(data, byAmountIn) {
|
|
3434
3458
|
let packages = /* @__PURE__ */ new Map();
|
|
3435
3459
|
if (data.packages) {
|
|
@@ -3464,6 +3488,50 @@ function parseRouterResponse(data, byAmountIn) {
|
|
|
3464
3488
|
}))
|
|
3465
3489
|
};
|
|
3466
3490
|
}
|
|
3491
|
+
function parseMergeSwapResponse(data) {
|
|
3492
|
+
var _a;
|
|
3493
|
+
let packages = /* @__PURE__ */ new Map();
|
|
3494
|
+
if (data.packages) {
|
|
3495
|
+
if (data.packages instanceof Map) {
|
|
3496
|
+
packages = data.packages;
|
|
3497
|
+
} else if (typeof data.packages === "object") {
|
|
3498
|
+
Object.entries(data.packages).forEach(([key, value]) => {
|
|
3499
|
+
packages.set(key, value);
|
|
3500
|
+
});
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3503
|
+
const allRoutes = [];
|
|
3504
|
+
if (data.all_routes) {
|
|
3505
|
+
for (const route of data.all_routes) {
|
|
3506
|
+
const mergeRoute = {
|
|
3507
|
+
amountIn: new import_bn2.default(route.amount_in.toString()),
|
|
3508
|
+
amountOut: new import_bn2.default(route.amount_out.toString()),
|
|
3509
|
+
deviationRatio: route.deviation_ratio,
|
|
3510
|
+
paths: route.paths.map((path) => ({
|
|
3511
|
+
id: path.id,
|
|
3512
|
+
direction: path.direction,
|
|
3513
|
+
provider: path.provider,
|
|
3514
|
+
from: path.from,
|
|
3515
|
+
target: path.target,
|
|
3516
|
+
feeRate: path.fee_rate,
|
|
3517
|
+
amountIn: path.amount_in.toString(),
|
|
3518
|
+
amountOut: path.amount_out.toString(),
|
|
3519
|
+
version: path.version,
|
|
3520
|
+
publishedAt: path.published_at,
|
|
3521
|
+
extendedDetails: path.extended_details
|
|
3522
|
+
}))
|
|
3523
|
+
};
|
|
3524
|
+
allRoutes.push(mergeRoute);
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
return {
|
|
3528
|
+
quoteID: data.request_id || "",
|
|
3529
|
+
totalAmountOut: new import_bn2.default(((_a = data.total_amount_out) == null ? void 0 : _a.toString()) || "0"),
|
|
3530
|
+
allRoutes,
|
|
3531
|
+
packages,
|
|
3532
|
+
gas: data.gas
|
|
3533
|
+
};
|
|
3534
|
+
}
|
|
3467
3535
|
function getRouterResult(endpoint, apiKey, params, overlayFee, overlayFeeReceiver) {
|
|
3468
3536
|
return __async(this, null, function* () {
|
|
3469
3537
|
let response;
|
|
@@ -3476,7 +3544,7 @@ function getRouterResult(endpoint, apiKey, params, overlayFee, overlayFeeReceive
|
|
|
3476
3544
|
return null;
|
|
3477
3545
|
}
|
|
3478
3546
|
if (!response.ok) {
|
|
3479
|
-
let errorCode =
|
|
3547
|
+
let errorCode = 1004 /* BadRequest */;
|
|
3480
3548
|
if (response.status === 429) {
|
|
3481
3549
|
errorCode = 1001 /* RateLimitExceeded */;
|
|
3482
3550
|
}
|
|
@@ -3495,24 +3563,6 @@ function getRouterResult(endpoint, apiKey, params, overlayFee, overlayFeeReceive
|
|
|
3495
3563
|
};
|
|
3496
3564
|
}
|
|
3497
3565
|
const data = JSONbig__default.default.parse(yield response.text());
|
|
3498
|
-
const insufficientLiquidity = data.msg === "liquidity is not enough";
|
|
3499
|
-
if (data.msg && data.msg.indexOf("HoneyPot scam") > -1) {
|
|
3500
|
-
return {
|
|
3501
|
-
quoteID: "",
|
|
3502
|
-
amountIn: ZERO,
|
|
3503
|
-
amountOut: ZERO,
|
|
3504
|
-
paths: [],
|
|
3505
|
-
byAmountIn: params.byAmountIn,
|
|
3506
|
-
insufficientLiquidity,
|
|
3507
|
-
deviationRatio: 0,
|
|
3508
|
-
error: {
|
|
3509
|
-
code: 1003 /* HoneyPot */,
|
|
3510
|
-
msg: getAggregatorServerErrorMessage(
|
|
3511
|
-
1003 /* HoneyPot */
|
|
3512
|
-
)
|
|
3513
|
-
}
|
|
3514
|
-
};
|
|
3515
|
-
}
|
|
3516
3566
|
if (data.data != null) {
|
|
3517
3567
|
const res = parseRouterResponse(data.data, params.byAmountIn);
|
|
3518
3568
|
if (overlayFee > 0 && overlayFeeReceiver !== "0x0") {
|
|
@@ -3537,6 +3587,9 @@ function getRouterResult(endpoint, apiKey, params, overlayFee, overlayFeeReceive
|
|
|
3537
3587
|
}
|
|
3538
3588
|
return res;
|
|
3539
3589
|
}
|
|
3590
|
+
const code = processErrorStatusCode(data.code);
|
|
3591
|
+
const msg = getAggregatorServerErrorMessage(code, data.msg);
|
|
3592
|
+
const insufficientLiquidity = msg.includes("Insufficient liquidity");
|
|
3540
3593
|
return {
|
|
3541
3594
|
quoteID: "",
|
|
3542
3595
|
amountIn: ZERO,
|
|
@@ -3546,10 +3599,8 @@ function getRouterResult(endpoint, apiKey, params, overlayFee, overlayFeeReceive
|
|
|
3546
3599
|
byAmountIn: params.byAmountIn,
|
|
3547
3600
|
deviationRatio: 0,
|
|
3548
3601
|
error: {
|
|
3549
|
-
code
|
|
3550
|
-
msg
|
|
3551
|
-
1002 /* InsufficientLiquidity */
|
|
3552
|
-
)
|
|
3602
|
+
code,
|
|
3603
|
+
msg
|
|
3553
3604
|
}
|
|
3554
3605
|
};
|
|
3555
3606
|
});
|
|
@@ -3651,6 +3702,103 @@ function postRouterWithLiquidityChanges(endpoint, params) {
|
|
|
3651
3702
|
}
|
|
3652
3703
|
});
|
|
3653
3704
|
}
|
|
3705
|
+
function getMergeSwapRouter(endpoint, apiKey, params) {
|
|
3706
|
+
return __async(this, null, function* () {
|
|
3707
|
+
try {
|
|
3708
|
+
const { target, byAmountIn, depth, providers, froms } = params;
|
|
3709
|
+
const targetCoin = completionCoin(target);
|
|
3710
|
+
let url = `${endpoint}/multi_find_routes?target=${targetCoin}&by_amount_in=${byAmountIn}`;
|
|
3711
|
+
if (depth) {
|
|
3712
|
+
url += `&depth=${depth}`;
|
|
3713
|
+
}
|
|
3714
|
+
if (providers && providers.length > 0) {
|
|
3715
|
+
url += `&providers=${providers.join(",")}`;
|
|
3716
|
+
}
|
|
3717
|
+
if (apiKey.length > 0) {
|
|
3718
|
+
url += `&apiKey=${apiKey}`;
|
|
3719
|
+
}
|
|
3720
|
+
url += `&v=${SDK_VERSION}`;
|
|
3721
|
+
const fromsData = froms.map((from) => ({
|
|
3722
|
+
coin_type: completionCoin(from.coinType),
|
|
3723
|
+
amount: Number(from.amount.toString())
|
|
3724
|
+
}));
|
|
3725
|
+
url += `&froms=${encodeURIComponent(JSON.stringify(fromsData))}`;
|
|
3726
|
+
const response = yield fetch(url);
|
|
3727
|
+
console.log("response", response);
|
|
3728
|
+
return response;
|
|
3729
|
+
} catch (error) {
|
|
3730
|
+
console.error(error);
|
|
3731
|
+
return null;
|
|
3732
|
+
}
|
|
3733
|
+
});
|
|
3734
|
+
}
|
|
3735
|
+
function getMergeSwapResult(endpoint, apiKey, params, overlayFee, overlayFeeReceiver) {
|
|
3736
|
+
return __async(this, null, function* () {
|
|
3737
|
+
const response = yield getMergeSwapRouter(endpoint, apiKey, params);
|
|
3738
|
+
if (!response) {
|
|
3739
|
+
return null;
|
|
3740
|
+
}
|
|
3741
|
+
if (!response.ok) {
|
|
3742
|
+
let errorCode = 1004 /* BadRequest */;
|
|
3743
|
+
if (response.status === 429) {
|
|
3744
|
+
errorCode = 1001 /* RateLimitExceeded */;
|
|
3745
|
+
}
|
|
3746
|
+
return {
|
|
3747
|
+
quoteID: "",
|
|
3748
|
+
totalAmountOut: ZERO,
|
|
3749
|
+
allRoutes: [],
|
|
3750
|
+
error: {
|
|
3751
|
+
code: errorCode,
|
|
3752
|
+
msg: getAggregatorServerErrorMessage(errorCode)
|
|
3753
|
+
}
|
|
3754
|
+
};
|
|
3755
|
+
}
|
|
3756
|
+
if (!response.ok) {
|
|
3757
|
+
const code2 = processErrorStatusCode(response.status);
|
|
3758
|
+
const responseText2 = yield response.text();
|
|
3759
|
+
const data2 = JSONbig__default.default.parse(responseText2);
|
|
3760
|
+
const msg2 = getAggregatorServerErrorMessage(code2, data2.msg);
|
|
3761
|
+
return {
|
|
3762
|
+
quoteID: "",
|
|
3763
|
+
totalAmountOut: ZERO,
|
|
3764
|
+
allRoutes: [],
|
|
3765
|
+
error: {
|
|
3766
|
+
code: code2,
|
|
3767
|
+
msg: msg2
|
|
3768
|
+
}
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
const responseText = yield response.text();
|
|
3772
|
+
const data = JSONbig__default.default.parse(responseText);
|
|
3773
|
+
if (data.data != null) {
|
|
3774
|
+
console.log("data.data not null", data.data);
|
|
3775
|
+
const res = parseMergeSwapResponse(data.data);
|
|
3776
|
+
if (overlayFee > 0 && overlayFeeReceiver !== "0x0" && params.byAmountIn) {
|
|
3777
|
+
const overlayFeeAmount = res.totalAmountOut.mul(new import_bn2.default(overlayFee)).div(new import_bn2.default(1e6));
|
|
3778
|
+
res.totalAmountOut = res.totalAmountOut.sub(overlayFeeAmount);
|
|
3779
|
+
for (const route of res.allRoutes) {
|
|
3780
|
+
const routeFee = route.amountOut.mul(new import_bn2.default(overlayFee)).div(new import_bn2.default(1e6));
|
|
3781
|
+
route.amountOut = route.amountOut.sub(routeFee);
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
if (!res.packages) {
|
|
3785
|
+
res.packages = /* @__PURE__ */ new Map();
|
|
3786
|
+
}
|
|
3787
|
+
return res;
|
|
3788
|
+
}
|
|
3789
|
+
const code = processErrorStatusCode(data.code);
|
|
3790
|
+
const msg = getAggregatorServerErrorMessage(code, data.msg);
|
|
3791
|
+
return {
|
|
3792
|
+
quoteID: "",
|
|
3793
|
+
totalAmountOut: ZERO,
|
|
3794
|
+
allRoutes: [],
|
|
3795
|
+
error: {
|
|
3796
|
+
code,
|
|
3797
|
+
msg
|
|
3798
|
+
}
|
|
3799
|
+
};
|
|
3800
|
+
});
|
|
3801
|
+
}
|
|
3654
3802
|
function getDeepbookV3Config(endpoint) {
|
|
3655
3803
|
return __async(this, null, function* () {
|
|
3656
3804
|
const url = `${endpoint}/deepbookv3_config`;
|
|
@@ -3696,6 +3844,32 @@ function processFlattenRoutes(routerData) {
|
|
|
3696
3844
|
overlayFee: routerData.overlayFee
|
|
3697
3845
|
};
|
|
3698
3846
|
}
|
|
3847
|
+
function processErrorStatusCode(status) {
|
|
3848
|
+
switch (status) {
|
|
3849
|
+
case 400:
|
|
3850
|
+
return 1004 /* BadRequest */;
|
|
3851
|
+
case 403:
|
|
3852
|
+
return 1005 /* Forbidden */;
|
|
3853
|
+
case 429:
|
|
3854
|
+
return 1001 /* RateLimitExceeded */;
|
|
3855
|
+
case 4e3:
|
|
3856
|
+
return 1004 /* BadRequest */;
|
|
3857
|
+
case 4030:
|
|
3858
|
+
return 1005 /* Forbidden */;
|
|
3859
|
+
case 4040:
|
|
3860
|
+
return 1010 /* HoneyPotScam */;
|
|
3861
|
+
case 5e3:
|
|
3862
|
+
return 1002 /* InsufficientLiquidity */;
|
|
3863
|
+
case 5001:
|
|
3864
|
+
return 1007 /* NotFoundRoute */;
|
|
3865
|
+
case 5030:
|
|
3866
|
+
return 1008 /* ServiceUnavailable */;
|
|
3867
|
+
case 5040:
|
|
3868
|
+
return 1009 /* UnsupportedApiVersion */;
|
|
3869
|
+
default:
|
|
3870
|
+
return 400 /* UnknownError */;
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3699
3873
|
|
|
3700
3874
|
// src/config.ts
|
|
3701
3875
|
var Env = /* @__PURE__ */ ((Env2) => {
|
|
@@ -8107,6 +8281,96 @@ var FullsailRouter = class {
|
|
|
8107
8281
|
});
|
|
8108
8282
|
}
|
|
8109
8283
|
};
|
|
8284
|
+
var CetusDlmmRouter = class {
|
|
8285
|
+
constructor(env, partner) {
|
|
8286
|
+
if (env !== 0 /* Mainnet */) {
|
|
8287
|
+
throw new Error("CetusRouter only supported on mainnet");
|
|
8288
|
+
}
|
|
8289
|
+
this.globalConfig = "0xf31b605d117f959b9730e8c07b08b856cb05143c5e81d5751c90d2979e82f599";
|
|
8290
|
+
this.partner = partner != null ? partner : "0x59ae16f6c42f578063c2da9b9c0173fe58120ceae08e40fd8212c8eceb80bb86";
|
|
8291
|
+
this.versioned = "0x05370b2d656612dd5759cbe80463de301e3b94a921dfc72dd9daa2ecdeb2d0a8";
|
|
8292
|
+
}
|
|
8293
|
+
swap(txb, flattenedPath, swapContext, _extends) {
|
|
8294
|
+
const swapData = this.prepareSwapData(flattenedPath);
|
|
8295
|
+
this.executeSwapContract(txb, swapData, swapContext);
|
|
8296
|
+
}
|
|
8297
|
+
prepareSwapData(flattenedPath) {
|
|
8298
|
+
if (flattenedPath.path.publishedAt == null) {
|
|
8299
|
+
throw new Error("Cetus not set publishedAt");
|
|
8300
|
+
}
|
|
8301
|
+
const path = flattenedPath.path;
|
|
8302
|
+
const [coinAType, coinBType] = path.direction ? [path.from, path.target] : [path.target, path.from];
|
|
8303
|
+
const amountIn = flattenedPath.isLastUseOfIntermediateToken ? AGGREGATOR_V3_CONFIG.MAX_AMOUNT_IN : path.amountIn;
|
|
8304
|
+
return {
|
|
8305
|
+
coinAType,
|
|
8306
|
+
coinBType,
|
|
8307
|
+
direction: path.direction,
|
|
8308
|
+
amountIn,
|
|
8309
|
+
publishedAt: path.publishedAt,
|
|
8310
|
+
poolId: path.id
|
|
8311
|
+
};
|
|
8312
|
+
}
|
|
8313
|
+
executeSwapContract(txb, swapData, swapContext) {
|
|
8314
|
+
const args = [
|
|
8315
|
+
swapContext,
|
|
8316
|
+
txb.object(this.globalConfig),
|
|
8317
|
+
txb.object(swapData.poolId),
|
|
8318
|
+
txb.object(this.partner),
|
|
8319
|
+
txb.pure.bool(swapData.direction),
|
|
8320
|
+
txb.pure.u64(swapData.amountIn),
|
|
8321
|
+
txb.object(this.versioned),
|
|
8322
|
+
txb.object(utils.SUI_CLOCK_OBJECT_ID)
|
|
8323
|
+
];
|
|
8324
|
+
txb.moveCall({
|
|
8325
|
+
target: `${swapData.publishedAt}::cetus_dlmm::swap`,
|
|
8326
|
+
typeArguments: [swapData.coinAType, swapData.coinBType],
|
|
8327
|
+
arguments: args
|
|
8328
|
+
});
|
|
8329
|
+
}
|
|
8330
|
+
};
|
|
8331
|
+
var FerraDlmmRouter = class {
|
|
8332
|
+
constructor(env) {
|
|
8333
|
+
if (env !== 0 /* Mainnet */) {
|
|
8334
|
+
throw new Error("FerraRouter only supported on mainnet");
|
|
8335
|
+
}
|
|
8336
|
+
this.globalConfig = "0x5c9dacf5a678ea15b8569d65960330307e23d429289ca380e665b1aa175ebeca";
|
|
8337
|
+
}
|
|
8338
|
+
swap(txb, flattenedPath, swapContext, _extends) {
|
|
8339
|
+
const swapData = this.prepareSwapData(flattenedPath);
|
|
8340
|
+
this.executeSwapContract(txb, swapData, swapContext);
|
|
8341
|
+
}
|
|
8342
|
+
prepareSwapData(flattenedPath) {
|
|
8343
|
+
if (flattenedPath.path.publishedAt == null) {
|
|
8344
|
+
throw new Error("Ferra not set publishedAt");
|
|
8345
|
+
}
|
|
8346
|
+
const path = flattenedPath.path;
|
|
8347
|
+
const [coinAType, coinBType] = path.direction ? [path.from, path.target] : [path.target, path.from];
|
|
8348
|
+
const amountIn = flattenedPath.isLastUseOfIntermediateToken ? AGGREGATOR_V3_CONFIG.MAX_AMOUNT_IN : path.amountIn;
|
|
8349
|
+
return {
|
|
8350
|
+
coinAType,
|
|
8351
|
+
coinBType,
|
|
8352
|
+
direction: path.direction,
|
|
8353
|
+
amountIn,
|
|
8354
|
+
publishedAt: path.publishedAt,
|
|
8355
|
+
poolId: path.id
|
|
8356
|
+
};
|
|
8357
|
+
}
|
|
8358
|
+
executeSwapContract(txb, swapData, swapContext) {
|
|
8359
|
+
const args = [
|
|
8360
|
+
swapContext,
|
|
8361
|
+
txb.object(this.globalConfig),
|
|
8362
|
+
txb.object(swapData.poolId),
|
|
8363
|
+
txb.pure.bool(swapData.direction),
|
|
8364
|
+
txb.pure.u64(swapData.amountIn),
|
|
8365
|
+
txb.object(utils.SUI_CLOCK_OBJECT_ID)
|
|
8366
|
+
];
|
|
8367
|
+
txb.moveCall({
|
|
8368
|
+
target: `${swapData.publishedAt}::ferra_dlmm::swap`,
|
|
8369
|
+
typeArguments: [swapData.coinAType, swapData.coinBType],
|
|
8370
|
+
arguments: args
|
|
8371
|
+
});
|
|
8372
|
+
}
|
|
8373
|
+
};
|
|
8110
8374
|
|
|
8111
8375
|
// src/client.ts
|
|
8112
8376
|
var CETUS = "CETUS";
|
|
@@ -8139,6 +8403,8 @@ var MAGMA = "MAGMA";
|
|
|
8139
8403
|
var SEVENK = "SEVENK";
|
|
8140
8404
|
var HAEDALHMMV2 = "HAEDALHMMV2";
|
|
8141
8405
|
var FULLSAIL = "FULLSAIL";
|
|
8406
|
+
var CETUSDLMM = "CETUSDLMM";
|
|
8407
|
+
var FERRADLMM = "FERRADLMM";
|
|
8142
8408
|
var DEFAULT_ENDPOINT = "https://api-sui.cetus.zone/router_v3";
|
|
8143
8409
|
var ALL_DEXES = [
|
|
8144
8410
|
CETUS,
|
|
@@ -8169,7 +8435,9 @@ var ALL_DEXES = [
|
|
|
8169
8435
|
MAGMA,
|
|
8170
8436
|
SEVENK,
|
|
8171
8437
|
HAEDALHMMV2,
|
|
8172
|
-
FULLSAIL
|
|
8438
|
+
FULLSAIL,
|
|
8439
|
+
CETUSDLMM,
|
|
8440
|
+
FERRADLMM
|
|
8173
8441
|
];
|
|
8174
8442
|
function getAllProviders() {
|
|
8175
8443
|
return ALL_DEXES;
|
|
@@ -8248,6 +8516,7 @@ var _AggregatorClient = class _AggregatorClient {
|
|
|
8248
8516
|
);
|
|
8249
8517
|
this.apiKey = params.apiKey || "";
|
|
8250
8518
|
this.partner = params.partner;
|
|
8519
|
+
this.cetusDlmmPartner = params.cetusDlmmPartner;
|
|
8251
8520
|
if (params.overlayFeeRate) {
|
|
8252
8521
|
if (params.overlayFeeRate > 0 && params.overlayFeeRate <= CLIENT_CONFIG.MAX_OVERLAY_FEE_RATE) {
|
|
8253
8522
|
this.overlayFeeRate = params.overlayFeeRate * AGGREGATOR_V3_CONFIG.FEE_DENOMINATOR;
|
|
@@ -8313,11 +8582,22 @@ var _AggregatorClient = class _AggregatorClient {
|
|
|
8313
8582
|
);
|
|
8314
8583
|
});
|
|
8315
8584
|
}
|
|
8585
|
+
findMergeSwapRouters(params) {
|
|
8586
|
+
return __async(this, null, function* () {
|
|
8587
|
+
return getMergeSwapResult(
|
|
8588
|
+
this.endpoint,
|
|
8589
|
+
this.apiKey,
|
|
8590
|
+
params,
|
|
8591
|
+
this.overlayFeeRate,
|
|
8592
|
+
this.overlayFeeReceiver
|
|
8593
|
+
);
|
|
8594
|
+
});
|
|
8595
|
+
}
|
|
8316
8596
|
executeFlexibleInputSwap(txb, inputCoin, routerData, expectedAmountOut, amountLimit, pythPriceIDs, partner, deepbookv3DeepFee, packages) {
|
|
8317
8597
|
return __async(this, null, function* () {
|
|
8318
8598
|
});
|
|
8319
8599
|
}
|
|
8320
|
-
newDexRouterV3(provider, pythPriceIDs, partner) {
|
|
8600
|
+
newDexRouterV3(provider, pythPriceIDs, partner, cetusDlmmPartner) {
|
|
8321
8601
|
switch (provider) {
|
|
8322
8602
|
case CETUS:
|
|
8323
8603
|
return new CetusRouter(this.env, partner);
|
|
@@ -8377,13 +8657,17 @@ var _AggregatorClient = class _AggregatorClient {
|
|
|
8377
8657
|
return new HaedalHMMV2Router(this.env, pythPriceIDs);
|
|
8378
8658
|
case FULLSAIL:
|
|
8379
8659
|
return new FullsailRouter(this.env);
|
|
8660
|
+
case CETUSDLMM:
|
|
8661
|
+
return new CetusDlmmRouter(this.env, cetusDlmmPartner);
|
|
8662
|
+
case FERRADLMM:
|
|
8663
|
+
return new FerraDlmmRouter(this.env);
|
|
8380
8664
|
default:
|
|
8381
8665
|
throw new Error(
|
|
8382
8666
|
`${CLIENT_CONFIG.ERRORS.UNSUPPORTED_DEX} ${provider}`
|
|
8383
8667
|
);
|
|
8384
8668
|
}
|
|
8385
8669
|
}
|
|
8386
|
-
expectInputSwapV3(txb, inputCoin, routerData, expectAmountOut, amountOutLimit, pythPriceIDs, partner) {
|
|
8670
|
+
expectInputSwapV3(txb, inputCoin, routerData, expectAmountOut, amountOutLimit, pythPriceIDs, partner, cetusDlmmPartner) {
|
|
8387
8671
|
if (routerData.quoteID == null) {
|
|
8388
8672
|
throw new Error(CLIENT_CONFIG.ERRORS.QUOTE_ID_REQUIRED);
|
|
8389
8673
|
}
|
|
@@ -8408,7 +8692,12 @@ var _AggregatorClient = class _AggregatorClient {
|
|
|
8408
8692
|
if (!dexRouters.has(path.provider)) {
|
|
8409
8693
|
dexRouters.set(
|
|
8410
8694
|
path.provider,
|
|
8411
|
-
this.newDexRouterV3(
|
|
8695
|
+
this.newDexRouterV3(
|
|
8696
|
+
path.provider,
|
|
8697
|
+
pythPriceIDs,
|
|
8698
|
+
partner,
|
|
8699
|
+
cetusDlmmPartner
|
|
8700
|
+
)
|
|
8412
8701
|
);
|
|
8413
8702
|
}
|
|
8414
8703
|
const dex = dexRouters.get(path.provider);
|
|
@@ -8650,6 +8939,103 @@ var _AggregatorClient = class _AggregatorClient {
|
|
|
8650
8939
|
}
|
|
8651
8940
|
});
|
|
8652
8941
|
}
|
|
8942
|
+
mergeSwap(params) {
|
|
8943
|
+
return __async(this, null, function* () {
|
|
8944
|
+
const { router, inputCoins, slippage, txb, partner } = params;
|
|
8945
|
+
if (slippage > 1 || slippage < 0) {
|
|
8946
|
+
throw new Error(CLIENT_CONFIG.ERRORS.INVALID_SLIPPAGE);
|
|
8947
|
+
}
|
|
8948
|
+
if (!router.packages || !router.packages.get(PACKAGE_NAMES.AGGREGATOR_V3)) {
|
|
8949
|
+
throw new Error(CLIENT_CONFIG.ERRORS.PACKAGES_REQUIRED);
|
|
8950
|
+
}
|
|
8951
|
+
if (!router.allRoutes || router.allRoutes.length === 0) {
|
|
8952
|
+
throw new Error("No routes found in merge swap response");
|
|
8953
|
+
}
|
|
8954
|
+
const outputCoins = [];
|
|
8955
|
+
for (let i = 0; i < router.allRoutes.length && i < inputCoins.length; i++) {
|
|
8956
|
+
const route = router.allRoutes[i];
|
|
8957
|
+
const inputCoin = inputCoins[i];
|
|
8958
|
+
const routeRouter = {
|
|
8959
|
+
quoteID: router.quoteID,
|
|
8960
|
+
amountIn: route.amountIn,
|
|
8961
|
+
amountOut: route.amountOut,
|
|
8962
|
+
deviationRatio: Number(route.deviationRatio),
|
|
8963
|
+
byAmountIn: true,
|
|
8964
|
+
// Merge swap is always by amount in
|
|
8965
|
+
paths: route.paths,
|
|
8966
|
+
insufficientLiquidity: false,
|
|
8967
|
+
packages: router.packages
|
|
8968
|
+
};
|
|
8969
|
+
const routerParams = {
|
|
8970
|
+
router: routeRouter,
|
|
8971
|
+
inputCoin: inputCoin.coin,
|
|
8972
|
+
slippage,
|
|
8973
|
+
txb,
|
|
8974
|
+
partner: partner != null ? partner : this.partner
|
|
8975
|
+
};
|
|
8976
|
+
const outputCoin = yield this.routerSwap(routerParams);
|
|
8977
|
+
outputCoins.push(outputCoin);
|
|
8978
|
+
}
|
|
8979
|
+
if (outputCoins.length === 0) {
|
|
8980
|
+
throw new Error("No output coins generated from merge swap");
|
|
8981
|
+
}
|
|
8982
|
+
let finalOutputCoin = outputCoins[0];
|
|
8983
|
+
if (outputCoins.length > 1) {
|
|
8984
|
+
txb.mergeCoins(finalOutputCoin, outputCoins.slice(1));
|
|
8985
|
+
}
|
|
8986
|
+
return finalOutputCoin;
|
|
8987
|
+
});
|
|
8988
|
+
}
|
|
8989
|
+
fastMergeSwap(params) {
|
|
8990
|
+
return __async(this, null, function* () {
|
|
8991
|
+
const { router, slippage, txb, partner } = params;
|
|
8992
|
+
if (!router || !router.allRoutes || router.allRoutes.length === 0) {
|
|
8993
|
+
throw new Error("Invalid router: no routes found");
|
|
8994
|
+
}
|
|
8995
|
+
const firstRoute = router.allRoutes[0];
|
|
8996
|
+
const targetCoinType = firstRoute.paths[firstRoute.paths.length - 1].target;
|
|
8997
|
+
const inputCoins = [];
|
|
8998
|
+
const coinTypeSet = /* @__PURE__ */ new Set();
|
|
8999
|
+
for (const route of router.allRoutes) {
|
|
9000
|
+
const firstCoinType = route.paths[0].from;
|
|
9001
|
+
if (coinTypeSet.has(firstCoinType)) {
|
|
9002
|
+
continue;
|
|
9003
|
+
}
|
|
9004
|
+
coinTypeSet.add(firstCoinType);
|
|
9005
|
+
const coin = transactions.coinWithBalance({
|
|
9006
|
+
balance: BigInt(route.amountIn.toString()),
|
|
9007
|
+
useGasCoin: CoinUtils.isSuiCoin(firstCoinType),
|
|
9008
|
+
type: firstCoinType
|
|
9009
|
+
});
|
|
9010
|
+
inputCoins.push({ coinType: firstCoinType, coin });
|
|
9011
|
+
}
|
|
9012
|
+
const mergeSwapParams = {
|
|
9013
|
+
router,
|
|
9014
|
+
inputCoins,
|
|
9015
|
+
slippage,
|
|
9016
|
+
txb,
|
|
9017
|
+
partner: partner != null ? partner : this.partner
|
|
9018
|
+
};
|
|
9019
|
+
const targetCoin = yield this.mergeSwap(mergeSwapParams);
|
|
9020
|
+
if (CoinUtils.isSuiCoin(targetCoinType)) {
|
|
9021
|
+
txb.mergeCoins(txb.gas, [targetCoin]);
|
|
9022
|
+
} else {
|
|
9023
|
+
const targetCoinObjID = yield this.getOneCoinUsedToMerge(targetCoinType);
|
|
9024
|
+
if (targetCoinObjID != null) {
|
|
9025
|
+
txb.mergeCoins(txb.object(targetCoinObjID), [targetCoin]);
|
|
9026
|
+
} else {
|
|
9027
|
+
transferOrDestroyCoin(
|
|
9028
|
+
{
|
|
9029
|
+
coin: targetCoin,
|
|
9030
|
+
coinType: targetCoinType,
|
|
9031
|
+
packages: router.packages
|
|
9032
|
+
},
|
|
9033
|
+
txb
|
|
9034
|
+
);
|
|
9035
|
+
}
|
|
9036
|
+
}
|
|
9037
|
+
});
|
|
9038
|
+
}
|
|
8653
9039
|
fixableRouterSwapV3(params) {
|
|
8654
9040
|
return __async(this, null, function* () {
|
|
8655
9041
|
const { router, inputCoin, slippage, txb, partner } = params;
|
|
@@ -8943,6 +9329,7 @@ exports.AggregatorServerErrorCode = AggregatorServerErrorCode;
|
|
|
8943
9329
|
exports.BLUEFIN = BLUEFIN;
|
|
8944
9330
|
exports.BLUEMOVE = BLUEMOVE;
|
|
8945
9331
|
exports.CETUS = CETUS;
|
|
9332
|
+
exports.CETUSDLMM = CETUSDLMM;
|
|
8946
9333
|
exports.CETUS_DEX = CETUS_DEX;
|
|
8947
9334
|
exports.CETUS_MODULE = CETUS_MODULE;
|
|
8948
9335
|
exports.CETUS_PUBLISHED_AT = CETUS_PUBLISHED_AT;
|
|
@@ -8973,6 +9360,7 @@ exports.DEFAULT_GAS_BUDGET_FOR_TRANSFER = DEFAULT_GAS_BUDGET_FOR_TRANSFER;
|
|
|
8973
9360
|
exports.DEFAULT_GAS_BUDGET_FOR_TRANSFER_SUI = DEFAULT_GAS_BUDGET_FOR_TRANSFER_SUI;
|
|
8974
9361
|
exports.DEFAULT_NFT_TRANSFER_GAS_FEE = DEFAULT_NFT_TRANSFER_GAS_FEE;
|
|
8975
9362
|
exports.Env = Env;
|
|
9363
|
+
exports.FERRADLMM = FERRADLMM;
|
|
8976
9364
|
exports.FLOWXV2 = FLOWXV2;
|
|
8977
9365
|
exports.FLOWXV3 = FLOWXV3;
|
|
8978
9366
|
exports.FLOWX_AMM = FLOWX_AMM;
|
|
@@ -9081,6 +9469,7 @@ exports.getAggregatorV2PublishedAt = getAggregatorV2PublishedAt;
|
|
|
9081
9469
|
exports.getAllProviders = getAllProviders;
|
|
9082
9470
|
exports.getDeepbookV3Config = getDeepbookV3Config;
|
|
9083
9471
|
exports.getDefaultSuiInputType = getDefaultSuiInputType;
|
|
9472
|
+
exports.getMergeSwapResult = getMergeSwapResult;
|
|
9084
9473
|
exports.getOrCreateAccountCap = getOrCreateAccountCap;
|
|
9085
9474
|
exports.getProvidersExcluding = getProvidersExcluding;
|
|
9086
9475
|
exports.getProvidersIncluding = getProvidersIncluding;
|