@rhea-finance/cross-chain-aggregation-dex 0.1.1 → 0.1.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/dist/index.d.mts CHANGED
@@ -396,20 +396,12 @@ declare class AggregateDexRouter implements DexRouter {
396
396
  */
397
397
  quote(params: QuoteParams): Promise<QuoteResult>;
398
398
  /**
399
- * Finalize quote with depositAddress (deprecated)
400
- *
401
- * @deprecated No longer needed. executeSwap automatically fetches final quote using receiveUser (depositAddress).
402
- * Kept for interface compatibility only.
399
+ * @deprecated No longer needed. Kept for interface compatibility only.
403
400
  */
404
401
  finalizeQuote(params: QuoteParams, depositAddress: string): Promise<QuoteResult>;
405
- /**
406
- * Execute swap with V2 Router
407
- * Automatically fetches final quote using receiveUser (depositAddress) to ensure correct routerMsg and signature.
408
- */
402
+ private reFetchQuoteWithBalance;
403
+ private ensureQuoteAmountWithinBalance;
409
404
  executeSwap(params: ExecuteParams): Promise<ExecuteResult>;
410
- /**
411
- * Query user token registration status in AGGREGATE_DEX contract
412
- */
413
405
  private queryUserTokensRegistered;
414
406
  }
415
407
 
package/dist/index.d.ts CHANGED
@@ -396,20 +396,12 @@ declare class AggregateDexRouter implements DexRouter {
396
396
  */
397
397
  quote(params: QuoteParams): Promise<QuoteResult>;
398
398
  /**
399
- * Finalize quote with depositAddress (deprecated)
400
- *
401
- * @deprecated No longer needed. executeSwap automatically fetches final quote using receiveUser (depositAddress).
402
- * Kept for interface compatibility only.
399
+ * @deprecated No longer needed. Kept for interface compatibility only.
403
400
  */
404
401
  finalizeQuote(params: QuoteParams, depositAddress: string): Promise<QuoteResult>;
405
- /**
406
- * Execute swap with V2 Router
407
- * Automatically fetches final quote using receiveUser (depositAddress) to ensure correct routerMsg and signature.
408
- */
402
+ private reFetchQuoteWithBalance;
403
+ private ensureQuoteAmountWithinBalance;
409
404
  executeSwap(params: ExecuteParams): Promise<ExecuteResult>;
410
- /**
411
- * Query user token registration status in AGGREGATE_DEX contract
412
- */
413
405
  private queryUserTokensRegistered;
414
406
  }
415
407
 
package/dist/index.js CHANGED
@@ -625,14 +625,6 @@ var AggregateDexRouter = class {
625
625
  }
626
626
  const slippageBps = convertSlippageToBasisPoints(slippage);
627
627
  const slippageDecimalForApi = slippageBps / 1e4;
