@imtbl/sdk 0.27.8 → 0.27.9

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.cjs CHANGED
@@ -3631,7 +3631,7 @@ class MultiRollupApiClients {
3631
3631
  }
3632
3632
 
3633
3633
  // eslint-disable-next-line @typescript-eslint/naming-convention
3634
- const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.8' };
3634
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.9' };
3635
3635
  const createConfig = ({ basePath, headers, }) => {
3636
3636
  if (!basePath.trim()) {
3637
3637
  throw Error('basePath can not be empty');
@@ -3691,7 +3691,7 @@ class APIError extends Error {
3691
3691
 
3692
3692
  /* eslint-disable implicit-arrow-linebreak */
3693
3693
  const defaultHeaders = {
3694
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.8',
3694
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.9',
3695
3695
  };
3696
3696
  /**
3697
3697
  * createAPIConfiguration to create a custom Configuration
@@ -4102,7 +4102,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
4102
4102
  chainID,
4103
4103
  coreContractAddress,
4104
4104
  registrationContractAddress,
4105
- sdkVersion: 'ts-immutable-sdk-0.27.8',
4105
+ sdkVersion: 'ts-immutable-sdk-0.27.9',
4106
4106
  });
4107
4107
  /**
4108
4108
  * Sets `sdkVersion` at the time of build
@@ -28054,18 +28054,45 @@ const newAmount = (amount, token) => ({
28054
28054
  token,
28055
28055
  });
28056
28056
  const isERC20Amount = (amount) => amount.token.type === 'erc20';
28057
+ const isNativeAmount = (amount) => amount.token.type === 'native';
28057
28058
  const addERC20Amount = (a, b) => {
28058
28059
  // Make sure the ERC20s have the same address
28059
28060
  if (a.token.address !== b.token.address)
28060
28061
  throw new Error('Token mismatch: token addresses must be the same');
28061
28062
  return { value: a.value.add(b.value), token: a.token };
28062
28063
  };
28064
+ const addNativeAmount = (a, b) => ({
28065
+ value: a.value.add(b.value),
28066
+ token: a.token,
28067
+ });
28068
+ const addAmount = (a, b) => {
28069
+ if (isERC20Amount(a) && isERC20Amount(b)) {
28070
+ return addERC20Amount(a, b);
28071
+ }
28072
+ if (isNativeAmount(a) && isNativeAmount(b)) {
28073
+ return addNativeAmount(a, b);
28074
+ }
28075
+ throw new Error('Token mismatch: token types must be the same');
28076
+ };
28063
28077
  const subtractERC20Amount = (a, b) => {
28064
28078
  // Make sure the ERC20s have the same address
28065
28079
  if (a.token.address !== b.token.address)
28066
28080
  throw new Error('Token mismatch: token addresses must be the same');
28067
28081
  return { value: a.value.sub(b.value), token: a.token };
28068
28082
  };
28083
+ const subtractNativeAmount = (a, b) => ({
28084
+ value: a.value.sub(b.value),
28085
+ token: a.token,
28086
+ });
28087
+ const subtractAmount = (a, b) => {
28088
+ if (isERC20Amount(a) && isERC20Amount(b)) {
28089
+ return subtractERC20Amount(a, b);
28090
+ }
28091
+ if (isNativeAmount(a) && isNativeAmount(b)) {
28092
+ return subtractNativeAmount(a, b);
28093
+ }
28094
+ throw new Error('Token mismatch: token types must be the same');
28095
+ };
28069
28096
 
28070
28097
  const amountIndex = 0;
28071
28098
  const gasEstimateIndex = 3;
@@ -28439,11 +28466,11 @@ const getUnsignedERC20ApproveTransaction = (ownerAddress, tokenAmount, spenderAd
28439
28466
  from: ownerAddress,
28440
28467
  };
28441
28468
  };
28442
- const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, routingContracts, secondaryFees) => {
28469
+ const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, contracts, secondaryFees) => {
28443
28470
  const amountOfTokenIn = tradeType === sdkCore.TradeType.EXACT_INPUT ? amountSpecified : amountWithSlippage;
28444
28471
  const spender = secondaryFees.length === 0
28445
- ? routingContracts.peripheryRouterAddress
28446
- : routingContracts.secondaryFeeAddress;
28472
+ ? contracts.routerAddress
28473
+ : contracts.secondaryFeeAddress;
28447
28474
  return { spender, amount: amountOfTokenIn };
28448
28475
  };
28449
28476
  /**
@@ -28522,7 +28549,7 @@ function applySlippage(tradeType, amount, slippage) {
28522
28549
  const amountWithSlippage = maybeInverted.multiply(amount.toString()).quotient;
28523
28550
  return ethers.ethers.BigNumber.from(amountWithSlippage.toString());
28524
28551
  }
28525
- function prepareUserQuote(otherToken, tradeInfo, slippage, fees) {
28552
+ function prepareUserQuote(otherToken, tradeInfo, slippage, fees, nativeTokenService) {
28526
28553
  const quote = getQuoteAmountFromTradeType(tradeInfo);
28527
28554
  const amountWithSlippage = applySlippage(tradeInfo.tradeType, quote.value, slippage);
28528
28555
  return {
@@ -28532,15 +28559,14 @@ function prepareUserQuote(otherToken, tradeInfo, slippage, fees) {
28532
28559
  value: amountWithSlippage,
28533
28560
  },
28534
28561
  slippage,
28535
- fees: fees.withAmounts(),
28562
+ fees: fees.withAmounts().map((fee) => ({
28563
+ ...fee,
28564
+ amount: nativeTokenService.maybeWrapAmount(fee.amount),
28565
+ })),
28536
28566
  };
28537
28567
  }
28538
28568
  function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
28539
28569
  fees, tradeType, nativeTokenService) {
28540
- // TODO: TP-1649: Remove this when we support Native
28541
- if (!isERC20Amount(amountSpecified)) {
28542
- throw new Error('Not implemented yet!');
28543
- }
28544
28570
  if (tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
28545
28571
  // For an exact output swap, we do not need to subtract fees from the given amount
28546
28572
  return nativeTokenService.maybeWrapAmount(amountSpecified);
@@ -28571,14 +28597,17 @@ class Fees {
28571
28597
  this.secondaryFees = secondaryFees;
28572
28598
  this.amount = newAmount(ethers.BigNumber.from(0), token);
28573
28599
  }
28600
+ get token() {
28601
+ return this.amount.token;
28602
+ }
28574
28603
  addAmount(amount) {
28575
- this.amount = addERC20Amount(this.amount, amount);
28604
+ this.amount = addAmount(this.amount, amount);
28576
28605
  }
28577
28606
  amountWithFeesApplied() {
28578
- return addERC20Amount(this.amount, this.total());
28607
+ return addAmount(this.amount, this.total());
28579
28608
  }
28580
28609
  amountLessFees() {
28581
- return subtractERC20Amount(this.amount, this.total());
28610
+ return subtractAmount(this.amount, this.total());
28582
28611
  }
28583
28612
  withAmounts() {
28584
28613
  return this.secondaryFees.map((fee) => {
@@ -28597,7 +28626,7 @@ class Fees {
28597
28626
  const feeAmount = this.amount.value
28598
28627
  .mul(fee.basisPoints)
28599
28628
  .div(BASIS_POINT_PRECISION);
28600
- totalFees = addERC20Amount(totalFees, newAmount(feeAmount, this.amount.token));
28629
+ totalFees = addAmount(totalFees, newAmount(feeAmount, this.amount.token));
28601
28630
  }
28602
28631
  return totalFees;
28603
28632
  }
@@ -28773,21 +28802,33 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
28773
28802
  gasFeeEstimate: gasFeeEstimate ? nativeTokenService.maybeWrapAmount(gasFeeEstimate) : null,
28774
28803
  };
28775
28804
  }
28776
- function prepareSwap(ourQuote, amountSpecified, fees) {
28805
+ const adjustAmountIn = (ourQuote, amountSpecified, fees, nativeTokenService) => {
28777
28806
  if (ourQuote.tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
28778
- fees.addAmount(ourQuote.amountIn);
28779
- return {
28780
- gasEstimate: ourQuote.gasEstimate,
28781
- route: ourQuote.route,
28782
- amountIn: fees.amountWithFeesApplied(),
28783
- amountOut: amountSpecified,
28784
- tradeType: ourQuote.tradeType,
28785
- };
28807
+ // when doing exact output, calculate the fees based on the amountIn
28808
+ const amountToAdd = nativeTokenService.isNativeToken(fees.token)
28809
+ ? nativeTokenService.unwrapAmount(ourQuote.amountIn)
28810
+ : ourQuote.amountIn;
28811
+ fees.addAmount(amountToAdd);
28812
+ return nativeTokenService.maybeWrapAmount(fees.amountWithFeesApplied());
28786
28813
  }
28814
+ return nativeTokenService.maybeWrapAmount(amountSpecified);
28815
+ };
28816
+ /**
28817
+ * adjustQuoteWithFees adjusts the amountIn of the quote to account for fees
28818
+ * EXACT_OUTPUT swaps will have the fees added to the amountIn if there are fees specified
28819
+ * EXACT_INPUT swaps will have amountIn set to the user-specified amount
28820
+ * @param ourQuote The quote from calling the Quoter contract
28821
+ * @param amountSpecified The user-specified amount for the swap (EXACT...)
28822
+ * @param fees The fees applied to the swap
28823
+ * @param tokenWrapper Helper class for the native token and associated ERC20
28824
+ * @returns {QuoteResult} The adjusted quote
28825
+ */
28826
+ function adjustQuoteWithFees(ourQuote, amountSpecified, fees, nativeTokenService) {
28827
+ const adjustedAmountIn = adjustAmountIn(ourQuote, amountSpecified, fees, nativeTokenService);
28787
28828
  return {
28788
28829
  gasEstimate: ourQuote.gasEstimate,
28789
28830
  route: ourQuote.route,
28790
- amountIn: amountSpecified,
28831
+ amountIn: adjustedAmountIn,
28791
28832
  amountOut: ourQuote.amountOut,
28792
28833
  tradeType: ourQuote.tradeType,
28793
28834
  };
@@ -28888,6 +28929,8 @@ class Exchange {
28888
28929
  wrappedNativeToken;
28889
28930
  secondaryFees;
28890
28931
  nativeTokenService;
28932
+ secondaryFeeContractAddress;
28933
+ routerContractAddress;
28891
28934
  constructor(configuration) {
28892
28935
  const config = new ExchangeConfiguration(configuration);
28893
28936
  this.chainId = config.chain.chainId;
@@ -28895,13 +28938,13 @@ class Exchange {
28895
28938
  this.wrappedNativeToken = config.chain.wrappedNativeToken;
28896
28939
  this.nativeTokenService = new NativeTokenService(this.nativeToken, this.wrappedNativeToken);
28897
28940
  this.secondaryFees = config.secondaryFees;
28941
+ this.routerContractAddress = config.chain.contracts.peripheryRouter;
28942
+ this.secondaryFeeContractAddress = config.chain.contracts.secondaryFee;
28898
28943
  this.provider = new ethers.ethers.providers.JsonRpcProvider(config.chain.rpcUrl);
28899
28944
  this.router = new Router(this.provider, config.chain.commonRoutingTokens, {
28900
28945
  multicallAddress: config.chain.contracts.multicall,
28901
28946
  factoryAddress: config.chain.contracts.coreFactory,
28902
28947
  quoterAddress: config.chain.contracts.quoterV2,
28903
- peripheryRouterAddress: config.chain.contracts.peripheryRouter,
28904
- secondaryFeeAddress: config.chain.contracts.secondaryFee,
28905
28948
  });
28906
28949
  }
28907
28950
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
@@ -28918,7 +28961,7 @@ class Exchange {
28918
28961
  if (this.secondaryFees.length === 0) {
28919
28962
  return [];
28920
28963
  }
28921
- const secondaryFeeContract = SecondaryFee__factory.connect(this.router.routingContracts.secondaryFeeAddress, this.provider);
28964
+ const secondaryFeeContract = SecondaryFee__factory.connect(this.secondaryFeeContractAddress, this.provider);
28922
28965
  if (await secondaryFeeContract.paused()) {
28923
28966
  // Do not use secondary fees if the contract is paused
28924
28967
  return [];
@@ -28946,8 +28989,7 @@ class Exchange {
28946
28989
  decimals: tokenOutDecimals,
28947
28990
  };
28948
28991
  // determine which amount was specified for the swap from the TradeType
28949
- const [tokenSpecified, otherToken] = tradeType === sdkCore.TradeType.EXACT_INPUT
28950
- ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
28992
+ const [tokenSpecified, otherToken] = tradeType === sdkCore.TradeType.EXACT_INPUT ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
28951
28993
  const amountSpecified = newAmount(amount, tokenSpecified);
28952
28994
  const fees = new Fees(secondaryFees, tokenIn);
28953
28995
  const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
@@ -28956,10 +28998,13 @@ class Exchange {
28956
28998
  this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
28957
28999
  fetchGasPrice(this.provider, this.nativeToken),
28958
29000
  ]);
28959
- const adjustedQuote = prepareSwap(ourQuote, amountSpecified, fees);
28960
- const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.router.routingContracts.peripheryRouterAddress, this.router.routingContracts.secondaryFeeAddress, gasPrice, secondaryFees, this.nativeTokenService);
28961
- const userQuote = prepareUserQuote(otherToken, adjustedQuote, slippagePercent, fees);
28962
- const preparedApproval = prepareApproval(tradeType, amountSpecified, userQuote.amountWithMaxSlippage, this.router.routingContracts, secondaryFees);
29001
+ const adjustedQuote = adjustQuoteWithFees(ourQuote, amountSpecified, fees, this.nativeTokenService);
29002
+ const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.routerContractAddress, this.secondaryFeeContractAddress, gasPrice, secondaryFees, this.nativeTokenService);
29003
+ const userQuote = prepareUserQuote(otherToken, adjustedQuote, slippagePercent, fees, this.nativeTokenService);
29004
+ const preparedApproval = prepareApproval(tradeType, amountSpecified, userQuote.amountWithMaxSlippage, {
29005
+ routerAddress: this.routerContractAddress,
29006
+ secondaryFeeAddress: this.secondaryFeeContractAddress,
29007
+ }, secondaryFees);
28963
29008
  // preparedApproval always uses the tokenIn address because we are always selling the tokenIn
28964
29009
  const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice, this.nativeTokenService);
28965
29010
  return {
@@ -33158,7 +33203,7 @@ var $045213b18e9f1f94$export$75be0f6af9650f2c;
33158
33203
  })($045213b18e9f1f94$export$75be0f6af9650f2c || ($045213b18e9f1f94$export$75be0f6af9650f2c = {}));
33159
33204
 
33160
33205
 
33161
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.8";
33206
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.9";
33162
33207
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
33163
33208
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
33164
33209
 
package/dist/index.js CHANGED
@@ -3609,7 +3609,7 @@ class MultiRollupApiClients {
3609
3609
  }
3610
3610
 
3611
3611
  // eslint-disable-next-line @typescript-eslint/naming-convention
3612
- const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.8' };
3612
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.9' };
3613
3613
  const createConfig = ({ basePath, headers, }) => {
3614
3614
  if (!basePath.trim()) {
3615
3615
  throw Error('basePath can not be empty');
@@ -3669,7 +3669,7 @@ class APIError extends Error {
3669
3669
 
3670
3670
  /* eslint-disable implicit-arrow-linebreak */
3671
3671
  const defaultHeaders = {
3672
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.8',
3672
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.9',
3673
3673
  };
3674
3674
  /**
3675
3675
  * createAPIConfiguration to create a custom Configuration
@@ -4080,7 +4080,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
4080
4080
  chainID,
4081
4081
  coreContractAddress,
4082
4082
  registrationContractAddress,
4083
- sdkVersion: 'ts-immutable-sdk-0.27.8',
4083
+ sdkVersion: 'ts-immutable-sdk-0.27.9',
4084
4084
  });
4085
4085
  /**
4086
4086
  * Sets `sdkVersion` at the time of build
@@ -28032,18 +28032,45 @@ const newAmount = (amount, token) => ({
28032
28032
  token,
28033
28033
  });
28034
28034
  const isERC20Amount = (amount) => amount.token.type === 'erc20';
28035
+ const isNativeAmount = (amount) => amount.token.type === 'native';
28035
28036
  const addERC20Amount = (a, b) => {
28036
28037
  // Make sure the ERC20s have the same address
28037
28038
  if (a.token.address !== b.token.address)
28038
28039
  throw new Error('Token mismatch: token addresses must be the same');
28039
28040
  return { value: a.value.add(b.value), token: a.token };
28040
28041
  };
28042
+ const addNativeAmount = (a, b) => ({
28043
+ value: a.value.add(b.value),
28044
+ token: a.token,
28045
+ });
28046
+ const addAmount = (a, b) => {
28047
+ if (isERC20Amount(a) && isERC20Amount(b)) {
28048
+ return addERC20Amount(a, b);
28049
+ }
28050
+ if (isNativeAmount(a) && isNativeAmount(b)) {
28051
+ return addNativeAmount(a, b);
28052
+ }
28053
+ throw new Error('Token mismatch: token types must be the same');
28054
+ };
28041
28055
  const subtractERC20Amount = (a, b) => {
28042
28056
  // Make sure the ERC20s have the same address
28043
28057
  if (a.token.address !== b.token.address)
28044
28058
  throw new Error('Token mismatch: token addresses must be the same');
28045
28059
  return { value: a.value.sub(b.value), token: a.token };
28046
28060
  };
28061
+ const subtractNativeAmount = (a, b) => ({
28062
+ value: a.value.sub(b.value),
28063
+ token: a.token,
28064
+ });
28065
+ const subtractAmount = (a, b) => {
28066
+ if (isERC20Amount(a) && isERC20Amount(b)) {
28067
+ return subtractERC20Amount(a, b);
28068
+ }
28069
+ if (isNativeAmount(a) && isNativeAmount(b)) {
28070
+ return subtractNativeAmount(a, b);
28071
+ }
28072
+ throw new Error('Token mismatch: token types must be the same');
28073
+ };
28047
28074
 
28048
28075
  const amountIndex = 0;
28049
28076
  const gasEstimateIndex = 3;
@@ -28417,11 +28444,11 @@ const getUnsignedERC20ApproveTransaction = (ownerAddress, tokenAmount, spenderAd
28417
28444
  from: ownerAddress,
28418
28445
  };
28419
28446
  };
28420
- const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, routingContracts, secondaryFees) => {
28447
+ const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, contracts, secondaryFees) => {
28421
28448
  const amountOfTokenIn = tradeType === TradeType.EXACT_INPUT ? amountSpecified : amountWithSlippage;
28422
28449
  const spender = secondaryFees.length === 0
28423
- ? routingContracts.peripheryRouterAddress
28424
- : routingContracts.secondaryFeeAddress;
28450
+ ? contracts.routerAddress
28451
+ : contracts.secondaryFeeAddress;
28425
28452
  return { spender, amount: amountOfTokenIn };
28426
28453
  };
28427
28454
  /**
@@ -28500,7 +28527,7 @@ function applySlippage(tradeType, amount, slippage) {
28500
28527
  const amountWithSlippage = maybeInverted.multiply(amount.toString()).quotient;
28501
28528
  return ethers.BigNumber.from(amountWithSlippage.toString());
28502
28529
  }
28503
- function prepareUserQuote(otherToken, tradeInfo, slippage, fees) {
28530
+ function prepareUserQuote(otherToken, tradeInfo, slippage, fees, nativeTokenService) {
28504
28531
  const quote = getQuoteAmountFromTradeType(tradeInfo);
28505
28532
  const amountWithSlippage = applySlippage(tradeInfo.tradeType, quote.value, slippage);
28506
28533
  return {
@@ -28510,15 +28537,14 @@ function prepareUserQuote(otherToken, tradeInfo, slippage, fees) {
28510
28537
  value: amountWithSlippage,
28511
28538
  },
28512
28539
  slippage,
28513
- fees: fees.withAmounts(),
28540
+ fees: fees.withAmounts().map((fee) => ({
28541
+ ...fee,
28542
+ amount: nativeTokenService.maybeWrapAmount(fee.amount),
28543
+ })),
28514
28544
  };
28515
28545
  }
28516
28546
  function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
28517
28547
  fees, tradeType, nativeTokenService) {
28518
- // TODO: TP-1649: Remove this when we support Native
28519
- if (!isERC20Amount(amountSpecified)) {
28520
- throw new Error('Not implemented yet!');
28521
- }
28522
28548
  if (tradeType === TradeType.EXACT_OUTPUT) {
28523
28549
  // For an exact output swap, we do not need to subtract fees from the given amount
28524
28550
  return nativeTokenService.maybeWrapAmount(amountSpecified);
@@ -28549,14 +28575,17 @@ class Fees {
28549
28575
  this.secondaryFees = secondaryFees;
28550
28576
  this.amount = newAmount(BigNumber$1.from(0), token);
28551
28577
  }
28578
+ get token() {
28579
+ return this.amount.token;
28580
+ }
28552
28581
  addAmount(amount) {
28553
- this.amount = addERC20Amount(this.amount, amount);
28582
+ this.amount = addAmount(this.amount, amount);
28554
28583
  }
28555
28584
  amountWithFeesApplied() {
28556
- return addERC20Amount(this.amount, this.total());
28585
+ return addAmount(this.amount, this.total());
28557
28586
  }
28558
28587
  amountLessFees() {
28559
- return subtractERC20Amount(this.amount, this.total());
28588
+ return subtractAmount(this.amount, this.total());
28560
28589
  }
28561
28590
  withAmounts() {
28562
28591
  return this.secondaryFees.map((fee) => {
@@ -28575,7 +28604,7 @@ class Fees {
28575
28604
  const feeAmount = this.amount.value
28576
28605
  .mul(fee.basisPoints)
28577
28606
  .div(BASIS_POINT_PRECISION);
28578
- totalFees = addERC20Amount(totalFees, newAmount(feeAmount, this.amount.token));
28607
+ totalFees = addAmount(totalFees, newAmount(feeAmount, this.amount.token));
28579
28608
  }
28580
28609
  return totalFees;
28581
28610
  }
@@ -28751,21 +28780,33 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
28751
28780
  gasFeeEstimate: gasFeeEstimate ? nativeTokenService.maybeWrapAmount(gasFeeEstimate) : null,
28752
28781
  };
28753
28782
  }
28754
- function prepareSwap(ourQuote, amountSpecified, fees) {
28783
+ const adjustAmountIn = (ourQuote, amountSpecified, fees, nativeTokenService) => {
28755
28784
  if (ourQuote.tradeType === TradeType.EXACT_OUTPUT) {
28756
- fees.addAmount(ourQuote.amountIn);
28757
- return {
28758
- gasEstimate: ourQuote.gasEstimate,
28759
- route: ourQuote.route,
28760
- amountIn: fees.amountWithFeesApplied(),
28761
- amountOut: amountSpecified,
28762
- tradeType: ourQuote.tradeType,
28763
- };
28785
+ // when doing exact output, calculate the fees based on the amountIn
28786
+ const amountToAdd = nativeTokenService.isNativeToken(fees.token)
28787
+ ? nativeTokenService.unwrapAmount(ourQuote.amountIn)
28788
+ : ourQuote.amountIn;
28789
+ fees.addAmount(amountToAdd);
28790
+ return nativeTokenService.maybeWrapAmount(fees.amountWithFeesApplied());
28764
28791
  }
28792
+ return nativeTokenService.maybeWrapAmount(amountSpecified);
28793
+ };
28794
+ /**
28795
+ * adjustQuoteWithFees adjusts the amountIn of the quote to account for fees
28796
+ * EXACT_OUTPUT swaps will have the fees added to the amountIn if there are fees specified
28797
+ * EXACT_INPUT swaps will have amountIn set to the user-specified amount
28798
+ * @param ourQuote The quote from calling the Quoter contract
28799
+ * @param amountSpecified The user-specified amount for the swap (EXACT...)
28800
+ * @param fees The fees applied to the swap
28801
+ * @param tokenWrapper Helper class for the native token and associated ERC20
28802
+ * @returns {QuoteResult} The adjusted quote
28803
+ */
28804
+ function adjustQuoteWithFees(ourQuote, amountSpecified, fees, nativeTokenService) {
28805
+ const adjustedAmountIn = adjustAmountIn(ourQuote, amountSpecified, fees, nativeTokenService);
28765
28806
  return {
28766
28807
  gasEstimate: ourQuote.gasEstimate,
28767
28808
  route: ourQuote.route,
28768
- amountIn: amountSpecified,
28809
+ amountIn: adjustedAmountIn,
28769
28810
  amountOut: ourQuote.amountOut,
28770
28811
  tradeType: ourQuote.tradeType,
28771
28812
  };
@@ -28866,6 +28907,8 @@ class Exchange {
28866
28907
  wrappedNativeToken;
28867
28908
  secondaryFees;
28868
28909
  nativeTokenService;
28910
+ secondaryFeeContractAddress;
28911
+ routerContractAddress;
28869
28912
  constructor(configuration) {
28870
28913
  const config = new ExchangeConfiguration(configuration);
28871
28914
  this.chainId = config.chain.chainId;
@@ -28873,13 +28916,13 @@ class Exchange {
28873
28916
  this.wrappedNativeToken = config.chain.wrappedNativeToken;
28874
28917
  this.nativeTokenService = new NativeTokenService(this.nativeToken, this.wrappedNativeToken);
28875
28918
  this.secondaryFees = config.secondaryFees;
28919
+ this.routerContractAddress = config.chain.contracts.peripheryRouter;
28920
+ this.secondaryFeeContractAddress = config.chain.contracts.secondaryFee;
28876
28921
  this.provider = new ethers.providers.JsonRpcProvider(config.chain.rpcUrl);
28877
28922
  this.router = new Router(this.provider, config.chain.commonRoutingTokens, {
28878
28923
  multicallAddress: config.chain.contracts.multicall,
28879
28924
  factoryAddress: config.chain.contracts.coreFactory,
28880
28925
  quoterAddress: config.chain.contracts.quoterV2,
28881
- peripheryRouterAddress: config.chain.contracts.peripheryRouter,
28882
- secondaryFeeAddress: config.chain.contracts.secondaryFee,
28883
28926
  });
28884
28927
  }
28885
28928
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
@@ -28896,7 +28939,7 @@ class Exchange {
28896
28939
  if (this.secondaryFees.length === 0) {
28897
28940
  return [];
28898
28941
  }
28899
- const secondaryFeeContract = SecondaryFee__factory.connect(this.router.routingContracts.secondaryFeeAddress, this.provider);
28942
+ const secondaryFeeContract = SecondaryFee__factory.connect(this.secondaryFeeContractAddress, this.provider);
28900
28943
  if (await secondaryFeeContract.paused()) {
28901
28944
  // Do not use secondary fees if the contract is paused
28902
28945
  return [];
@@ -28924,8 +28967,7 @@ class Exchange {
28924
28967
  decimals: tokenOutDecimals,
28925
28968
  };
28926
28969
  // determine which amount was specified for the swap from the TradeType
28927
- const [tokenSpecified, otherToken] = tradeType === TradeType.EXACT_INPUT
28928
- ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
28970
+ const [tokenSpecified, otherToken] = tradeType === TradeType.EXACT_INPUT ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
28929
28971
  const amountSpecified = newAmount(amount, tokenSpecified);
28930
28972
  const fees = new Fees(secondaryFees, tokenIn);
28931
28973
  const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
@@ -28934,10 +28976,13 @@ class Exchange {
28934
28976
  this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
28935
28977
  fetchGasPrice(this.provider, this.nativeToken),
28936
28978
  ]);
28937
- const adjustedQuote = prepareSwap(ourQuote, amountSpecified, fees);
28938
- const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.router.routingContracts.peripheryRouterAddress, this.router.routingContracts.secondaryFeeAddress, gasPrice, secondaryFees, this.nativeTokenService);
28939
- const userQuote = prepareUserQuote(otherToken, adjustedQuote, slippagePercent, fees);
28940
- const preparedApproval = prepareApproval(tradeType, amountSpecified, userQuote.amountWithMaxSlippage, this.router.routingContracts, secondaryFees);
28979
+ const adjustedQuote = adjustQuoteWithFees(ourQuote, amountSpecified, fees, this.nativeTokenService);
28980
+ const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.routerContractAddress, this.secondaryFeeContractAddress, gasPrice, secondaryFees, this.nativeTokenService);
28981
+ const userQuote = prepareUserQuote(otherToken, adjustedQuote, slippagePercent, fees, this.nativeTokenService);
28982
+ const preparedApproval = prepareApproval(tradeType, amountSpecified, userQuote.amountWithMaxSlippage, {
28983
+ routerAddress: this.routerContractAddress,
28984
+ secondaryFeeAddress: this.secondaryFeeContractAddress,
28985
+ }, secondaryFees);
28941
28986
  // preparedApproval always uses the tokenIn address because we are always selling the tokenIn
28942
28987
  const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice, this.nativeTokenService);
28943
28988
  return {
@@ -33136,7 +33181,7 @@ var $045213b18e9f1f94$export$75be0f6af9650f2c;
33136
33181
  })($045213b18e9f1f94$export$75be0f6af9650f2c || ($045213b18e9f1f94$export$75be0f6af9650f2c = {}));
33137
33182
 
33138
33183
 
33139
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.8";
33184
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.9";
33140
33185
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
33141
33186
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
33142
33187
 
package/dist/passport.js CHANGED
@@ -2072,7 +2072,7 @@ class MultiRollupApiClients {
2072
2072
  }
2073
2073
 
2074
2074
  // eslint-disable-next-line @typescript-eslint/naming-convention
2075
- const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-0.27.8' };
2075
+ const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-0.27.9' };
2076
2076
  const createConfig = ({ basePath, headers, }) => {
2077
2077
  if (!basePath.trim()) {
2078
2078
  throw Error('basePath can not be empty');
@@ -2128,7 +2128,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
2128
2128
  chainID,
2129
2129
  coreContractAddress,
2130
2130
  registrationContractAddress,
2131
- sdkVersion: 'ts-immutable-sdk-0.27.8',
2131
+ sdkVersion: 'ts-immutable-sdk-0.27.9',
2132
2132
  });
2133
2133
  /**
2134
2134
  * Sets `sdkVersion` at the time of build
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@imtbl/sdk",
3
3
  "description": "Immutable Unified SDK",
4
- "version": "0.27.8",
4
+ "version": "0.27.9",
5
5
  "author": "Immutable",
6
6
  "browser": "./dist/index.browser.js",
7
7
  "bugs": "https://github.com/immutable/ts-immutable-sdk/issues",