@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 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.ref.finance/findPath?${new URLSearchParams({
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
- logger.debug("SmartRouter quote - Calling findPath:", {
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
- const response = await this.findPathAdapter.findPath({
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: response?.result_code,
249
- result_msg: response?.result_msg || response?.result_message,
250
- hasRoutes: !!response?.result_data?.routes?.length
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 (response?.result_code !== 0 || !response?.result_data?.routes?.length) {
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: response?.result_msg || response?.result_message || "No route found"
327
+ error: findPathResp?.result_msg || findPathResp?.result_message || "No route found"
262
328
  };
263
329
  }
264
- const { routes: serverRoutes, amount_out } = response.result_data;
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
- return {
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,