@rhea-finance/cross-chain-aggregation-dex 1.0.0 → 1.0.2
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/README.md +24 -1
- package/dist/index.d.mts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.js +214 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +214 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,10 +38,11 @@ import {
|
|
|
38
38
|
const findPathAdapter: FindPathAdapter = {
|
|
39
39
|
async findPath(params) {
|
|
40
40
|
const response = await fetch(
|
|
41
|
-
`https://smartrouter.
|
|
41
|
+
`https://smartrouter.rhea.finance/findPath?${new URLSearchParams({
|
|
42
42
|
amountIn: params.amountIn,
|
|
43
43
|
tokenIn: params.tokenIn,
|
|
44
44
|
tokenOut: params.tokenOut,
|
|
45
|
+
pathDeep: "3",
|
|
45
46
|
slippage: String(params.slippage),
|
|
46
47
|
})}`
|
|
47
48
|
);
|
|
@@ -49,6 +50,27 @@ const findPathAdapter: FindPathAdapter = {
|
|
|
49
50
|
},
|
|
50
51
|
};
|
|
51
52
|
|
|
53
|
+
// SmartX swapMultiDexPath adapter (optional, used to compare and show the best quote)
|
|
54
|
+
const swapMultiDexPathAdapter = {
|
|
55
|
+
async swapMultiDexPath(params: any) {
|
|
56
|
+
const response = await fetch(
|
|
57
|
+
`https://smartx.rhea.finance/swapMultiDexPath?${new URLSearchParams({
|
|
58
|
+
amountIn: params.amountIn,
|
|
59
|
+
tokenIn: params.tokenIn,
|
|
60
|
+
tokenOut: params.tokenOut,
|
|
61
|
+
slippage: String(params.slippage),
|
|
62
|
+
pathDeep: "2",
|
|
63
|
+
chainId: "0",
|
|
64
|
+
routerCount: "1",
|
|
65
|
+
skipUnwrapNativeToken: "false",
|
|
66
|
+
user: params.user,
|
|
67
|
+
receiveUser: params.receiveUser,
|
|
68
|
+
})}`
|
|
69
|
+
);
|
|
70
|
+
return response.json();
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
52
74
|
// NearIntents quotation adapter
|
|
53
75
|
const intentsQuotationAdapter: IntentsQuotationAdapter = {
|
|
54
76
|
async quote(params) {
|
|
@@ -88,6 +110,7 @@ import { NearSmartRouter } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
|
88
110
|
|
|
89
111
|
const router = new NearSmartRouter({
|
|
90
112
|
findPathAdapter,
|
|
113
|
+
swapMultiDexPathAdapter,
|
|
91
114
|
nearChainAdapter,
|
|
92
115
|
configAdapter,
|
|
93
116
|
});
|
package/dist/index.d.mts
CHANGED
|
@@ -28,6 +28,8 @@ interface QuoteParams {
|
|
|
28
28
|
slippage: number;
|
|
29
29
|
swapType?: "EXACT_INPUT" | "EXACT_OUTPUT";
|
|
30
30
|
recipient?: string;
|
|
31
|
+
/** Caller's NEAR account ID (used as fallback for SmartX user/receiveUser when recipient is not available). */
|
|
32
|
+
accountId?: string;
|
|
31
33
|
}
|
|
32
34
|
interface QuoteResult {
|
|
33
35
|
success: boolean;
|
|
@@ -43,6 +45,18 @@ interface QuoteResult {
|
|
|
43
45
|
* - Kept optional to avoid tightly coupling implementation details into core logic
|
|
44
46
|
*/
|
|
45
47
|
rawRoutes?: any[];
|
|
48
|
+
/** Quote source identifier (used when multiple quote backends are supported). */
|
|
49
|
+
quoteSource?: "findPath" | "smartx";
|
|
50
|
+
/** SmartX quote payload (present when quoteSource === "smartx"). */
|
|
51
|
+
smartxResult?: {
|
|
52
|
+
amountIn: string;
|
|
53
|
+
amountOut: string;
|
|
54
|
+
minAmountOut: string;
|
|
55
|
+
dexs?: string[];
|
|
56
|
+
msg?: string;
|
|
57
|
+
signature?: string;
|
|
58
|
+
tokens?: string[];
|
|
59
|
+
};
|
|
46
60
|
priceImpact?: number;
|
|
47
61
|
avgFee?: number;
|
|
48
62
|
estimatedGas?: string;
|
|
@@ -110,6 +124,37 @@ interface FindPathAdapter {
|
|
|
110
124
|
supportLedger?: boolean;
|
|
111
125
|
}): Promise<FindPathResponse>;
|
|
112
126
|
}
|
|
127
|
+
/** SmartX swapMultiDexPath response. */
|
|
128
|
+
interface SwapMultiDexPathResponse {
|
|
129
|
+
result_code: number;
|
|
130
|
+
result_message?: string;
|
|
131
|
+
result_data: {
|
|
132
|
+
amount_in: string;
|
|
133
|
+
amount_out: string;
|
|
134
|
+
min_amount_out: string;
|
|
135
|
+
dexs?: string[];
|
|
136
|
+
msg?: string;
|
|
137
|
+
signature?: string;
|
|
138
|
+
tokens?: string[];
|
|
139
|
+
[key: string]: any;
|
|
140
|
+
} | null;
|
|
141
|
+
}
|
|
142
|
+
/** Adapter for querying SmartX swapMultiDexPath. */
|
|
143
|
+
interface SwapMultiDexPathAdapter {
|
|
144
|
+
swapMultiDexPath(params: {
|
|
145
|
+
amountIn: string;
|
|
146
|
+
tokenIn: string;
|
|
147
|
+
tokenOut: string;
|
|
148
|
+
slippage: number;
|
|
149
|
+
pathDeep: number;
|
|
150
|
+
chainId: number;
|
|
151
|
+
routerCount: number;
|
|
152
|
+
skipUnwrapNativeToken: boolean;
|
|
153
|
+
user: string;
|
|
154
|
+
receiveUser: string;
|
|
155
|
+
[key: string]: any;
|
|
156
|
+
}): Promise<SwapMultiDexPathResponse>;
|
|
157
|
+
}
|
|
113
158
|
/** NearIntents quote result. */
|
|
114
159
|
interface IntentsQuoteResult {
|
|
115
160
|
quoteStatus: "success" | "error";
|
|
@@ -166,6 +211,8 @@ interface ConfigAdapter {
|
|
|
166
211
|
getFindPathUrl(): string;
|
|
167
212
|
/** Storage deposit amount (yoctoNEAR) for `storage_deposit` when needed. */
|
|
168
213
|
getTokenStorageDepositRead?(): string;
|
|
214
|
+
/** Aggregate DEX contract id for SmartX execution. */
|
|
215
|
+
getAggregateDexContractId?(): string;
|
|
169
216
|
}
|
|
170
217
|
|
|
171
218
|
declare const logger: {
|
|
@@ -203,16 +250,20 @@ declare function normalizeDestinationAsset(assetId: string, wrapNearContractId?:
|
|
|
203
250
|
|
|
204
251
|
interface NearSmartRouterConfig {
|
|
205
252
|
findPathAdapter: FindPathAdapter;
|
|
253
|
+
/** Optional: SmartX quote adapter. When provided, quote() will compare results and return the best. */
|
|
254
|
+
swapMultiDexPathAdapter?: SwapMultiDexPathAdapter;
|
|
206
255
|
nearChainAdapter: NearChainAdapter;
|
|
207
256
|
configAdapter: ConfigAdapter;
|
|
208
257
|
}
|
|
209
258
|
declare class NearSmartRouter implements DexRouter {
|
|
210
259
|
private findPathAdapter;
|
|
260
|
+
private swapMultiDexPathAdapter?;
|
|
211
261
|
private nearChainAdapter;
|
|
212
262
|
private configAdapter;
|
|
213
263
|
private wrapNearContractId;
|
|
214
264
|
private refExchangeId;
|
|
215
265
|
private tokenStorageDepositRead;
|
|
266
|
+
private aggregateDexContractId?;
|
|
216
267
|
constructor(config: NearSmartRouterConfig);
|
|
217
268
|
/**
|
|
218
269
|
* Get a swap quote (normalizes token ids and queries FindPath for routes).
|
|
@@ -275,4 +326,4 @@ interface CompleteQuoteConfig {
|
|
|
275
326
|
*/
|
|
276
327
|
declare function completeQuote(params: CompleteQuoteParams, config: CompleteQuoteConfig): Promise<CompleteQuoteResult>;
|
|
277
328
|
|
|
278
|
-
export { type BluechipTokenConfig, type BluechipTokensConfig, type CompleteQuoteConfig, type CompleteQuoteParams, type CompleteQuoteResult, type ConfigAdapter, type DexRouter, type ExecuteParams, type ExecuteResult, type FindPathAdapter, type FindPathResponse, type IntentsQuotationAdapter, type IntentsQuoteResult, type NearChainAdapter, NearSmartRouter, type NearSmartRouterConfig, type PoolInfo, type QuoteParams, type QuoteResult, type Route, type SupportedChain, type TokenInfo, completeQuote, convertSlippageToBasisPoints, findBestBluechipToken, getBluechipTokensConfig, isNearIntentsSupportedToken, logger, normalizeDestinationAsset, normalizeTokenId, setBluechipTokensConfig };
|
|
329
|
+
export { type BluechipTokenConfig, type BluechipTokensConfig, type CompleteQuoteConfig, type CompleteQuoteParams, type CompleteQuoteResult, type ConfigAdapter, type DexRouter, type ExecuteParams, type ExecuteResult, type FindPathAdapter, type FindPathResponse, type IntentsQuotationAdapter, type IntentsQuoteResult, type NearChainAdapter, NearSmartRouter, type NearSmartRouterConfig, type PoolInfo, type QuoteParams, type QuoteResult, type Route, type SupportedChain, type SwapMultiDexPathAdapter, type SwapMultiDexPathResponse, type TokenInfo, completeQuote, convertSlippageToBasisPoints, findBestBluechipToken, getBluechipTokensConfig, isNearIntentsSupportedToken, logger, normalizeDestinationAsset, normalizeTokenId, setBluechipTokensConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ interface QuoteParams {
|
|
|
28
28
|
slippage: number;
|
|
29
29
|
swapType?: "EXACT_INPUT" | "EXACT_OUTPUT";
|
|
30
30
|
recipient?: string;
|
|
31
|
+
/** Caller's NEAR account ID (used as fallback for SmartX user/receiveUser when recipient is not available). */
|
|
32
|
+
accountId?: string;
|
|
31
33
|
}
|
|
32
34
|
interface QuoteResult {
|
|
33
35
|
success: boolean;
|
|
@@ -43,6 +45,18 @@ interface QuoteResult {
|
|
|
43
45
|
* - Kept optional to avoid tightly coupling implementation details into core logic
|
|
44
46
|
*/
|
|
45
47
|
rawRoutes?: any[];
|
|
48
|
+
/** Quote source identifier (used when multiple quote backends are supported). */
|
|
49
|
+
quoteSource?: "findPath" | "smartx";
|
|
50
|
+
/** SmartX quote payload (present when quoteSource === "smartx"). */
|
|
51
|
+
smartxResult?: {
|
|
52
|
+
amountIn: string;
|
|
53
|
+
amountOut: string;
|
|
54
|
+
minAmountOut: string;
|
|
55
|
+
dexs?: string[];
|
|
56
|
+
msg?: string;
|
|
57
|
+
signature?: string;
|
|
58
|
+
tokens?: string[];
|
|
59
|
+
};
|
|
46
60
|
priceImpact?: number;
|
|
47
61
|
avgFee?: number;
|
|
48
62
|
estimatedGas?: string;
|
|
@@ -110,6 +124,37 @@ interface FindPathAdapter {
|
|
|
110
124
|
supportLedger?: boolean;
|
|
111
125
|
}): Promise<FindPathResponse>;
|
|
112
126
|
}
|
|
127
|
+
/** SmartX swapMultiDexPath response. */
|
|
128
|
+
interface SwapMultiDexPathResponse {
|
|
129
|
+
result_code: number;
|
|
130
|
+
result_message?: string;
|
|
131
|
+
result_data: {
|
|
132
|
+
amount_in: string;
|
|
133
|
+
amount_out: string;
|
|
134
|
+
min_amount_out: string;
|
|
135
|
+
dexs?: string[];
|
|
136
|
+
msg?: string;
|
|
137
|
+
signature?: string;
|
|
138
|
+
tokens?: string[];
|
|
139
|
+
[key: string]: any;
|
|
140
|
+
} | null;
|
|
141
|
+
}
|
|
142
|
+
/** Adapter for querying SmartX swapMultiDexPath. */
|
|
143
|
+
interface SwapMultiDexPathAdapter {
|
|
144
|
+
swapMultiDexPath(params: {
|
|
145
|
+
amountIn: string;
|
|
146
|
+
tokenIn: string;
|
|
147
|
+
tokenOut: string;
|
|
148
|
+
slippage: number;
|
|
149
|
+
pathDeep: number;
|
|
150
|
+
chainId: number;
|
|
151
|
+
routerCount: number;
|
|
152
|
+
skipUnwrapNativeToken: boolean;
|
|
153
|
+
user: string;
|
|
154
|
+
receiveUser: string;
|
|
155
|
+
[key: string]: any;
|
|
156
|
+
}): Promise<SwapMultiDexPathResponse>;
|
|
157
|
+
}
|
|
113
158
|
/** NearIntents quote result. */
|
|
114
159
|
interface IntentsQuoteResult {
|
|
115
160
|
quoteStatus: "success" | "error";
|
|
@@ -166,6 +211,8 @@ interface ConfigAdapter {
|
|
|
166
211
|
getFindPathUrl(): string;
|
|
167
212
|
/** Storage deposit amount (yoctoNEAR) for `storage_deposit` when needed. */
|
|
168
213
|
getTokenStorageDepositRead?(): string;
|
|
214
|
+
/** Aggregate DEX contract id for SmartX execution. */
|
|
215
|
+
getAggregateDexContractId?(): string;
|
|
169
216
|
}
|
|
170
217
|
|
|
171
218
|
declare const logger: {
|
|
@@ -203,16 +250,20 @@ declare function normalizeDestinationAsset(assetId: string, wrapNearContractId?:
|
|
|
203
250
|
|
|
204
251
|
interface NearSmartRouterConfig {
|
|
205
252
|
findPathAdapter: FindPathAdapter;
|
|
253
|
+
/** Optional: SmartX quote adapter. When provided, quote() will compare results and return the best. */
|
|
254
|
+
swapMultiDexPathAdapter?: SwapMultiDexPathAdapter;
|
|
206
255
|
nearChainAdapter: NearChainAdapter;
|
|
207
256
|
configAdapter: ConfigAdapter;
|
|
208
257
|
}
|
|
209
258
|
declare class NearSmartRouter implements DexRouter {
|
|
210
259
|
private findPathAdapter;
|
|
260
|
+
private swapMultiDexPathAdapter?;
|
|
211
261
|
private nearChainAdapter;
|
|
212
262
|
private configAdapter;
|
|
213
263
|
private wrapNearContractId;
|
|
214
264
|
private refExchangeId;
|
|
215
265
|
private tokenStorageDepositRead;
|
|
266
|
+
private aggregateDexContractId?;
|
|
216
267
|
constructor(config: NearSmartRouterConfig);
|
|
217
268
|
/**
|
|
218
269
|
* Get a swap quote (normalizes token ids and queries FindPath for routes).
|
|
@@ -275,4 +326,4 @@ interface CompleteQuoteConfig {
|
|
|
275
326
|
*/
|
|
276
327
|
declare function completeQuote(params: CompleteQuoteParams, config: CompleteQuoteConfig): Promise<CompleteQuoteResult>;
|
|
277
328
|
|
|
278
|
-
export { type BluechipTokenConfig, type BluechipTokensConfig, type CompleteQuoteConfig, type CompleteQuoteParams, type CompleteQuoteResult, type ConfigAdapter, type DexRouter, type ExecuteParams, type ExecuteResult, type FindPathAdapter, type FindPathResponse, type IntentsQuotationAdapter, type IntentsQuoteResult, type NearChainAdapter, NearSmartRouter, type NearSmartRouterConfig, type PoolInfo, type QuoteParams, type QuoteResult, type Route, type SupportedChain, type TokenInfo, completeQuote, convertSlippageToBasisPoints, findBestBluechipToken, getBluechipTokensConfig, isNearIntentsSupportedToken, logger, normalizeDestinationAsset, normalizeTokenId, setBluechipTokensConfig };
|
|
329
|
+
export { type BluechipTokenConfig, type BluechipTokensConfig, type CompleteQuoteConfig, type CompleteQuoteParams, type CompleteQuoteResult, type ConfigAdapter, type DexRouter, type ExecuteParams, type ExecuteResult, type FindPathAdapter, type FindPathResponse, type IntentsQuotationAdapter, type IntentsQuoteResult, type NearChainAdapter, NearSmartRouter, type NearSmartRouterConfig, type PoolInfo, type QuoteParams, type QuoteResult, type Route, type SupportedChain, type SwapMultiDexPathAdapter, type SwapMultiDexPathResponse, type TokenInfo, completeQuote, convertSlippageToBasisPoints, findBestBluechipToken, getBluechipTokensConfig, isNearIntentsSupportedToken, logger, normalizeDestinationAsset, normalizeTokenId, setBluechipTokensConfig };
|
package/dist/index.js
CHANGED
|
@@ -167,11 +167,13 @@ function normalizeDestinationAsset(assetId, wrapNearContractId = "wrap.near") {
|
|
|
167
167
|
var NearSmartRouter = class {
|
|
168
168
|
constructor(config) {
|
|
169
169
|
this.findPathAdapter = config.findPathAdapter;
|
|
170
|
+
this.swapMultiDexPathAdapter = config.swapMultiDexPathAdapter;
|
|
170
171
|
this.nearChainAdapter = config.nearChainAdapter;
|
|
171
172
|
this.configAdapter = config.configAdapter;
|
|
172
173
|
this.wrapNearContractId = this.configAdapter.getWrapNearContractId();
|
|
173
174
|
this.refExchangeId = this.configAdapter.getRefExchangeId();
|
|
174
175
|
this.tokenStorageDepositRead = this.configAdapter.getTokenStorageDepositRead?.() || "1250000000000000000000";
|
|
176
|
+
this.aggregateDexContractId = this.configAdapter.getAggregateDexContractId?.() || void 0;
|
|
175
177
|
}
|
|
176
178
|
/**
|
|
177
179
|
* Get a swap quote (normalizes token ids and queries FindPath for routes).
|
|
@@ -183,8 +185,10 @@ var NearSmartRouter = class {
|
|
|
183
185
|
tokenOut,
|
|
184
186
|
amountIn,
|
|
185
187
|
slippage,
|
|
186
|
-
swapType: _swapType = "EXACT_INPUT"
|
|
188
|
+
swapType: _swapType = "EXACT_INPUT",
|
|
187
189
|
// Currently not used, reserved for future use
|
|
190
|
+
recipient,
|
|
191
|
+
accountId
|
|
188
192
|
} = params;
|
|
189
193
|
if (!tokenIn?.address || !tokenOut?.address) {
|
|
190
194
|
return {
|
|
@@ -230,26 +234,88 @@ var NearSmartRouter = class {
|
|
|
230
234
|
}
|
|
231
235
|
const slippageBps = convertSlippageToBasisPoints(slippage);
|
|
232
236
|
const slippageDecimalForApi = slippageBps / 1e4;
|
|
233
|
-
|
|
237
|
+
const smartxUser = recipient || accountId || "";
|
|
238
|
+
const canCallSmartX = this.swapMultiDexPathAdapter && !!smartxUser;
|
|
239
|
+
logger.debug("SmartRouter quote - Calling quote backends:", {
|
|
234
240
|
tokenIn: normalizedTokenIn,
|
|
235
241
|
tokenOut: normalizedTokenOut,
|
|
236
242
|
amountIn,
|
|
237
243
|
slippage: slippageDecimalForApi,
|
|
238
|
-
slippageBps
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
tokenIn: normalizedTokenIn,
|
|
242
|
-
tokenOut: normalizedTokenOut,
|
|
243
|
-
amountIn: String(amountIn),
|
|
244
|
-
slippage: slippageDecimalForApi,
|
|
245
|
-
supportLedger: false
|
|
244
|
+
slippageBps,
|
|
245
|
+
hasSmartX: canCallSmartX,
|
|
246
|
+
smartxUser: smartxUser || "none"
|
|
246
247
|
});
|
|
248
|
+
const [findPathResp, smartxResp] = await Promise.all([
|
|
249
|
+
this.findPathAdapter.findPath({
|
|
250
|
+
tokenIn: normalizedTokenIn,
|
|
251
|
+
tokenOut: normalizedTokenOut,
|
|
252
|
+
amountIn: String(amountIn),
|
|
253
|
+
slippage: slippageDecimalForApi,
|
|
254
|
+
// v1 requires pathDeep=3 (handled by adapter implementation)
|
|
255
|
+
supportLedger: false
|
|
256
|
+
}),
|
|
257
|
+
canCallSmartX ? this.swapMultiDexPathAdapter.swapMultiDexPath({
|
|
258
|
+
amountIn: String(amountIn),
|
|
259
|
+
tokenIn: normalizedTokenIn,
|
|
260
|
+
tokenOut: normalizedTokenOut,
|
|
261
|
+
slippage: slippageDecimalForApi,
|
|
262
|
+
pathDeep: 2,
|
|
263
|
+
chainId: 0,
|
|
264
|
+
routerCount: 1,
|
|
265
|
+
skipUnwrapNativeToken: false,
|
|
266
|
+
user: smartxUser,
|
|
267
|
+
receiveUser: smartxUser
|
|
268
|
+
}) : Promise.resolve(null)
|
|
269
|
+
]);
|
|
247
270
|
logger.debug("SmartRouter quote - findPath response:", {
|
|
248
|
-
result_code:
|
|
249
|
-
result_msg:
|
|
250
|
-
hasRoutes: !!
|
|
271
|
+
result_code: findPathResp?.result_code,
|
|
272
|
+
result_msg: findPathResp?.result_msg || findPathResp?.result_message,
|
|
273
|
+
hasRoutes: !!findPathResp?.result_data?.routes?.length
|
|
251
274
|
});
|
|
252
|
-
if (
|
|
275
|
+
if (smartxResp) {
|
|
276
|
+
logger.debug("SmartRouter quote - SmartX response:", {
|
|
277
|
+
result_code: smartxResp?.result_code,
|
|
278
|
+
result_msg: smartxResp?.result_message,
|
|
279
|
+
hasData: !!smartxResp?.result_data
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (findPathResp?.result_code !== 0 || !findPathResp?.result_data?.routes?.length) {
|
|
283
|
+
const smartxData2 = smartxResp?.result_code === 0 ? smartxResp?.result_data : null;
|
|
284
|
+
if (smartxData2?.amount_out) {
|
|
285
|
+
const smartxAmt = new Big__default.default(smartxData2.amount_out || 0);
|
|
286
|
+
const smartxMin = new Big__default.default(smartxData2.min_amount_out || 0);
|
|
287
|
+
if (smartxAmt.lte(0) || smartxMin.lt(0)) {
|
|
288
|
+
return {
|
|
289
|
+
success: false,
|
|
290
|
+
tokenIn,
|
|
291
|
+
tokenOut,
|
|
292
|
+
amountIn,
|
|
293
|
+
amountOut: "0",
|
|
294
|
+
minAmountOut: "0",
|
|
295
|
+
routes: [],
|
|
296
|
+
error: findPathResp?.result_msg || findPathResp?.result_message || "No route found"
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
success: true,
|
|
301
|
+
tokenIn,
|
|
302
|
+
tokenOut,
|
|
303
|
+
amountIn,
|
|
304
|
+
amountOut: String(smartxData2.amount_out),
|
|
305
|
+
minAmountOut: String(smartxData2.min_amount_out || "0"),
|
|
306
|
+
routes: [],
|
|
307
|
+
quoteSource: "smartx",
|
|
308
|
+
smartxResult: {
|
|
309
|
+
amountIn: String(smartxData2.amount_in || amountIn),
|
|
310
|
+
amountOut: String(smartxData2.amount_out),
|
|
311
|
+
minAmountOut: String(smartxData2.min_amount_out || "0"),
|
|
312
|
+
dexs: smartxData2.dexs,
|
|
313
|
+
msg: smartxData2.msg,
|
|
314
|
+
signature: smartxData2.signature,
|
|
315
|
+
tokens: smartxData2.tokens
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
253
319
|
return {
|
|
254
320
|
success: false,
|
|
255
321
|
tokenIn,
|
|
@@ -258,10 +324,10 @@ var NearSmartRouter = class {
|
|
|
258
324
|
amountOut: "0",
|
|
259
325
|
minAmountOut: "0",
|
|
260
326
|
routes: [],
|
|
261
|
-
error:
|
|
327
|
+
error: findPathResp?.result_msg || findPathResp?.result_message || "No route found"
|
|
262
328
|
};
|
|
263
329
|
}
|
|
264
|
-
const { routes: serverRoutes, amount_out } =
|
|
330
|
+
const { routes: serverRoutes, amount_out } = findPathResp.result_data;
|
|
265
331
|
const slippageDecimal = new Big__default.default(slippageBps).div(1e4);
|
|
266
332
|
const routes = serverRoutes.map((route) => ({
|
|
267
333
|
pools: route.pools.map((pool) => ({
|
|
@@ -277,7 +343,7 @@ var NearSmartRouter = class {
|
|
|
277
343
|
}));
|
|
278
344
|
const amountOut = new Big__default.default(amount_out || 0);
|
|
279
345
|
const minAmountOut = amountOut.mul(new Big__default.default(1).minus(slippageDecimal)).toFixed(0, Big__default.default.roundDown);
|
|
280
|
-
|
|
346
|
+
const findPathQuote = {
|
|
281
347
|
success: true,
|
|
282
348
|
tokenIn,
|
|
283
349
|
tokenOut,
|
|
@@ -286,8 +352,36 @@ var NearSmartRouter = class {
|
|
|
286
352
|
minAmountOut,
|
|
287
353
|
routes,
|
|
288
354
|
// Save raw serverRoutes data for executeSwap
|
|
289
|
-
rawRoutes: serverRoutes
|
|
355
|
+
rawRoutes: serverRoutes,
|
|
356
|
+
quoteSource: "findPath"
|
|
290
357
|
};
|
|
358
|
+
const smartxData = smartxResp?.result_code === 0 ? smartxResp?.result_data : null;
|
|
359
|
+
if (smartxData?.amount_out) {
|
|
360
|
+
const smartxAmountOut = new Big__default.default(smartxData.amount_out || 0);
|
|
361
|
+
const smartxMin = new Big__default.default(smartxData.min_amount_out || 0);
|
|
362
|
+
if (smartxAmountOut.gt(0) && smartxMin.gte(0) && smartxAmountOut.gt(amountOut)) {
|
|
363
|
+
return {
|
|
364
|
+
success: true,
|
|
365
|
+
tokenIn,
|
|
366
|
+
tokenOut,
|
|
367
|
+
amountIn,
|
|
368
|
+
amountOut: String(smartxData.amount_out),
|
|
369
|
+
minAmountOut: String(smartxData.min_amount_out || "0"),
|
|
370
|
+
routes: [],
|
|
371
|
+
quoteSource: "smartx",
|
|
372
|
+
smartxResult: {
|
|
373
|
+
amountIn: String(smartxData.amount_in || amountIn),
|
|
374
|
+
amountOut: String(smartxData.amount_out),
|
|
375
|
+
minAmountOut: String(smartxData.min_amount_out || "0"),
|
|
376
|
+
dexs: smartxData.dexs,
|
|
377
|
+
msg: smartxData.msg,
|
|
378
|
+
signature: smartxData.signature,
|
|
379
|
+
tokens: smartxData.tokens
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return findPathQuote;
|
|
291
385
|
} catch (error) {
|
|
292
386
|
return {
|
|
293
387
|
success: false,
|
|
@@ -307,6 +401,108 @@ var NearSmartRouter = class {
|
|
|
307
401
|
async executeSwap(params) {
|
|
308
402
|
try {
|
|
309
403
|
const { quote, recipient, depositAddress } = params;
|
|
404
|
+
if (quote.quoteSource === "smartx") {
|
|
405
|
+
const smartx = quote.smartxResult;
|
|
406
|
+
const aggDexId = this.aggregateDexContractId;
|
|
407
|
+
if (!smartx || !aggDexId) {
|
|
408
|
+
return {
|
|
409
|
+
success: false,
|
|
410
|
+
error: "SmartX quote missing execution context (smartxResult or aggregateDexContractId)."
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
if (!quote.tokenIn?.address) {
|
|
414
|
+
return { success: false, error: "tokenIn address is required" };
|
|
415
|
+
}
|
|
416
|
+
const transactions2 = [];
|
|
417
|
+
const finalRecipient2 = depositAddress || recipient;
|
|
418
|
+
if (!finalRecipient2) {
|
|
419
|
+
return { success: false, error: "recipient is required for SmartX execution" };
|
|
420
|
+
}
|
|
421
|
+
const tokensToCheck = Array.from(
|
|
422
|
+
new Set(
|
|
423
|
+
[
|
|
424
|
+
...smartx.tokens || [],
|
|
425
|
+
quote.tokenIn.address || "",
|
|
426
|
+
quote.tokenOut?.address || ""
|
|
427
|
+
].filter(Boolean)
|
|
428
|
+
)
|
|
429
|
+
);
|
|
430
|
+
if (tokensToCheck.length === 0) {
|
|
431
|
+
return {
|
|
432
|
+
success: false,
|
|
433
|
+
error: "SmartX tokens list is empty, cannot proceed with execution"
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
const targets = [finalRecipient2, aggDexId];
|
|
437
|
+
for (const token of tokensToCheck) {
|
|
438
|
+
for (const target of targets) {
|
|
439
|
+
if (!token || !target) continue;
|
|
440
|
+
let isRegistered = false;
|
|
441
|
+
try {
|
|
442
|
+
const storageBalance = await this.nearChainAdapter.view({
|
|
443
|
+
contractId: token,
|
|
444
|
+
methodName: "storage_balance_of",
|
|
445
|
+
args: {
|
|
446
|
+
account_id: target
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
isRegistered = !!storageBalance;
|
|
450
|
+
} catch (err) {
|
|
451
|
+
logger.debug(
|
|
452
|
+
`Storage check failed for ${token} -> ${target}, assuming not registered:`,
|
|
453
|
+
err
|
|
454
|
+
);
|
|
455
|
+
isRegistered = false;
|
|
456
|
+
}
|
|
457
|
+
if (!isRegistered) {
|
|
458
|
+
transactions2.push({
|
|
459
|
+
contractId: token,
|
|
460
|
+
methodName: "storage_deposit",
|
|
461
|
+
args: {
|
|
462
|
+
account_id: target,
|
|
463
|
+
registration_only: true
|
|
464
|
+
},
|
|
465
|
+
gas: "50",
|
|
466
|
+
expandDeposit: this.tokenStorageDepositRead
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
const routerMsg = smartx.msg;
|
|
472
|
+
const signature = smartx.signature;
|
|
473
|
+
if (!routerMsg || !signature) {
|
|
474
|
+
return {
|
|
475
|
+
success: false,
|
|
476
|
+
error: "SmartX smartxResult missing msg or signature."
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
const swapMsg2 = {
|
|
480
|
+
msg: routerMsg,
|
|
481
|
+
signature
|
|
482
|
+
};
|
|
483
|
+
transactions2.push({
|
|
484
|
+
contractId: quote.tokenIn.address,
|
|
485
|
+
methodName: "ft_transfer_call",
|
|
486
|
+
args: {
|
|
487
|
+
receiver_id: aggDexId,
|
|
488
|
+
amount: quote.amountIn,
|
|
489
|
+
msg: JSON.stringify(swapMsg2)
|
|
490
|
+
},
|
|
491
|
+
gas: "300000000000000",
|
|
492
|
+
// ~300 Tgas reference
|
|
493
|
+
expandDeposit: "1"
|
|
494
|
+
// 1 yoctoNEAR
|
|
495
|
+
});
|
|
496
|
+
const result2 = await this.nearChainAdapter.call({ transactions: transactions2 });
|
|
497
|
+
if (result2.status === "success") {
|
|
498
|
+
return {
|
|
499
|
+
success: true,
|
|
500
|
+
txHash: result2.txHash,
|
|
501
|
+
txHashArray: result2.txHashArr || (result2.txHash ? [result2.txHash] : [])
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
return { success: false, error: result2.message || "Execute swap failed" };
|
|
505
|
+
}
|
|
310
506
|
if (!quote.success || !quote.routes.length) {
|
|
311
507
|
return {
|
|
312
508
|
success: false,
|