@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.cjs CHANGED
@@ -3632,7 +3632,7 @@ class MultiRollupApiClients {
3632
3632
  }
3633
3633
 
3634
3634
  // eslint-disable-next-line @typescript-eslint/naming-convention
3635
- const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.10' };
3635
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.11' };
3636
3636
  const createConfig = ({ basePath, headers, }) => {
3637
3637
  if (!basePath.trim()) {
3638
3638
  throw Error('basePath can not be empty');
@@ -3692,7 +3692,7 @@ class APIError extends Error {
3692
3692
 
3693
3693
  /* eslint-disable implicit-arrow-linebreak */
3694
3694
  const defaultHeaders = {
3695
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.10',
3695
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.11',
3696
3696
  };
3697
3697
  /**
3698
3698
  * createAPIConfiguration to create a custom Configuration
@@ -4103,7 +4103,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
4103
4103
  chainID,
4104
4104
  coreContractAddress,
4105
4105
  registrationContractAddress,
4106
- sdkVersion: 'ts-immutable-sdk-0.27.10',
4106
+ sdkVersion: 'ts-immutable-sdk-0.27.11',
4107
4107
  });
4108
4108
  /**
4109
4109
  * Sets `sdkVersion` at the time of build
@@ -28033,8 +28033,11 @@ function poolEquals(poolA, poolB) {
28033
28033
  return (poolA === poolB ||
28034
28034
  (poolA.token0.equals(poolB.token0) && poolA.token1.equals(poolB.token1) && poolA.fee === poolB.fee));
28035
28035
  }
28036
- async function getERC20Decimals(tokenAddress, provider) {
28037
- const decimalsFunctionSig = ethers.ethers.utils.id('decimals()').substring(0, 10);
28036
+ const decimalsFunctionSig = ethers.ethers.utils.id('decimals()').substring(0, 10);
28037
+ async function getTokenDecimals(tokenAddress, provider, nativeToken) {
28038
+ if (tokenAddress === 'native') {
28039
+ return nativeToken.decimals;
28040
+ }
28038
28041
  try {
28039
28042
  const decimalsResult = await provider.call({
28040
28043
  to: tokenAddress,
@@ -28062,6 +28065,7 @@ function isValidNonZeroAddress(address) {
28062
28065
  return false;
28063
28066
  }
28064
28067
  }
28068
+ const isValidTokenLiteral = (address) => address === 'native' ? true : isValidNonZeroAddress(address);
28065
28069
  const erc20ToUniswapToken = (token) =>
28066
28070
  // eslint-disable-next-line implicit-arrow-linebreak
28067
28071
  new Uniswap__namespace.Token(token.chainId, token.address, token.decimals, token.symbol, token.name);
@@ -28516,12 +28520,13 @@ const getUnsignedERC20ApproveTransaction = (ownerAddress, tokenAmount, spenderAd
28516
28520
  from: ownerAddress,
28517
28521
  };
28518
28522
  };
28519
- const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, contracts, secondaryFees) => {
28520
- const amountOfTokenIn = tradeType === Uniswap.TradeType.EXACT_INPUT ? amountSpecified : amountWithSlippage;
28521
- const spender = secondaryFees.length === 0
28522
- ? contracts.routerAddress
28523
- : contracts.secondaryFeeAddress;
28524
- return { spender, amount: amountOfTokenIn };
28523
+ const prepareApproval = (tradeType, userSpecifiedAmount, quotedAmountWithSlippage, contracts, secondaryFees) => {
28524
+ const amountInToApprove = tradeType === Uniswap.TradeType.EXACT_INPUT ? userSpecifiedAmount : quotedAmountWithSlippage;
28525
+ if (!isERC20Amount(amountInToApprove)) {
28526
+ return null;
28527
+ }
28528
+ const spender = secondaryFees.length === 0 ? contracts.routerAddress : contracts.secondaryFeeAddress;
28529
+ return { spender, amount: amountInToApprove };
28525
28530
  };
28526
28531
  /**
28527
28532
  * Get an unsigned approval transaction if needed
@@ -28566,6 +28571,38 @@ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) =
28566
28571
  };
28567
28572
  };
28568
28573
 
28574
+ const canUnwrapToken = (token) => token.type === 'native';
28575
+ class NativeTokenService {
28576
+ nativeToken;
28577
+ wrappedToken;
28578
+ constructor(nativeToken, wrappedToken) {
28579
+ this.nativeToken = nativeToken;
28580
+ this.wrappedToken = wrappedToken;
28581
+ }
28582
+ wrapAmount(amount) {
28583
+ if (!canUnwrapToken(amount.token)) {
28584
+ throw new Error(`cannot wrap non-native token: ${amount.token.address}`);
28585
+ }
28586
+ return newAmount(amount.value, this.wrappedToken);
28587
+ }
28588
+ unwrapAmount(amount) {
28589
+ const isWrappedToken = amount.token.address.toLowerCase() !== this.wrappedToken.address.toLowerCase();
28590
+ if (isWrappedToken) {
28591
+ throw new Error(`cannot unwrap non-wrapped token ${amount.token.address}`);
28592
+ }
28593
+ return newAmount(amount.value, this.nativeToken);
28594
+ }
28595
+ maybeWrapToken(token) {
28596
+ if (canUnwrapToken(token)) {
28597
+ return this.wrappedToken;
28598
+ }
28599
+ return token;
28600
+ }
28601
+ maybeWrapAmount(amount) {
28602
+ return newAmount(amount.value, this.maybeWrapToken(amount.token));
28603
+ }
28604
+ }
28605
+
28569
28606
  // slippageToPercent takes the slippage as a percentage (e.g. 0.1) and
28570
28607
  // converts it to the Uniswap equivalent type
28571
28608
  const slippageToFraction = (slippage) => {
@@ -28585,11 +28622,11 @@ const slippageToFraction = (slippage) => {
28585
28622
  return new Uniswap.Percent(numerator, denominator);
28586
28623
  };
28587
28624
 
28588
- function getQuoteAmountFromTradeType(tradeInfo) {
28589
- if (tradeInfo.tradeType === Uniswap.TradeType.EXACT_INPUT) {
28590
- return tradeInfo.amountOut;
28625
+ function getQuoteAmountFromTradeType(routerQuote) {
28626
+ if (routerQuote.tradeType === Uniswap.TradeType.EXACT_INPUT) {
28627
+ return routerQuote.amountOut;
28591
28628
  }
28592
- return tradeInfo.amountIn;
28629
+ return routerQuote.amountIn;
28593
28630
  }
28594
28631
  function applySlippage(tradeType, amount, slippage) {
28595
28632
  const slippageTolerance = slippageToFraction(slippage);
@@ -28598,6 +28635,18 @@ function applySlippage(tradeType, amount, slippage) {
28598
28635
  const amountWithSlippage = maybeInverted.multiply(amount.toString()).quotient;
28599
28636
  return ethers.ethers.BigNumber.from(amountWithSlippage.toString());
28600
28637
  }
28638
+ const prepareUserQuote = (nativeTokenService, routerQuote, slippage, tokenOfQuotedAmount) => {
28639
+ const erc20QuoteAmount = getQuoteAmountFromTradeType(routerQuote);
28640
+ // If the quote amount is the native token, we need to unwrap it if the user originally specified the native token
28641
+ const quotedAmount = canUnwrapToken(tokenOfQuotedAmount)
28642
+ ? nativeTokenService.unwrapAmount(erc20QuoteAmount)
28643
+ : erc20QuoteAmount;
28644
+ const quotedAmountWithMaxSlippage = newAmount(applySlippage(routerQuote.tradeType, quotedAmount.value, slippage), tokenOfQuotedAmount);
28645
+ return {
28646
+ quotedAmount,
28647
+ quotedAmountWithMaxSlippage,
28648
+ };
28649
+ };
28601
28650
  function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
28602
28651
  fees, tradeType, nativeTokenService) {
28603
28652
  if (tradeType === Uniswap.TradeType.EXACT_OUTPUT) {
@@ -28665,39 +28714,6 @@ class Fees {
28665
28714
  }
28666
28715
  }
28667
28716
 
28668
- class NativeTokenService {
28669
- nativeToken;
28670
- wrappedToken;
28671
- constructor(nativeToken, wrappedToken) {
28672
- this.nativeToken = nativeToken;
28673
- this.wrappedToken = wrappedToken;
28674
- }
28675
- wrapAmount(amount) {
28676
- if (!this.isNativeToken(amount.token)) {
28677
- throw new Error(`cannot wrap non-native token: ${amount.token.address}`);
28678
- }
28679
- return newAmount(amount.value, this.wrappedToken);
28680
- }
28681
- unwrapAmount(amount) {
28682
- if (amount.token !== this.wrappedToken) {
28683
- throw new Error(`cannot unwrap non-wrapped token ${amount.token.address}`);
28684
- }
28685
- return newAmount(amount.value, this.nativeToken);
28686
- }
28687
- maybeWrapToken(token) {
28688
- if (this.isNativeToken(token)) {
28689
- return this.wrappedToken;
28690
- }
28691
- return token;
28692
- }
28693
- maybeWrapAmount(amount) {
28694
- return newAmount(amount.value, this.maybeWrapToken(amount.token));
28695
- }
28696
- isNativeToken(token) {
28697
- return token === this.nativeToken;
28698
- }
28699
- }
28700
-
28701
28717
  const IMMUTABLE_TESTNET_RPC_URL = 'https://rpc.testnet.immutable.com';
28702
28718
  const IMMUTABLE_TESTNET_CHAIN_ID = 13472;
28703
28719
  const TIMX_IMMUTABLE_TESTNET = {
@@ -28729,7 +28745,9 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
28729
28745
  recipient: fee.recipient,
28730
28746
  }));
28731
28747
  if (trade.tradeType === Uniswap.TradeType.EXACT_INPUT) {
28732
- return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [secondaryFeeValues, {
28748
+ return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [
28749
+ secondaryFeeValues,
28750
+ {
28733
28751
  tokenIn: route.tokenPath[0].address,
28734
28752
  tokenOut: route.tokenPath[1].address,
28735
28753
  fee: route.pools[0].fee,
@@ -28737,9 +28755,12 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
28737
28755
  amountIn,
28738
28756
  amountOutMinimum: amountOut,
28739
28757
  sqrtPriceLimitX96: 0,
28740
- }]);
28758
+ },
28759
+ ]);
28741
28760
  }
28742
- return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [secondaryFeeValues, {
28761
+ return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [
28762
+ secondaryFeeValues,
28763
+ {
28743
28764
  tokenIn: route.tokenPath[0].address,
28744
28765
  tokenOut: route.tokenPath[1].address,
28745
28766
  fee: route.pools[0].fee,
@@ -28747,7 +28768,8 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
28747
28768
  amountInMaximum: amountIn,
28748
28769
  amountOut,
28749
28770
  sqrtPriceLimitX96: 0,
28750
- }]);
28771
+ },
28772
+ ]);
28751
28773
  }
28752
28774
  function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract) {
28753
28775
  const path = v3Sdk.encodeRouteToPath(route, trade.tradeType === Uniswap.TradeType.EXACT_OUTPUT);
@@ -28756,19 +28778,25 @@ function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn
28756
28778
  recipient: fee.recipient,
28757
28779
  }));
28758
28780
  if (trade.tradeType === Uniswap.TradeType.EXACT_INPUT) {
28759
- return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [secondaryFeeValues, {
28781
+ return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [
28782
+ secondaryFeeValues,
28783
+ {
28760
28784
  path,
28761
28785
  recipient: fromAddress,
28762
28786
  amountIn,
28763
28787
  amountOutMinimum: amountOut,
28764
- }]);
28788
+ },
28789
+ ]);
28765
28790
  }
28766
- return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [secondaryFeeValues, {
28791
+ return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [
28792
+ secondaryFeeValues,
28793
+ {
28767
28794
  path,
28768
28795
  recipient: fromAddress,
28769
28796
  amountInMaximum: amountIn,
28770
28797
  amountOut,
28771
- }]);
28798
+ },
28799
+ ]);
28772
28800
  }
28773
28801
  /**
28774
28802
  * Builds swap parameters
@@ -28793,7 +28821,10 @@ function buildSwapParameters(fromAddress, trade, options, secondaryFees, seconda
28793
28821
  function createSwapCallParametersWithFees(trade, fromAddress, swapOptions, secondaryFees) {
28794
28822
  const secondaryFeeContract = SecondaryFee__factory.createInterface();
28795
28823
  const swapWithFeesCalldata = buildSwapParameters(fromAddress, trade, swapOptions, secondaryFees, secondaryFeeContract);
28796
- return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [swapOptions.deadlineOrPreviousBlockhash, [swapWithFeesCalldata]]);
28824
+ return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [
28825
+ swapOptions.deadlineOrPreviousBlockhash,
28826
+ [swapWithFeesCalldata],
28827
+ ]);
28797
28828
  }
28798
28829
  function createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, secondaryFees) {
28799
28830
  // Create an unchecked trade to be used in generating swap parameters.
@@ -28833,7 +28864,7 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
28833
28864
  const adjustAmountIn = (ourQuote, amountSpecified, fees, nativeTokenService) => {
28834
28865
  if (ourQuote.tradeType === Uniswap.TradeType.EXACT_OUTPUT) {
28835
28866
  // when doing exact output, calculate the fees based on the amountIn
28836
- const amountToAdd = nativeTokenService.isNativeToken(fees.token)
28867
+ const amountToAdd = canUnwrapToken(fees.token)
28837
28868
  ? nativeTokenService.unwrapAmount(ourQuote.amountIn)
28838
28869
  : ourQuote.amountIn;
28839
28870
  fees.addAmount(amountToAdd);
@@ -28950,8 +28981,8 @@ class ExchangeConfiguration {
28950
28981
  }
28951
28982
 
28952
28983
  const toPublicQuote = (amount, amountWithMaxSlippage, slippage, fees) => ({
28953
- amount,
28954
- amountWithMaxSlippage,
28984
+ amount: toPublicAmount(amount),
28985
+ amountWithMaxSlippage: toPublicAmount(amountWithMaxSlippage),
28955
28986
  slippage,
28956
28987
  fees: fees.withAmounts().map((fee) => ({
28957
28988
  ...fee,
@@ -28986,8 +29017,8 @@ class Exchange {
28986
29017
  }
28987
29018
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
28988
29019
  assert(isValidNonZeroAddress(fromAddress), new InvalidAddressError('invalid from address'));
28989
- assert(isValidNonZeroAddress(tokenInAddress), new InvalidAddressError('invalid token in address'));
28990
- assert(isValidNonZeroAddress(tokenOutAddress), new InvalidAddressError('invalid token out address'));
29020
+ assert(isValidTokenLiteral(tokenInAddress), new InvalidAddressError('invalid token in address'));
29021
+ assert(isValidTokenLiteral(tokenOutAddress), new InvalidAddressError('invalid token out address'));
28991
29022
  assert(tokenInAddress.toLocaleLowerCase() !== tokenOutAddress.toLocaleLowerCase(), new DuplicateAddressesError());
28992
29023
  assert(maxHops <= MAX_MAX_HOPS, new InvalidMaxHopsError('max hops must be less than or equal to 10'));
28993
29024
  assert(maxHops >= MIN_MAX_HOPS, new InvalidMaxHopsError('max hops must be greater than or equal to 1'));
@@ -29005,61 +29036,63 @@ class Exchange {
29005
29036
  }
29006
29037
  return this.secondaryFees;
29007
29038
  }
29008
- async getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, amount, slippagePercent, maxHops, deadline, tradeType) {
29009
- Exchange.validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress);
29039
+ parseTokenLiteral(tokenLiteral, decimals) {
29040
+ if (tokenLiteral === 'native') {
29041
+ return this.nativeToken;
29042
+ }
29043
+ return {
29044
+ type: 'erc20',
29045
+ address: tokenLiteral,
29046
+ chainId: this.chainId,
29047
+ decimals,
29048
+ };
29049
+ }
29050
+ async getUnsignedSwapTx(fromAddress, tokenInLiteral, tokenOutLiteral, amount, slippagePercent, maxHops, deadline, tradeType) {
29051
+ Exchange.validate(tokenInLiteral, tokenOutLiteral, maxHops, slippagePercent, fromAddress);
29010
29052
  // get the decimals of the tokens that will be swapped
29011
29053
  const [tokenInDecimals, tokenOutDecimals, secondaryFees] = await Promise.all([
29012
- getERC20Decimals(tokenInAddress, this.provider),
29013
- getERC20Decimals(tokenOutAddress, this.provider),
29054
+ getTokenDecimals(tokenInLiteral, this.provider, this.nativeToken),
29055
+ getTokenDecimals(tokenOutLiteral, this.provider, this.nativeToken),
29014
29056
  this.getSecondaryFees(),
29015
29057
  ]);
29016
- const tokenIn = {
29017
- type: 'erc20',
29018
- address: tokenInAddress,
29019
- chainId: this.chainId,
29020
- decimals: tokenInDecimals,
29021
- };
29022
- const tokenOut = {
29023
- type: 'erc20',
29024
- address: tokenOutAddress,
29025
- chainId: this.chainId,
29026
- decimals: tokenOutDecimals,
29027
- };
29058
+ const tokenIn = this.parseTokenLiteral(tokenInLiteral, tokenInDecimals);
29059
+ const tokenOut = this.parseTokenLiteral(tokenOutLiteral, tokenOutDecimals);
29028
29060
  // determine which amount was specified for the swap from the TradeType
29029
29061
  const [tokenSpecified, otherToken] = tradeType === Uniswap.TradeType.EXACT_INPUT ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
29030
29062
  const amountSpecified = newAmount(amount, tokenSpecified);
29031
29063
  const fees = new Fees(secondaryFees, tokenIn);
29032
29064
  const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
29033
- // get quote and gas details
29065
+ // Quotes will always use ERC20s. If the user-specified token is Native, we use the Wrapped Native Token pool
29034
29066
  const [ourQuote, gasPrice] = await Promise.all([
29035
- this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
29067
+ this.router.findOptimalRoute(ourQuoteReqAmount, this.nativeTokenService.maybeWrapToken(otherToken), tradeType, maxHops),
29036
29068
  fetchGasPrice(this.provider, this.nativeToken),
29037
29069
  ]);
29038
29070
  const adjustedQuote = adjustQuoteWithFees(ourQuote, amountSpecified, fees, this.nativeTokenService);
29039
29071
  const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.routerContractAddress, this.secondaryFeeContractAddress, gasPrice, secondaryFees, this.nativeTokenService);
29040
- const quotedAmount = getQuoteAmountFromTradeType(adjustedQuote);
29041
- const amountWithMaxSlippage = newAmount(applySlippage(adjustedQuote.tradeType, quotedAmount.value, slippagePercent), otherToken);
29042
- const preparedApproval = prepareApproval(tradeType, amountSpecified, amountWithMaxSlippage, {
29072
+ const { quotedAmount, quotedAmountWithMaxSlippage } = prepareUserQuote(this.nativeTokenService, adjustedQuote, slippagePercent, otherToken);
29073
+ const preparedApproval = prepareApproval(tradeType, amountSpecified, quotedAmountWithMaxSlippage, {
29043
29074
  routerAddress: this.routerContractAddress,
29044
29075
  secondaryFeeAddress: this.secondaryFeeContractAddress,
29045
29076
  }, secondaryFees);
29046
29077
  // preparedApproval always uses the tokenIn address because we are always selling the tokenIn
29047
- const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice);
29048
- const quote = toPublicQuote(quotedAmount, amountWithMaxSlippage, slippagePercent, fees);
29078
+ const approval = preparedApproval
29079
+ ? await getApproval(this.provider, fromAddress, preparedApproval, gasPrice)
29080
+ : null;
29081
+ const quote = toPublicQuote(quotedAmount, quotedAmountWithMaxSlippage, slippagePercent, fees);
29049
29082
  return { quote, approval, swap };
29050
29083
  }
29051
29084
  /**
29052
29085
  * Get the unsigned swap transaction given the amount to sell.
29053
29086
  * Includes quote details for the swap.
29054
29087
  *
29055
- * @param {string} fromAddress The public address that will sign and submit the transaction.
29056
- * @param {string} tokenInAddress Token address to sell.
29057
- * @param {string} tokenOutAddress Token address to buy.
29058
- * @param {ethers.BigNumberish} amountIn Amount to sell.
29059
- * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0.
29060
- * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2.
29061
- * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes.
29062
- * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap.
29088
+ * @param {string} fromAddress The public address that will sign and submit the transaction
29089
+ * @param {string} tokenInAddress Token address or 'native' to sell
29090
+ * @param {string} tokenOutAddress Token address or 'native' to buy
29091
+ * @param {ethers.BigNumberish} amountIn Amount to sell in the smallest unit of the token-in
29092
+ * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
29093
+ * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
29094
+ * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
29095
+ * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap
29063
29096
  */
29064
29097
  async getUnsignedSwapTxFromAmountIn(fromAddress, tokenInAddress, tokenOutAddress, amountIn, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
29065
29098
  return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.ethers.BigNumber.from(amountIn), slippagePercent, maxHops, deadline, Uniswap.TradeType.EXACT_INPUT);
@@ -29068,14 +29101,14 @@ class Exchange {
29068
29101
  * Get the unsigned swap transaction given the amount to buy.
29069
29102
  * Includes quote details for the swap.
29070
29103
  *
29071
- * @param {string} fromAddress The public address that will sign and submit the transaction.
29072
- * @param {string} tokenInAddress Token address to sell.
29073
- * @param {string} tokenOutAddress Token address to buy.
29074
- * @param {ethers.BigNumberish} amountOut Amount to buy.
29075
- * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0.
29076
- * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2.
29077
- * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes.
29078
- * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap.
29104
+ * @param {string} fromAddress The public address that will sign and submit the transaction
29105
+ * @param {string} tokenInAddress ERC20 contract address or 'native' to sell
29106
+ * @param {string} tokenOutAddress ERC20 contract address or 'native' to buy
29107
+ * @param {ethers.BigNumberish} amountOut Amount to buy in the smallest unit of the token-out
29108
+ * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
29109
+ * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
29110
+ * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
29111
+ * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap
29079
29112
  */
29080
29113
  async getUnsignedSwapTxFromAmountOut(fromAddress, tokenInAddress, tokenOutAddress, amountOut, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
29081
29114
  return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.ethers.BigNumber.from(amountOut), slippagePercent, maxHops, deadline, Uniswap.TradeType.EXACT_OUTPUT);
@@ -29319,6 +29352,14 @@ const $d85ad1457a3f1a83$export$fc55ed5a42b458ba = {
29319
29352
  [($0472f23319457bfb$export$c06e1e7429de6283).IMTBL_ZKEVM_MAINNET]: {
29320
29353
  url: "https://explorer.mainnet.immutable.com",
29321
29354
  nativeToken: $d85ad1457a3f1a83$export$6f24f3cef7d501c4.get(($0472f23319457bfb$export$c06e1e7429de6283).IMTBL_ZKEVM_MAINNET).nativeCurrency
29355
+ },
29356
+ [($0472f23319457bfb$export$c06e1e7429de6283).SEPOLIA]: {
29357
+ url: "https://eth-sepolia.blockscout.com",
29358
+ nativeToken: $d85ad1457a3f1a83$export$3e81fc0987227f10.get(($0472f23319457bfb$export$c06e1e7429de6283).SEPOLIA).nativeCurrency
29359
+ },
29360
+ [($0472f23319457bfb$export$c06e1e7429de6283).ETHEREUM]: {
29361
+ url: "https://eth.blockscout.com/",
29362
+ nativeToken: $d85ad1457a3f1a83$export$6f24f3cef7d501c4.get(($0472f23319457bfb$export$c06e1e7429de6283).ETHEREUM).nativeCurrency
29322
29363
  }
29323
29364
  };
29324
29365
  const $d85ad1457a3f1a83$export$db5daa1b5156ccfe = [
@@ -29918,6 +29959,7 @@ const $efe60cea83bfc4e8$export$473cec51305fdae8 = async (config, { type: type =
29918
29959
 
29919
29960
 
29920
29961
 
29962
+
29921
29963
  const $fd8a8472dcc3ec2b$var$CACHE_DATA_TTL = 60; // seconds
29922
29964
  class $fd8a8472dcc3ec2b$export$ef140a6b05dfc786 {
29923
29965
  url;
@@ -30090,18 +30132,23 @@ async function $1564e43dde50bb61$export$60e0fe116a0e6ed0(web3Provider, walletAdd
30090
30132
  type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_ERC20_BALANCE_ERROR
30091
30133
  });
30092
30134
  }
30093
- // Blockscout client singleton
30094
- let $1564e43dde50bb61$var$blockscoutClient;
30095
- const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId, rename)=>{
30135
+ // Blockscout client singleton per chain id
30136
+ const $1564e43dde50bb61$var$blockscoutClientMap = new Map();
30137
+ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId, filterTokens)=>{
30096
30138
  // Shuffle the mapping of the tokens configuration so it is a hashmap
30097
30139
  // for faster access to tokens config objects.
30098
- const mapRename = Object.assign({}, ...rename.map((t)=>({
30140
+ const shouldFilter = filterTokens.length > 0;
30141
+ const mapFilterTokens = Object.assign({}, ...filterTokens.map((t)=>({
30099
30142
  [t.address || ""]: t
30100
30143
  })));
30101
- // Ensure singleton is present and match the selected chain
30102
- if (!$1564e43dde50bb61$var$blockscoutClient || $1564e43dde50bb61$var$blockscoutClient.chainId !== chainId) $1564e43dde50bb61$var$blockscoutClient = new ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786)({
30103
- chainId: chainId
30104
- });
30144
+ // Get blockscout client for the given chain
30145
+ let blockscoutClient = $1564e43dde50bb61$var$blockscoutClientMap.get(chainId);
30146
+ if (!blockscoutClient) {
30147
+ blockscoutClient = new ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786)({
30148
+ chainId: chainId
30149
+ });
30150
+ $1564e43dde50bb61$var$blockscoutClientMap.set(chainId, blockscoutClient);
30151
+ }
30105
30152
  // Hold the items in an array for post-fetching processing
30106
30153
  const items = [];
30107
30154
  const tokenType = ($887a00f8f72d61f0$export$5bd1ea2b3d18210).ERC20;
@@ -30111,7 +30158,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
30111
30158
  try {
30112
30159
  do {
30113
30160
  // eslint-disable-next-line no-await-in-loop
30114
- resp = await $1564e43dde50bb61$var$blockscoutClient.getTokensByWalletAddress({
30161
+ resp = await blockscoutClient.getTokensByWalletAddress({
30115
30162
  walletAddress: walletAddress,
30116
30163
  tokenType: tokenType,
30117
30164
  nextPage: resp?.next_page_params
@@ -30129,7 +30176,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
30129
30176
  if (err?.code !== (globalAxios$1.HttpStatusCode).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getTokensByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
30130
30177
  }
30131
30178
  try {
30132
- const respNative = await $1564e43dde50bb61$var$blockscoutClient.getNativeTokenByWalletAddress({
30179
+ const respNative = await blockscoutClient.getNativeTokenByWalletAddress({
30133
30180
  walletAddress: walletAddress
30134
30181
  });
30135
30182
  items.push(respNative);
@@ -30143,24 +30190,26 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
30143
30190
  // or simply an incorrect wallet address was provided.
30144
30191
  if (err?.code !== (globalAxios$1.HttpStatusCode).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getNativeTokenByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
30145
30192
  }
30193
+ const balances = [];
30194
+ items.forEach((item)=>{
30195
+ if (shouldFilter && !mapFilterTokens[item.token.address]) return;
30196
+ const tokenData = item.token || {};
30197
+ const balance = (ethers.BigNumber).from(item.value);
30198
+ let decimals = parseInt(tokenData.decimals, 10);
30199
+ if (Number.isNaN(decimals)) decimals = ($d85ad1457a3f1a83$export$903389470ba9433c);
30200
+ const token = {
30201
+ ...tokenData,
30202
+ decimals: decimals
30203
+ };
30204
+ const formattedBalance = (ethers.utils).formatUnits(item.value, token.decimals);
30205
+ balances.push({
30206
+ balance: balance,
30207
+ formattedBalance: formattedBalance,
30208
+ token: token
30209
+ });
30210
+ });
30146
30211
  return {
30147
- balances: items.map((item)=>{
30148
- const tokenData = item.token || {};
30149
- const balance = (ethers.BigNumber).from(item.value);
30150
- const renamed = mapRename[tokenData.address] || {};
30151
- const token = {
30152
- ...tokenData,
30153
- name: renamed.name ?? tokenData.name,
30154
- symbol: renamed.symbol ?? tokenData.symbol,
30155
- decimals: parseInt(tokenData.decimals, 10)
30156
- };
30157
- const formattedBalance = (ethers.utils).formatUnits(item.value, token.decimals);
30158
- return {
30159
- balance: balance,
30160
- formattedBalance: formattedBalance,
30161
- token: token
30162
- };
30163
- })
30212
+ balances: balances
30164
30213
  };
30165
30214
  };
30166
30215
  const $1564e43dde50bb61$export$a3238cee431627c6 = async (config, web3Provider, walletAddress, tokens)=>{
@@ -30191,7 +30240,15 @@ const $1564e43dde50bb61$export$fee49741664a4d7e = async (config, web3Provider, w
30191
30240
  // eslint-disable-next-line no-console
30192
30241
  console.error(err);
30193
30242
  }
30194
- if (flag && ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786).isChainSupported(chainId)) return await $1564e43dde50bb61$export$8c978679845804d4(walletAddress, chainId, tokens);
30243
+ if (flag && ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786).isChainSupported(chainId)) {
30244
+ // This is a hack because the widgets are still using the tokens symbol
30245
+ // to drive the conversions. If we remove all the token symbols from e.g. zkevm
30246
+ // then we would not have fiat conversions.
30247
+ // Please remove this hack once https://immutable.atlassian.net/browse/WT-1710
30248
+ // is done.
30249
+ const isL1Chain = ($4013c5c91bb535f6$export$9b794d067cdd1af6)(config) === chainId;
30250
+ return await $1564e43dde50bb61$export$8c978679845804d4(walletAddress, chainId, isL1Chain ? tokens : []);
30251
+ }
30195
30252
  // This fallback to use ERC20s calls which is a best effort solution
30196
30253
  // Fails in fetching data from the RCP calls might result in some
30197
30254
  // missing data.
@@ -33165,7 +33222,7 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
33165
33222
  const tokenList = await $efe60cea83bfc4e8$export$473cec51305fdae8(this.config, {
33166
33223
  type: ($08d5ddc39acd6833$export$fd9b17d87f4121d2).ONRAMP
33167
33224
  });
33168
- const token = tokenList.tokens.find((t)=>t.address?.toLowerCase() === params.tokenAddress?.toLowerCase());
33225
+ const token = tokenList.tokens?.find((t)=>t.address?.toLowerCase() === params.tokenAddress?.toLowerCase());
33169
33226
  if (token) {
33170
33227
  tokenAmount = params.tokenAmount;
33171
33228
  tokenSymbol = token.symbol;
@@ -33238,7 +33295,7 @@ var $045213b18e9f1f94$export$75be0f6af9650f2c;
33238
33295
  })($045213b18e9f1f94$export$75be0f6af9650f2c || ($045213b18e9f1f94$export$75be0f6af9650f2c = {}));
33239
33296
 
33240
33297
 
33241
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.10";
33298
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.11";
33242
33299
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
33243
33300
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
33244
33301
 
@@ -33372,7 +33429,7 @@ var $207ed853f11d19d5$export$5a0ace85cae72d45;
33372
33429
  IMTBLWidgetEvents["IMTBL_SWAP_WIDGET_EVENT"] = "imtbl-swap-widget";
33373
33430
  IMTBLWidgetEvents["IMTBL_BRIDGE_WIDGET_EVENT"] = "imtbl-bridge-widget";
33374
33431
  IMTBLWidgetEvents["IMTBL_ONRAMP_WIDGET_EVENT"] = "imtbl-onramp-widget";
33375
- IMTBLWidgetEvents["IMTBL_PRIMARY_REVENUE_WIDGET_EVENT"] = "imtbl-sale-widget";
33432
+ IMTBLWidgetEvents["IMTBL_SALE_WIDGET_EVENT"] = "imtbl-sale-widget";
33376
33433
  })($207ed853f11d19d5$export$5a0ace85cae72d45 || ($207ed853f11d19d5$export$5a0ace85cae72d45 = {}));
33377
33434
 
33378
33435
 
package/dist/index.d.ts CHANGED
@@ -32410,7 +32410,7 @@ declare enum IMTBLWidgetEvents {
32410
32410
  IMTBL_SWAP_WIDGET_EVENT = "imtbl-swap-widget",
32411
32411
  IMTBL_BRIDGE_WIDGET_EVENT = "imtbl-bridge-widget",
32412
32412
  IMTBL_ONRAMP_WIDGET_EVENT = "imtbl-onramp-widget",
32413
- IMTBL_PRIMARY_REVENUE_WIDGET_EVENT = "imtbl-sale-widget"
32413
+ IMTBL_SALE_WIDGET_EVENT = "imtbl-sale-widget"
32414
32414
  }
32415
32415
  /**
32416
32416
  * Represents an event emitted by a widget.