@imtbl/sdk 0.27.10 → 0.27.11

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.js CHANGED
@@ -3610,7 +3610,7 @@ class MultiRollupApiClients {
3610
3610
  }
3611
3611
 
3612
3612
  // eslint-disable-next-line @typescript-eslint/naming-convention
3613
- const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.10' };
3613
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.11' };
3614
3614
  const createConfig = ({ basePath, headers, }) => {
3615
3615
  if (!basePath.trim()) {
3616
3616
  throw Error('basePath can not be empty');
@@ -3670,7 +3670,7 @@ class APIError extends Error {
3670
3670
 
3671
3671
  /* eslint-disable implicit-arrow-linebreak */
3672
3672
  const defaultHeaders = {
3673
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.10',
3673
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.11',
3674
3674
  };
3675
3675
  /**
3676
3676
  * createAPIConfiguration to create a custom Configuration
@@ -4081,7 +4081,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
4081
4081
  chainID,
4082
4082
  coreContractAddress,
4083
4083
  registrationContractAddress,
4084
- sdkVersion: 'ts-immutable-sdk-0.27.10',
4084
+ sdkVersion: 'ts-immutable-sdk-0.27.11',
4085
4085
  });
4086
4086
  /**
4087
4087
  * Sets `sdkVersion` at the time of build
@@ -28011,8 +28011,11 @@ function poolEquals(poolA, poolB) {
28011
28011
  return (poolA === poolB ||
28012
28012
  (poolA.token0.equals(poolB.token0) && poolA.token1.equals(poolB.token1) && poolA.fee === poolB.fee));
28013
28013
  }
28014
- async function getERC20Decimals(tokenAddress, provider) {
28015
- const decimalsFunctionSig = ethers.utils.id('decimals()').substring(0, 10);
28014
+ const decimalsFunctionSig = ethers.utils.id('decimals()').substring(0, 10);
28015
+ async function getTokenDecimals(tokenAddress, provider, nativeToken) {
28016
+ if (tokenAddress === 'native') {
28017
+ return nativeToken.decimals;
28018
+ }
28016
28019
  try {
28017
28020
  const decimalsResult = await provider.call({
28018
28021
  to: tokenAddress,
@@ -28040,6 +28043,7 @@ function isValidNonZeroAddress(address) {
28040
28043
  return false;
28041
28044
  }
28042
28045
  }
28046
+ const isValidTokenLiteral = (address) => address === 'native' ? true : isValidNonZeroAddress(address);
28043
28047
  const erc20ToUniswapToken = (token) =>
28044
28048
  // eslint-disable-next-line implicit-arrow-linebreak
28045
28049
  new Uniswap.Token(token.chainId, token.address, token.decimals, token.symbol, token.name);
@@ -28494,12 +28498,13 @@ const getUnsignedERC20ApproveTransaction = (ownerAddress, tokenAmount, spenderAd
28494
28498
  from: ownerAddress,
28495
28499
  };
28496
28500
  };
28497
- const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, contracts, secondaryFees) => {
28498
- const amountOfTokenIn = tradeType === TradeType.EXACT_INPUT ? amountSpecified : amountWithSlippage;
28499
- const spender = secondaryFees.length === 0
28500
- ? contracts.routerAddress
28501
- : contracts.secondaryFeeAddress;
28502
- return { spender, amount: amountOfTokenIn };
28501
+ const prepareApproval = (tradeType, userSpecifiedAmount, quotedAmountWithSlippage, contracts, secondaryFees) => {
28502
+ const amountInToApprove = tradeType === TradeType.EXACT_INPUT ? userSpecifiedAmount : quotedAmountWithSlippage;
28503
+ if (!isERC20Amount(amountInToApprove)) {
28504
+ return null;
28505
+ }
28506
+ const spender = secondaryFees.length === 0 ? contracts.routerAddress : contracts.secondaryFeeAddress;
28507
+ return { spender, amount: amountInToApprove };
28503
28508
  };
28504
28509
  /**
28505
28510
  * Get an unsigned approval transaction if needed
@@ -28544,6 +28549,38 @@ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) =
28544
28549
  };
28545
28550
  };
28546
28551
 
28552
+ const canUnwrapToken = (token) => token.type === 'native';
28553
+ class NativeTokenService {
28554
+ nativeToken;
28555
+ wrappedToken;
28556
+ constructor(nativeToken, wrappedToken) {
28557
+ this.nativeToken = nativeToken;
28558
+ this.wrappedToken = wrappedToken;
28559
+ }
28560
+ wrapAmount(amount) {
28561
+ if (!canUnwrapToken(amount.token)) {
28562
+ throw new Error(`cannot wrap non-native token: ${amount.token.address}`);
28563
+ }
28564
+ return newAmount(amount.value, this.wrappedToken);
28565
+ }
28566
+ unwrapAmount(amount) {
28567
+ const isWrappedToken = amount.token.address.toLowerCase() !== this.wrappedToken.address.toLowerCase();
28568
+ if (isWrappedToken) {
28569
+ throw new Error(`cannot unwrap non-wrapped token ${amount.token.address}`);
28570
+ }
28571
+ return newAmount(amount.value, this.nativeToken);
28572
+ }
28573
+ maybeWrapToken(token) {
28574
+ if (canUnwrapToken(token)) {
28575
+ return this.wrappedToken;
28576
+ }
28577
+ return token;
28578
+ }
28579
+ maybeWrapAmount(amount) {
28580
+ return newAmount(amount.value, this.maybeWrapToken(amount.token));
28581
+ }
28582
+ }
28583
+
28547
28584
  // slippageToPercent takes the slippage as a percentage (e.g. 0.1) and
28548
28585
  // converts it to the Uniswap equivalent type
28549
28586
  const slippageToFraction = (slippage) => {
@@ -28563,11 +28600,11 @@ const slippageToFraction = (slippage) => {
28563
28600
  return new Percent(numerator, denominator);
28564
28601
  };
28565
28602
 
28566
- function getQuoteAmountFromTradeType(tradeInfo) {
28567
- if (tradeInfo.tradeType === TradeType.EXACT_INPUT) {
28568
- return tradeInfo.amountOut;
28603
+ function getQuoteAmountFromTradeType(routerQuote) {
28604
+ if (routerQuote.tradeType === TradeType.EXACT_INPUT) {
28605
+ return routerQuote.amountOut;
28569
28606
  }
28570
- return tradeInfo.amountIn;
28607
+ return routerQuote.amountIn;
28571
28608
  }
28572
28609
  function applySlippage(tradeType, amount, slippage) {
28573
28610
  const slippageTolerance = slippageToFraction(slippage);
@@ -28576,6 +28613,18 @@ function applySlippage(tradeType, amount, slippage) {
28576
28613
  const amountWithSlippage = maybeInverted.multiply(amount.toString()).quotient;
28577
28614
  return ethers.BigNumber.from(amountWithSlippage.toString());
28578
28615
  }
28616
+ const prepareUserQuote = (nativeTokenService, routerQuote, slippage, tokenOfQuotedAmount) => {
28617
+ const erc20QuoteAmount = getQuoteAmountFromTradeType(routerQuote);
28618
+ // If the quote amount is the native token, we need to unwrap it if the user originally specified the native token
28619
+ const quotedAmount = canUnwrapToken(tokenOfQuotedAmount)
28620
+ ? nativeTokenService.unwrapAmount(erc20QuoteAmount)
28621
+ : erc20QuoteAmount;
28622
+ const quotedAmountWithMaxSlippage = newAmount(applySlippage(routerQuote.tradeType, quotedAmount.value, slippage), tokenOfQuotedAmount);
28623
+ return {
28624
+ quotedAmount,
28625
+ quotedAmountWithMaxSlippage,
28626
+ };
28627
+ };
28579
28628
  function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
28580
28629
  fees, tradeType, nativeTokenService) {
28581
28630
  if (tradeType === TradeType.EXACT_OUTPUT) {
@@ -28643,39 +28692,6 @@ class Fees {
28643
28692
  }
28644
28693
  }
28645
28694
 
28646
- class NativeTokenService {
28647
- nativeToken;
28648
- wrappedToken;
28649
- constructor(nativeToken, wrappedToken) {
28650
- this.nativeToken = nativeToken;
28651
- this.wrappedToken = wrappedToken;
28652
- }
28653
- wrapAmount(amount) {
28654
- if (!this.isNativeToken(amount.token)) {
28655
- throw new Error(`cannot wrap non-native token: ${amount.token.address}`);
28656
- }
28657
- return newAmount(amount.value, this.wrappedToken);
28658
- }
28659
- unwrapAmount(amount) {
28660
- if (amount.token !== this.wrappedToken) {
28661
- throw new Error(`cannot unwrap non-wrapped token ${amount.token.address}`);
28662
- }
28663
- return newAmount(amount.value, this.nativeToken);
28664
- }
28665
- maybeWrapToken(token) {
28666
- if (this.isNativeToken(token)) {
28667
- return this.wrappedToken;
28668
- }
28669
- return token;
28670
- }
28671
- maybeWrapAmount(amount) {
28672
- return newAmount(amount.value, this.maybeWrapToken(amount.token));
28673
- }
28674
- isNativeToken(token) {
28675
- return token === this.nativeToken;
28676
- }
28677
- }
28678
-
28679
28695
  const IMMUTABLE_TESTNET_RPC_URL = 'https://rpc.testnet.immutable.com';
28680
28696
  const IMMUTABLE_TESTNET_CHAIN_ID = 13472;
28681
28697
  const TIMX_IMMUTABLE_TESTNET = {
@@ -28707,7 +28723,9 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
28707
28723
  recipient: fee.recipient,
28708
28724
  }));
28709
28725
  if (trade.tradeType === TradeType.EXACT_INPUT) {
28710
- return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [secondaryFeeValues, {
28726
+ return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [
28727
+ secondaryFeeValues,
28728
+ {
28711
28729
  tokenIn: route.tokenPath[0].address,
28712
28730
  tokenOut: route.tokenPath[1].address,
28713
28731
  fee: route.pools[0].fee,
@@ -28715,9 +28733,12 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
28715
28733
  amountIn,
28716
28734
  amountOutMinimum: amountOut,
28717
28735
  sqrtPriceLimitX96: 0,
28718
- }]);
28736
+ },
28737
+ ]);
28719
28738
  }
28720
- return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [secondaryFeeValues, {
28739
+ return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [
28740
+ secondaryFeeValues,
28741
+ {
28721
28742
  tokenIn: route.tokenPath[0].address,
28722
28743
  tokenOut: route.tokenPath[1].address,
28723
28744
  fee: route.pools[0].fee,
@@ -28725,7 +28746,8 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
28725
28746
  amountInMaximum: amountIn,
28726
28747
  amountOut,
28727
28748
  sqrtPriceLimitX96: 0,
28728
- }]);
28749
+ },
28750
+ ]);
28729
28751
  }
28730
28752
  function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract) {
28731
28753
  const path = encodeRouteToPath(route, trade.tradeType === TradeType.EXACT_OUTPUT);
@@ -28734,19 +28756,25 @@ function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn
28734
28756
  recipient: fee.recipient,
28735
28757
  }));
28736
28758
  if (trade.tradeType === TradeType.EXACT_INPUT) {
28737
- return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [secondaryFeeValues, {
28759
+ return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [
28760
+ secondaryFeeValues,
28761
+ {
28738
28762
  path,
28739
28763
  recipient: fromAddress,
28740
28764
  amountIn,
28741
28765
  amountOutMinimum: amountOut,
28742
- }]);
28766
+ },
28767
+ ]);
28743
28768
  }
28744
- return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [secondaryFeeValues, {
28769
+ return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [
28770
+ secondaryFeeValues,
28771
+ {
28745
28772
  path,
28746
28773
  recipient: fromAddress,
28747
28774
  amountInMaximum: amountIn,
28748
28775
  amountOut,
28749
- }]);
28776
+ },
28777
+ ]);
28750
28778
  }
28751
28779
  /**
28752
28780
  * Builds swap parameters
@@ -28771,7 +28799,10 @@ function buildSwapParameters(fromAddress, trade, options, secondaryFees, seconda
28771
28799
  function createSwapCallParametersWithFees(trade, fromAddress, swapOptions, secondaryFees) {
28772
28800
  const secondaryFeeContract = SecondaryFee__factory.createInterface();
28773
28801
  const swapWithFeesCalldata = buildSwapParameters(fromAddress, trade, swapOptions, secondaryFees, secondaryFeeContract);
28774
- return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [swapOptions.deadlineOrPreviousBlockhash, [swapWithFeesCalldata]]);
28802
+ return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [
28803
+ swapOptions.deadlineOrPreviousBlockhash,
28804
+ [swapWithFeesCalldata],
28805
+ ]);
28775
28806
  }
28776
28807
  function createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, secondaryFees) {
28777
28808
  // Create an unchecked trade to be used in generating swap parameters.
@@ -28811,7 +28842,7 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
28811
28842
  const adjustAmountIn = (ourQuote, amountSpecified, fees, nativeTokenService) => {
28812
28843
  if (ourQuote.tradeType === TradeType.EXACT_OUTPUT) {
28813
28844
  // when doing exact output, calculate the fees based on the amountIn
28814
- const amountToAdd = nativeTokenService.isNativeToken(fees.token)
28845
+ const amountToAdd = canUnwrapToken(fees.token)
28815
28846
  ? nativeTokenService.unwrapAmount(ourQuote.amountIn)
28816
28847
  : ourQuote.amountIn;
28817
28848
  fees.addAmount(amountToAdd);
@@ -28928,8 +28959,8 @@ class ExchangeConfiguration {
28928
28959
  }
28929
28960
 
28930
28961
  const toPublicQuote = (amount, amountWithMaxSlippage, slippage, fees) => ({
28931
- amount,
28932
- amountWithMaxSlippage,
28962
+ amount: toPublicAmount(amount),
28963
+ amountWithMaxSlippage: toPublicAmount(amountWithMaxSlippage),
28933
28964
  slippage,
28934
28965
  fees: fees.withAmounts().map((fee) => ({
28935
28966
  ...fee,
@@ -28964,8 +28995,8 @@ class Exchange {
28964
28995
  }
28965
28996
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
28966
28997
  assert(isValidNonZeroAddress(fromAddress), new InvalidAddressError('invalid from address'));
28967
- assert(isValidNonZeroAddress(tokenInAddress), new InvalidAddressError('invalid token in address'));
28968
- assert(isValidNonZeroAddress(tokenOutAddress), new InvalidAddressError('invalid token out address'));
28998
+ assert(isValidTokenLiteral(tokenInAddress), new InvalidAddressError('invalid token in address'));
28999
+ assert(isValidTokenLiteral(tokenOutAddress), new InvalidAddressError('invalid token out address'));
28969
29000
  assert(tokenInAddress.toLocaleLowerCase() !== tokenOutAddress.toLocaleLowerCase(), new DuplicateAddressesError());
28970
29001
  assert(maxHops <= MAX_MAX_HOPS, new InvalidMaxHopsError('max hops must be less than or equal to 10'));
28971
29002
  assert(maxHops >= MIN_MAX_HOPS, new InvalidMaxHopsError('max hops must be greater than or equal to 1'));
@@ -28983,61 +29014,63 @@ class Exchange {
28983
29014
  }
28984
29015
  return this.secondaryFees;
28985
29016
  }
28986
- async getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, amount, slippagePercent, maxHops, deadline, tradeType) {
28987
- Exchange.validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress);
29017
+ parseTokenLiteral(tokenLiteral, decimals) {
29018
+ if (tokenLiteral === 'native') {
29019
+ return this.nativeToken;
29020
+ }
29021
+ return {
29022
+ type: 'erc20',
29023
+ address: tokenLiteral,
29024
+ chainId: this.chainId,
29025
+ decimals,
29026
+ };
29027
+ }
29028
+ async getUnsignedSwapTx(fromAddress, tokenInLiteral, tokenOutLiteral, amount, slippagePercent, maxHops, deadline, tradeType) {
29029
+ Exchange.validate(tokenInLiteral, tokenOutLiteral, maxHops, slippagePercent, fromAddress);
28988
29030
  // get the decimals of the tokens that will be swapped
28989
29031
  const [tokenInDecimals, tokenOutDecimals, secondaryFees] = await Promise.all([
28990
- getERC20Decimals(tokenInAddress, this.provider),
28991
- getERC20Decimals(tokenOutAddress, this.provider),
29032
+ getTokenDecimals(tokenInLiteral, this.provider, this.nativeToken),
29033
+ getTokenDecimals(tokenOutLiteral, this.provider, this.nativeToken),
28992
29034
  this.getSecondaryFees(),
28993
29035
  ]);
28994
- const tokenIn = {
28995
- type: 'erc20',
28996
- address: tokenInAddress,
28997
- chainId: this.chainId,
28998
- decimals: tokenInDecimals,
28999
- };
29000
- const tokenOut = {
29001
- type: 'erc20',
29002
- address: tokenOutAddress,
29003
- chainId: this.chainId,
29004
- decimals: tokenOutDecimals,
29005
- };
29036
+ const tokenIn = this.parseTokenLiteral(tokenInLiteral, tokenInDecimals);
29037
+ const tokenOut = this.parseTokenLiteral(tokenOutLiteral, tokenOutDecimals);
29006
29038
  // determine which amount was specified for the swap from the TradeType
29007
29039
  const [tokenSpecified, otherToken] = tradeType === TradeType.EXACT_INPUT ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
29008
29040
  const amountSpecified = newAmount(amount, tokenSpecified);
29009
29041
  const fees = new Fees(secondaryFees, tokenIn);
29010
29042
  const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
29011
- // get quote and gas details
29043
+ // Quotes will always use ERC20s. If the user-specified token is Native, we use the Wrapped Native Token pool
29012
29044
  const [ourQuote, gasPrice] = await Promise.all([
29013
- this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
29045
+ this.router.findOptimalRoute(ourQuoteReqAmount, this.nativeTokenService.maybeWrapToken(otherToken), tradeType, maxHops),
29014
29046
  fetchGasPrice(this.provider, this.nativeToken),
29015
29047
  ]);
29016
29048
  const adjustedQuote = adjustQuoteWithFees(ourQuote, amountSpecified, fees, this.nativeTokenService);
29017
29049
  const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.routerContractAddress, this.secondaryFeeContractAddress, gasPrice, secondaryFees, this.nativeTokenService);
29018
- const quotedAmount = getQuoteAmountFromTradeType(adjustedQuote);
29019
- const amountWithMaxSlippage = newAmount(applySlippage(adjustedQuote.tradeType, quotedAmount.value, slippagePercent), otherToken);
29020
- const preparedApproval = prepareApproval(tradeType, amountSpecified, amountWithMaxSlippage, {
29050
+ const { quotedAmount, quotedAmountWithMaxSlippage } = prepareUserQuote(this.nativeTokenService, adjustedQuote, slippagePercent, otherToken);
29051
+ const preparedApproval = prepareApproval(tradeType, amountSpecified, quotedAmountWithMaxSlippage, {
29021
29052
  routerAddress: this.routerContractAddress,
29022
29053
  secondaryFeeAddress: this.secondaryFeeContractAddress,
29023
29054
  }, secondaryFees);
29024
29055
  // preparedApproval always uses the tokenIn address because we are always selling the tokenIn
29025
- const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice);
29026
- const quote = toPublicQuote(quotedAmount, amountWithMaxSlippage, slippagePercent, fees);
29056
+ const approval = preparedApproval
29057
+ ? await getApproval(this.provider, fromAddress, preparedApproval, gasPrice)
29058
+ : null;
29059
+ const quote = toPublicQuote(quotedAmount, quotedAmountWithMaxSlippage, slippagePercent, fees);
29027
29060
  return { quote, approval, swap };
29028
29061
  }
29029
29062
  /**
29030
29063
  * Get the unsigned swap transaction given the amount to sell.
29031
29064
  * Includes quote details for the swap.
29032
29065
  *
29033
- * @param {string} fromAddress The public address that will sign and submit the transaction.
29034
- * @param {string} tokenInAddress Token address to sell.
29035
- * @param {string} tokenOutAddress Token address to buy.
29036
- * @param {ethers.BigNumberish} amountIn Amount to sell.
29037
- * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0.
29038
- * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2.
29039
- * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes.
29040
- * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap.
29066
+ * @param {string} fromAddress The public address that will sign and submit the transaction
29067
+ * @param {string} tokenInAddress Token address or 'native' to sell
29068
+ * @param {string} tokenOutAddress Token address or 'native' to buy
29069
+ * @param {ethers.BigNumberish} amountIn Amount to sell in the smallest unit of the token-in
29070
+ * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
29071
+ * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
29072
+ * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
29073
+ * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap
29041
29074
  */
29042
29075
  async getUnsignedSwapTxFromAmountIn(fromAddress, tokenInAddress, tokenOutAddress, amountIn, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
29043
29076
  return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.BigNumber.from(amountIn), slippagePercent, maxHops, deadline, TradeType.EXACT_INPUT);
@@ -29046,14 +29079,14 @@ class Exchange {
29046
29079
  * Get the unsigned swap transaction given the amount to buy.
29047
29080
  * Includes quote details for the swap.
29048
29081
  *
29049
- * @param {string} fromAddress The public address that will sign and submit the transaction.
29050
- * @param {string} tokenInAddress Token address to sell.
29051
- * @param {string} tokenOutAddress Token address to buy.
29052
- * @param {ethers.BigNumberish} amountOut Amount to buy.
29053
- * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0.
29054
- * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2.
29055
- * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes.
29056
- * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap.
29082
+ * @param {string} fromAddress The public address that will sign and submit the transaction
29083
+ * @param {string} tokenInAddress ERC20 contract address or 'native' to sell
29084
+ * @param {string} tokenOutAddress ERC20 contract address or 'native' to buy
29085
+ * @param {ethers.BigNumberish} amountOut Amount to buy in the smallest unit of the token-out
29086
+ * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
29087
+ * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
29088
+ * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
29089
+ * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap
29057
29090
  */
29058
29091
  async getUnsignedSwapTxFromAmountOut(fromAddress, tokenInAddress, tokenOutAddress, amountOut, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
29059
29092
  return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.BigNumber.from(amountOut), slippagePercent, maxHops, deadline, TradeType.EXACT_OUTPUT);
@@ -29297,6 +29330,14 @@ const $d85ad1457a3f1a83$export$fc55ed5a42b458ba = {
29297
29330
  [($0472f23319457bfb$export$c06e1e7429de6283).IMTBL_ZKEVM_MAINNET]: {
29298
29331
  url: "https://explorer.mainnet.immutable.com",
29299
29332
  nativeToken: $d85ad1457a3f1a83$export$6f24f3cef7d501c4.get(($0472f23319457bfb$export$c06e1e7429de6283).IMTBL_ZKEVM_MAINNET).nativeCurrency
29333
+ },
29334
+ [($0472f23319457bfb$export$c06e1e7429de6283).SEPOLIA]: {
29335
+ url: "https://eth-sepolia.blockscout.com",
29336
+ nativeToken: $d85ad1457a3f1a83$export$3e81fc0987227f10.get(($0472f23319457bfb$export$c06e1e7429de6283).SEPOLIA).nativeCurrency
29337
+ },
29338
+ [($0472f23319457bfb$export$c06e1e7429de6283).ETHEREUM]: {
29339
+ url: "https://eth.blockscout.com/",
29340
+ nativeToken: $d85ad1457a3f1a83$export$6f24f3cef7d501c4.get(($0472f23319457bfb$export$c06e1e7429de6283).ETHEREUM).nativeCurrency
29300
29341
  }
29301
29342
  };
29302
29343
  const $d85ad1457a3f1a83$export$db5daa1b5156ccfe = [
@@ -29896,6 +29937,7 @@ const $efe60cea83bfc4e8$export$473cec51305fdae8 = async (config, { type: type =
29896
29937
 
29897
29938
 
29898
29939
 
29940
+
29899
29941
  const $fd8a8472dcc3ec2b$var$CACHE_DATA_TTL = 60; // seconds
29900
29942
  class $fd8a8472dcc3ec2b$export$ef140a6b05dfc786 {
29901
29943
  url;
@@ -30068,18 +30110,23 @@ async function $1564e43dde50bb61$export$60e0fe116a0e6ed0(web3Provider, walletAdd
30068
30110
  type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_ERC20_BALANCE_ERROR
30069
30111
  });
30070
30112
  }
30071
- // Blockscout client singleton
30072
- let $1564e43dde50bb61$var$blockscoutClient;
30073
- const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId, rename)=>{
30113
+ // Blockscout client singleton per chain id
30114
+ const $1564e43dde50bb61$var$blockscoutClientMap = new Map();
30115
+ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId, filterTokens)=>{
30074
30116
  // Shuffle the mapping of the tokens configuration so it is a hashmap
30075
30117
  // for faster access to tokens config objects.
30076
- const mapRename = Object.assign({}, ...rename.map((t)=>({
30118
+ const shouldFilter = filterTokens.length > 0;
30119
+ const mapFilterTokens = Object.assign({}, ...filterTokens.map((t)=>({
30077
30120
  [t.address || ""]: t
30078
30121
  })));
30079
- // Ensure singleton is present and match the selected chain
30080
- if (!$1564e43dde50bb61$var$blockscoutClient || $1564e43dde50bb61$var$blockscoutClient.chainId !== chainId) $1564e43dde50bb61$var$blockscoutClient = new ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786)({
30081
- chainId: chainId
30082
- });
30122
+ // Get blockscout client for the given chain
30123
+ let blockscoutClient = $1564e43dde50bb61$var$blockscoutClientMap.get(chainId);
30124
+ if (!blockscoutClient) {
30125
+ blockscoutClient = new ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786)({
30126
+ chainId: chainId
30127
+ });
30128
+ $1564e43dde50bb61$var$blockscoutClientMap.set(chainId, blockscoutClient);
30129
+ }
30083
30130
  // Hold the items in an array for post-fetching processing
30084
30131
  const items = [];
30085
30132
  const tokenType = ($887a00f8f72d61f0$export$5bd1ea2b3d18210).ERC20;
@@ -30089,7 +30136,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
30089
30136
  try {
30090
30137
  do {
30091
30138
  // eslint-disable-next-line no-await-in-loop
30092
- resp = await $1564e43dde50bb61$var$blockscoutClient.getTokensByWalletAddress({
30139
+ resp = await blockscoutClient.getTokensByWalletAddress({
30093
30140
  walletAddress: walletAddress,
30094
30141
  tokenType: tokenType,
30095
30142
  nextPage: resp?.next_page_params
@@ -30107,7 +30154,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
30107
30154
  if (err?.code !== (HttpStatusCode$2).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getTokensByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
30108
30155
  }
30109
30156
  try {
30110
- const respNative = await $1564e43dde50bb61$var$blockscoutClient.getNativeTokenByWalletAddress({
30157
+ const respNative = await blockscoutClient.getNativeTokenByWalletAddress({
30111
30158
  walletAddress: walletAddress
30112
30159
  });
30113
30160
  items.push(respNative);
@@ -30121,24 +30168,26 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
30121
30168
  // or simply an incorrect wallet address was provided.
30122
30169
  if (err?.code !== (HttpStatusCode$2).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getNativeTokenByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
30123
30170
  }
30171
+ const balances = [];
30172
+ items.forEach((item)=>{
30173
+ if (shouldFilter && !mapFilterTokens[item.token.address]) return;
30174
+ const tokenData = item.token || {};
30175
+ const balance = (BigNumber$1).from(item.value);
30176
+ let decimals = parseInt(tokenData.decimals, 10);
30177
+ if (Number.isNaN(decimals)) decimals = ($d85ad1457a3f1a83$export$903389470ba9433c);
30178
+ const token = {
30179
+ ...tokenData,
30180
+ decimals: decimals
30181
+ };
30182
+ const formattedBalance = (utils$1).formatUnits(item.value, token.decimals);
30183
+ balances.push({
30184
+ balance: balance,
30185
+ formattedBalance: formattedBalance,
30186
+ token: token
30187
+ });
30188
+ });
30124
30189
  return {
30125
- balances: items.map((item)=>{
30126
- const tokenData = item.token || {};
30127
- const balance = (BigNumber$1).from(item.value);
30128
- const renamed = mapRename[tokenData.address] || {};
30129
- const token = {
30130
- ...tokenData,
30131
- name: renamed.name ?? tokenData.name,
30132
- symbol: renamed.symbol ?? tokenData.symbol,
30133
- decimals: parseInt(tokenData.decimals, 10)
30134
- };
30135
- const formattedBalance = (utils$1).formatUnits(item.value, token.decimals);
30136
- return {
30137
- balance: balance,
30138
- formattedBalance: formattedBalance,
30139
- token: token
30140
- };
30141
- })
30190
+ balances: balances
30142
30191
  };
30143
30192
  };
30144
30193
  const $1564e43dde50bb61$export$a3238cee431627c6 = async (config, web3Provider, walletAddress, tokens)=>{
@@ -30169,7 +30218,15 @@ const $1564e43dde50bb61$export$fee49741664a4d7e = async (config, web3Provider, w
30169
30218
  // eslint-disable-next-line no-console
30170
30219
  console.error(err);
30171
30220
  }
30172
- if (flag && ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786).isChainSupported(chainId)) return await $1564e43dde50bb61$export$8c978679845804d4(walletAddress, chainId, tokens);
30221
+ if (flag && ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786).isChainSupported(chainId)) {
30222
+ // This is a hack because the widgets are still using the tokens symbol
30223
+ // to drive the conversions. If we remove all the token symbols from e.g. zkevm
30224
+ // then we would not have fiat conversions.
30225
+ // Please remove this hack once https://immutable.atlassian.net/browse/WT-1710
30226
+ // is done.
30227
+ const isL1Chain = ($4013c5c91bb535f6$export$9b794d067cdd1af6)(config) === chainId;
30228
+ return await $1564e43dde50bb61$export$8c978679845804d4(walletAddress, chainId, isL1Chain ? tokens : []);
30229
+ }
30173
30230
  // This fallback to use ERC20s calls which is a best effort solution
30174
30231
  // Fails in fetching data from the RCP calls might result in some
30175
30232
  // missing data.
@@ -33143,7 +33200,7 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
33143
33200
  const tokenList = await $efe60cea83bfc4e8$export$473cec51305fdae8(this.config, {
33144
33201
  type: ($08d5ddc39acd6833$export$fd9b17d87f4121d2).ONRAMP
33145
33202
  });
33146
- const token = tokenList.tokens.find((t)=>t.address?.toLowerCase() === params.tokenAddress?.toLowerCase());
33203
+ const token = tokenList.tokens?.find((t)=>t.address?.toLowerCase() === params.tokenAddress?.toLowerCase());
33147
33204
  if (token) {
33148
33205
  tokenAmount = params.tokenAmount;
33149
33206
  tokenSymbol = token.symbol;
@@ -33216,7 +33273,7 @@ var $045213b18e9f1f94$export$75be0f6af9650f2c;
33216
33273
  })($045213b18e9f1f94$export$75be0f6af9650f2c || ($045213b18e9f1f94$export$75be0f6af9650f2c = {}));
33217
33274
 
33218
33275
 
33219
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.10";
33276
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.11";
33220
33277
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
33221
33278
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
33222
33279
 
@@ -33350,7 +33407,7 @@ var $207ed853f11d19d5$export$5a0ace85cae72d45;
33350
33407
  IMTBLWidgetEvents["IMTBL_SWAP_WIDGET_EVENT"] = "imtbl-swap-widget";
33351
33408
  IMTBLWidgetEvents["IMTBL_BRIDGE_WIDGET_EVENT"] = "imtbl-bridge-widget";
33352
33409
  IMTBLWidgetEvents["IMTBL_ONRAMP_WIDGET_EVENT"] = "imtbl-onramp-widget";
33353
- IMTBLWidgetEvents["IMTBL_PRIMARY_REVENUE_WIDGET_EVENT"] = "imtbl-sale-widget";
33410
+ IMTBLWidgetEvents["IMTBL_SALE_WIDGET_EVENT"] = "imtbl-sale-widget";
33354
33411
  })($207ed853f11d19d5$export$5a0ace85cae72d45 || ($207ed853f11d19d5$export$5a0ace85cae72d45 = {}));
33355
33412
 
33356
33413
 
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.10' };
2075
+ const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-0.27.11' };
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.10',
2131
+ sdkVersion: 'ts-immutable-sdk-0.27.11',
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.10",
4
+ "version": "0.27.11",
5
5
  "author": "Immutable",
6
6
  "browser": "./dist/index.browser.js",
7
7
  "bugs": "https://github.com/immutable/ts-immutable-sdk/issues",