628
- logger.debug("AggregateDexRouter quote - Calling swapMultiDexPath:", {
629
- tokenIn: normalizedTokenIn,
630
- tokenOut: normalizedTokenOut,
631
- amountIn,
632
- slippage: slippageDecimalForApi,
633
- sender,
634
- recipient
635
- });
636
628
  const response = await this.swapMultiDexPathAdapter.swapMultiDexPath({
637
629
  amountIn: String(amountIn),
638
630
  tokenIn: normalizedTokenIn,
@@ -642,11 +634,6 @@ var AggregateDexRouter = class {
642
634
  user: sender,
643
635
  receiveUser: recipient
644
636
  });
645
- logger.debug("AggregateDexRouter quote - swapMultiDexPath response:", {
646
- result_code: response?.result_code,
647
- result_message: response?.result_message,
648
- hasData: !!response?.result_data
649
- });
650
637
  if (response.result_code !== 0 || !response.result_data) {
651
638
  return {
652
639
  success: false,
@@ -698,10 +685,7 @@ var AggregateDexRouter = class {
698
685
  }
699
686
  }
700
687
  /**
701
- * Finalize quote with depositAddress (deprecated)
702
- *
703
- * @deprecated No longer needed. executeSwap automatically fetches final quote using receiveUser (depositAddress).
704
- * Kept for interface compatibility only.
688
+ * @deprecated No longer needed. Kept for interface compatibility only.
705
689
  */
706
690
  async finalizeQuote(params, depositAddress) {
707
691
  if (!requiresRecipient(params)) {
@@ -712,10 +696,70 @@ var AggregateDexRouter = class {
712
696
  recipient: depositAddress
713
697
  });
714
698
  }
715
- /**
716
- * Execute swap with V2 Router
717
- * Automatically fetches final quote using receiveUser (depositAddress) to ensure correct routerMsg and signature.
718
- */
699
+ async reFetchQuoteWithBalance(quoteParams, actualBalance, context) {
700
+ const balanceBig = new Big2__default.default(actualBalance);
701
+ const adjustedParams = {
702
+ ...quoteParams,
703
+ amountIn: balanceBig.toFixed(0)
704
+ };
705
+ logger.warn(`AggregateDexRouter - ${context}: re-fetching quote with actual balance:`, {
706
+ requestedAmount: quoteParams.amountIn,
707
+ actualBalance
708
+ });
709
+ const adjustedQuote = await this.quote(adjustedParams);
710
+ if (adjustedQuote.success && adjustedQuote.routerMsg && adjustedQuote.signature) {
711
+ return adjustedQuote;
712
+ } else {
713
+ throw new Error(`Failed to re-fetch quote with actual balance: ${adjustedQuote.error || "Unknown error"}`);
714
+ }
715
+ }
716
+ async ensureQuoteAmountWithinBalance(quoteParams, actualBalance, context) {
717
+ const requestedAmountBig = new Big2__default.default(quoteParams.amountIn);
718
+ const balanceBig = new Big2__default.default(actualBalance);
719
+ const isNativeNear = (quoteParams.tokenIn.symbol === "NEAR" || quoteParams.tokenIn.address === "near" || !quoteParams.tokenIn.address && quoteParams.tokenIn.symbol === "NEAR") && quoteParams.tokenIn.address !== this.wrapNearContractId;
720
+ let effectiveBalanceBig = balanceBig;
721
+ let effectiveBalanceStr = actualBalance;
722
+ if (isNativeNear) {
723
+ const reserveAmount = new Big2__default.default("50000000000000000000000");
724
+ if (balanceBig.gt(reserveAmount)) {
725
+ effectiveBalanceBig = balanceBig.minus(reserveAmount);
726
+ effectiveBalanceStr = effectiveBalanceBig.toFixed(0);
727
+ } else {
728
+ effectiveBalanceBig = new Big2__default.default(0);
729
+ effectiveBalanceStr = "0";
730
+ }
731
+ }
732
+ if (requestedAmountBig.gt(effectiveBalanceBig) && balanceBig.gt(0)) {
733
+ return await this.reFetchQuoteWithBalance(quoteParams, effectiveBalanceStr, `${context} (requested amount exceeds available balance${isNativeNear ? " minus gas reserve" : ""})`);
734
+ }
735
+ if (balanceBig.gt(0) && requestedAmountBig.lt(balanceBig)) {
736
+ const diff = balanceBig.minus(requestedAmountBig);
737
+ const diffPercent = diff.div(balanceBig).times(100);
738
+ const isMaxSwap = diffPercent.lt(0.1) || diff.lt(1e3);
739
+ if (isMaxSwap) {
740
+ return await this.reFetchQuoteWithBalance(quoteParams, effectiveBalanceStr, `${context} (MAX swap detected, using ${isNativeNear ? "balance minus gas reserve" : "actual balance"})`);
741
+ }
742
+ }
743
+ const quote = await this.quote(quoteParams);
744
+ if (!quote.success) {
745
+ throw new Error(`Failed to fetch quote: ${quote.error || "Unknown error"}`);
746
+ }
747
+ if (quote.amountIn !== quoteParams.amountIn) {
748
+ const apiAmountBig = new Big2__default.default(quote.amountIn);
749
+ if (apiAmountBig.gt(effectiveBalanceBig) && balanceBig.gt(0)) {
750
+ return await this.reFetchQuoteWithBalance(quoteParams, effectiveBalanceStr, `${context} (API returned amount_in exceeds available balance)`);
751
+ }
752
+ if (apiAmountBig.lt(balanceBig) && balanceBig.gt(0)) {
753
+ const diff = balanceBig.minus(apiAmountBig);
754
+ const diffPercent = diff.div(balanceBig).times(100);
755
+ const isMaxSwap = diffPercent.lt(0.1) || diff.lt(1e3);
756
+ if (isMaxSwap) {
757
+ return await this.reFetchQuoteWithBalance(quoteParams, effectiveBalanceStr, `${context} (API returned amount_in close to balance, MAX swap detected)`);
758
+ }
759
+ }
760
+ }
761
+ return quote;
762
+ }
719
763
  async executeSwap(params) {
720
764
  try {
721
765
  if (!requiresRecipientInExecute(params)) {
@@ -743,16 +787,17 @@ var AggregateDexRouter = class {
743
787
  error: `receiveUser appears to be an EVM address (${receiveUser}). For NEAR chain swaps, depositAddress must be a NEAR account (64 hex chars or .near format)`
744
788
  };
745
789
  }
746
- logger.debug("AggregateDexRouter - executeSwap params:", {
747
- sender,
748
- receiveUser,
749
- tokenIn: quote.tokenIn.address,
750
- tokenOut: quote.tokenOut.address,
751
- amountIn: quote.amountIn,
752
- tokens: quote.tokens,
753
- dexs: quote.dexs
754
- });
755
790
  const slippage = quote.slippage || 5e-3;
791
+ let tokenBalanceAtExecution = "0";
792
+ try {
793
+ const balanceResult = await this.nearChainAdapter.view({
794
+ contractId: quote.tokenIn.address,
795
+ methodName: "ft_balance_of",
796
+ args: { account_id: sender }
797
+ });
798
+ tokenBalanceAtExecution = balanceResult || "0";
799
+ } catch (e) {
800
+ }
756
801
  const finalQuoteParams = {
757
802
  tokenIn: quote.tokenIn,
758
803
  tokenOut: quote.tokenOut,
@@ -763,13 +808,11 @@ var AggregateDexRouter = class {
763
808
  };
764
809
  let finalQuote;
765
810
  try {
766
- finalQuote = await this.quote(finalQuoteParams);
767
- if (!finalQuote.success) {
768
- return {
769
- success: false,
770
- error: `Failed to fetch quote with receiveUser="${receiveUser}": ${finalQuote.error}`
771
- };
772
- }
811
+ finalQuote = await this.ensureQuoteAmountWithinBalance(
812
+ finalQuoteParams,
813
+ tokenBalanceAtExecution,
814
+ "Re-fetching quote with receiveUser"
815
+ );
773
816
  } catch (error) {
774
817
  logger.error("AggregateDexRouter - Failed to fetch quote with receiveUser:", error);
775
818
  return {
@@ -785,12 +828,6 @@ var AggregateDexRouter = class {
785
828
  error: `Quote fetched with receiveUser="${receiveUser}" is missing routerMsg or signature.`
786
829
  };
787
830
  }
788
- logger.debug("AggregateDexRouter - Successfully fetched final quote:", {
789
- receiveUser,
790
- quoteRecipient: finalQuote.recipient,
791
- routerMsgLength: routerMsg.length,
792
- signatureLength: signature.length
793
- });
794
831
  const tokens = finalQuote.tokens || [];
795
832
  const dexs = finalQuote.dexs || [];
796
833
  const transactions = [];
@@ -805,7 +842,7 @@ var AggregateDexRouter = class {
805
842
  return null;
806
843
  }
807
844
  };
808
- const isNativeNear = finalQuote.tokenIn.symbol === "NEAR" || finalQuote.tokenIn.address === "near" || !finalQuote.tokenIn.address && finalQuote.tokenIn.symbol === "NEAR";
845
+ const isNativeNear = (finalQuote.tokenIn.symbol === "NEAR" || finalQuote.tokenIn.address === "near" || !finalQuote.tokenIn.address && finalQuote.tokenIn.symbol === "NEAR") && finalQuote.tokenIn.address !== this.wrapNearContractId;
809
846
  if (isNativeNear) {
810
847
  const wrapNearStorageBalance = await getStorageBalance(
811
848
  this.wrapNearContractId,
@@ -852,11 +889,6 @@ var AggregateDexRouter = class {
852
889
  }
853
890
  });
854
891
  if (receiveUser && receiveUser !== sender) {
855
- logger.debug("AggregateDexRouter - Checking receiveUser registration in tokenOut:", {
856
- receiveUser,
857
- tokenOut: finalQuote.tokenOut.address,
858
- tokenOutSymbol: finalQuote.tokenOut.symbol
859
- });
860
892
  const receiveUserStorageBalance = await getStorageBalance(
861
893
  finalQuote.tokenOut.address,
862
894
  receiveUser
@@ -869,12 +901,6 @@ var AggregateDexRouter = class {
869
901
  return null;
870
902
  });
871
903
  if (!receiveUserStorageBalance) {
872
- logger.debug("AggregateDexRouter - receiveUser not registered in tokenOut, adding registration transaction:", {
873
- receiveUser,
874
- tokenOut: finalQuote.tokenOut.address,
875
- tokenOutSymbol: finalQuote.tokenOut.symbol,
876
- storageCost: this.NEW_ACCOUNT_STORAGE_COST
877
- });
878
904
  transactions.push({
879
905
  contractId: finalQuote.tokenOut.address,
880
906
  methodName: "storage_deposit",
@@ -920,7 +946,7 @@ var AggregateDexRouter = class {
920
946
  const depositPerToken = new Big2__default.default("0.005").mul(
921
947
  new Big2__default.default("1000000000000000000000000")
922
948
  );
923
- const totalDeposit2 = depositPerToken.mul(unregisteredTokens.length);
949
+ const totalDeposit = depositPerToken.mul(unregisteredTokens.length);
924
950
  transactions.push({
925
951
  contractId: this.aggregateDexContractId,
926
952
  methodName: "tokens_storage_deposit",
@@ -929,50 +955,57 @@ var AggregateDexRouter = class {
929
955
  tokens: unregisteredTokens
930
956
  },
931
957
  gas: "30000000000000",
932
- expandDeposit: totalDeposit2.toFixed(0)
958
+ expandDeposit: totalDeposit.toFixed(0)
933
959
  });
934
960
  }
935
961
  }
936
- const msgString = JSON.stringify({
937
- msg: routerMsg,
938
- signature
962
+ try {
963
+ const balanceResult = await this.nearChainAdapter.view({
964
+ contractId: finalQuote.tokenIn.address,
965
+ methodName: "ft_balance_of",
966
+ args: { account_id: sender }
967
+ });
968
+ tokenBalanceAtExecution = balanceResult || "0";
969
+ } catch (e) {
970
+ }
971
+ const finalBalanceQuoteParams = {
972
+ tokenIn: finalQuote.tokenIn,
973
+ tokenOut: finalQuote.tokenOut,
974
+ amountIn: finalQuote.amountIn,
975
+ slippage,
976
+ sender,
977
+ recipient: receiveUser
978
+ };
979
+ let finalQuoteForExecution;
980
+ try {
981
+ finalQuoteForExecution = await this.ensureQuoteAmountWithinBalance(
982
+ finalBalanceQuoteParams,
983
+ tokenBalanceAtExecution,
984
+ "Final balance check before execution"
985
+ );
986
+ } catch (error) {
987
+ logger.error("AggregateDexRouter - Failed final balance check:", error);
988
+ return {
989
+ success: false,
990
+ error: `Failed final balance check: ${error?.message || "Unknown error"}`
991
+ };
992
+ }
993
+ const finalAmountToTransfer = finalQuoteForExecution.amountIn;
994
+ const finalMsgString = JSON.stringify({
995
+ msg: finalQuoteForExecution.routerMsg,
996
+ signature: finalQuoteForExecution.signature
939
997
  });
940
998
  transactions.push({
941
999
  contractId: finalQuote.tokenIn.address,
942
1000
  methodName: "ft_transfer_call",
943
1001
  args: {
944
1002
  receiver_id: this.aggregateDexContractId,
945
- amount: finalQuote.amountIn,
946
- msg: msgString
1003
+ amount: finalAmountToTransfer,
1004
+ msg: finalMsgString
947
1005
  },
948
1006
  gas: "300000000000000",
949
1007
  expandDeposit: this.ONE_YOCTO_NEAR
950
1008
  });
951
- const totalDeposit = transactions.reduce((sum, tx) => {
952
- if (tx.expandDeposit) {
953
- return sum.plus(tx.expandDeposit);
954
- }
955
- return sum;
956
- }, new Big2__default.default(0));
957
- logger.debug("AggregateDexRouter - Executing swap (following mature codebase logic):", {
958
- contractId: finalQuote.tokenIn.address,
959
- receiver_id: this.aggregateDexContractId,
960
- amount: finalQuote.amountIn,
961
- transactionsCount: transactions.length,
962
- sender,
963
- receiveUser,
964
- tokens: tokens.length,
965
- dexs: dexs.length,
966
- totalDepositYocto: totalDeposit.toFixed(0),
967
- totalDepositNEAR: totalDeposit.div(new Big2__default.default("1000000000000000000000000")).toFixed(6),
968
- transactions: transactions.map((tx, idx) => ({
969
- index: idx,
970
- contractId: tx.contractId,
971
- methodName: tx.methodName,
972
- expandDeposit: tx.expandDeposit,
973
- expandDepositNEAR: tx.expandDeposit ? new Big2__default.default(tx.expandDeposit).div(new Big2__default.default("1000000000000000000000000")).toFixed(6) : "0"
974
- }))
975
- });
976
1009
  const result = await this.nearChainAdapter.call({
977
1010
  transactions
978
1011
  });
@@ -996,9 +1029,6 @@ var AggregateDexRouter = class {
996
1029
  };
997
1030
  }
998
1031
  }
999
- /**
1000
- * Query user token registration status in AGGREGATE_DEX contract
1001
- */
1002
1032
  async queryUserTokensRegistered({
1003
1033
  user,
1004
1034
  tokens