@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.
@@ -14685,8 +14685,11 @@ function poolEquals(poolA, poolB) {
14685
14685
  return (poolA === poolB ||
14686
14686
  (poolA.token0.equals(poolB.token0) && poolA.token1.equals(poolB.token1) && poolA.fee === poolB.fee));
14687
14687
  }
14688
- async function getERC20Decimals(tokenAddress, provider) {
14689
- const decimalsFunctionSig = ethers.utils.id('decimals()').substring(0, 10);
14688
+ const decimalsFunctionSig = ethers.utils.id('decimals()').substring(0, 10);
14689
+ async function getTokenDecimals(tokenAddress, provider, nativeToken) {
14690
+ if (tokenAddress === 'native') {
14691
+ return nativeToken.decimals;
14692
+ }
14690
14693
  try {
14691
14694
  const decimalsResult = await provider.call({
14692
14695
  to: tokenAddress,
@@ -14714,6 +14717,7 @@ function isValidNonZeroAddress(address) {
14714
14717
  return false;
14715
14718
  }
14716
14719
  }
14720
+ const isValidTokenLiteral = (address) => address === 'native' ? true : isValidNonZeroAddress(address);
14717
14721
  const erc20ToUniswapToken = (token) =>
14718
14722
  // eslint-disable-next-line implicit-arrow-linebreak
14719
14723
  new Uniswap.Token(token.chainId, token.address, token.decimals, token.symbol, token.name);
@@ -15168,12 +15172,13 @@ const getUnsignedERC20ApproveTransaction = (ownerAddress, tokenAmount, spenderAd
15168
15172
  from: ownerAddress,
15169
15173
  };
15170
15174
  };
15171
- const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, contracts, secondaryFees) => {
15172
- const amountOfTokenIn = tradeType === TradeType.EXACT_INPUT ? amountSpecified : amountWithSlippage;
15173
- const spender = secondaryFees.length === 0
15174
- ? contracts.routerAddress
15175
- : contracts.secondaryFeeAddress;
15176
- return { spender, amount: amountOfTokenIn };
15175
+ const prepareApproval = (tradeType, userSpecifiedAmount, quotedAmountWithSlippage, contracts, secondaryFees) => {
15176
+ const amountInToApprove = tradeType === TradeType.EXACT_INPUT ? userSpecifiedAmount : quotedAmountWithSlippage;
15177
+ if (!isERC20Amount(amountInToApprove)) {
15178
+ return null;
15179
+ }
15180
+ const spender = secondaryFees.length === 0 ? contracts.routerAddress : contracts.secondaryFeeAddress;
15181
+ return { spender, amount: amountInToApprove };
15177
15182
  };
15178
15183
  /**
15179
15184
  * Get an unsigned approval transaction if needed
@@ -15218,6 +15223,38 @@ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) =
15218
15223
  };
15219
15224
  };
15220
15225
 
15226
+ const canUnwrapToken = (token) => token.type === 'native';
15227
+ class NativeTokenService {
15228
+ nativeToken;
15229
+ wrappedToken;
15230
+ constructor(nativeToken, wrappedToken) {
15231
+ this.nativeToken = nativeToken;
15232
+ this.wrappedToken = wrappedToken;
15233
+ }
15234
+ wrapAmount(amount) {
15235
+ if (!canUnwrapToken(amount.token)) {
15236
+ throw new Error(`cannot wrap non-native token: ${amount.token.address}`);
15237
+ }
15238
+ return newAmount(amount.value, this.wrappedToken);
15239
+ }
15240
+ unwrapAmount(amount) {
15241
+ const isWrappedToken = amount.token.address.toLowerCase() !== this.wrappedToken.address.toLowerCase();
15242
+ if (isWrappedToken) {
15243
+ throw new Error(`cannot unwrap non-wrapped token ${amount.token.address}`);
15244
+ }
15245
+ return newAmount(amount.value, this.nativeToken);
15246
+ }
15247
+ maybeWrapToken(token) {
15248
+ if (canUnwrapToken(token)) {
15249
+ return this.wrappedToken;
15250
+ }
15251
+ return token;
15252
+ }
15253
+ maybeWrapAmount(amount) {
15254
+ return newAmount(amount.value, this.maybeWrapToken(amount.token));
15255
+ }
15256
+ }
15257
+
15221
15258
  // slippageToPercent takes the slippage as a percentage (e.g. 0.1) and
15222
15259
  // converts it to the Uniswap equivalent type
15223
15260
  const slippageToFraction = (slippage) => {
@@ -15237,11 +15274,11 @@ const slippageToFraction = (slippage) => {
15237
15274
  return new Percent(numerator, denominator);
15238
15275
  };
15239
15276
 
15240
- function getQuoteAmountFromTradeType(tradeInfo) {
15241
- if (tradeInfo.tradeType === TradeType.EXACT_INPUT) {
15242
- return tradeInfo.amountOut;
15277
+ function getQuoteAmountFromTradeType(routerQuote) {
15278
+ if (routerQuote.tradeType === TradeType.EXACT_INPUT) {
15279
+ return routerQuote.amountOut;
15243
15280
  }
15244
- return tradeInfo.amountIn;
15281
+ return routerQuote.amountIn;
15245
15282
  }
15246
15283
  function applySlippage(tradeType, amount, slippage) {
15247
15284
  const slippageTolerance = slippageToFraction(slippage);
@@ -15250,6 +15287,18 @@ function applySlippage(tradeType, amount, slippage) {
15250
15287
  const amountWithSlippage = maybeInverted.multiply(amount.toString()).quotient;
15251
15288
  return ethers.BigNumber.from(amountWithSlippage.toString());
15252
15289
  }
15290
+ const prepareUserQuote = (nativeTokenService, routerQuote, slippage, tokenOfQuotedAmount) => {
15291
+ const erc20QuoteAmount = getQuoteAmountFromTradeType(routerQuote);
15292
+ // If the quote amount is the native token, we need to unwrap it if the user originally specified the native token
15293
+ const quotedAmount = canUnwrapToken(tokenOfQuotedAmount)
15294
+ ? nativeTokenService.unwrapAmount(erc20QuoteAmount)
15295
+ : erc20QuoteAmount;
15296
+ const quotedAmountWithMaxSlippage = newAmount(applySlippage(routerQuote.tradeType, quotedAmount.value, slippage), tokenOfQuotedAmount);
15297
+ return {
15298
+ quotedAmount,
15299
+ quotedAmountWithMaxSlippage,
15300
+ };
15301
+ };
15253
15302
  function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
15254
15303
  fees, tradeType, nativeTokenService) {
15255
15304
  if (tradeType === TradeType.EXACT_OUTPUT) {
@@ -15317,39 +15366,6 @@ class Fees {
15317
15366
  }
15318
15367
  }
15319
15368
 
15320
- class NativeTokenService {
15321
- nativeToken;
15322
- wrappedToken;
15323
- constructor(nativeToken, wrappedToken) {
15324
- this.nativeToken = nativeToken;
15325
- this.wrappedToken = wrappedToken;
15326
- }
15327
- wrapAmount(amount) {
15328
- if (!this.isNativeToken(amount.token)) {
15329
- throw new Error(`cannot wrap non-native token: ${amount.token.address}`);
15330
- }
15331
- return newAmount(amount.value, this.wrappedToken);
15332
- }
15333
- unwrapAmount(amount) {
15334
- if (amount.token !== this.wrappedToken) {
15335
- throw new Error(`cannot unwrap non-wrapped token ${amount.token.address}`);
15336
- }
15337
- return newAmount(amount.value, this.nativeToken);
15338
- }
15339
- maybeWrapToken(token) {
15340
- if (this.isNativeToken(token)) {
15341
- return this.wrappedToken;
15342
- }
15343
- return token;
15344
- }
15345
- maybeWrapAmount(amount) {
15346
- return newAmount(amount.value, this.maybeWrapToken(amount.token));
15347
- }
15348
- isNativeToken(token) {
15349
- return token === this.nativeToken;
15350
- }
15351
- }
15352
-
15353
15369
  const IMMUTABLE_TESTNET_RPC_URL = 'https://rpc.testnet.immutable.com';
15354
15370
  const IMMUTABLE_TESTNET_CHAIN_ID = 13472;
15355
15371
  const TIMX_IMMUTABLE_TESTNET = {
@@ -15381,7 +15397,9 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
15381
15397
  recipient: fee.recipient,
15382
15398
  }));
15383
15399
  if (trade.tradeType === TradeType.EXACT_INPUT) {
15384
- return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [secondaryFeeValues, {
15400
+ return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [
15401
+ secondaryFeeValues,
15402
+ {
15385
15403
  tokenIn: route.tokenPath[0].address,
15386
15404
  tokenOut: route.tokenPath[1].address,
15387
15405
  fee: route.pools[0].fee,
@@ -15389,9 +15407,12 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
15389
15407
  amountIn,
15390
15408
  amountOutMinimum: amountOut,
15391
15409
  sqrtPriceLimitX96: 0,
15392
- }]);
15410
+ },
15411
+ ]);
15393
15412
  }
15394
- return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [secondaryFeeValues, {
15413
+ return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [
15414
+ secondaryFeeValues,
15415
+ {
15395
15416
  tokenIn: route.tokenPath[0].address,
15396
15417
  tokenOut: route.tokenPath[1].address,
15397
15418
  fee: route.pools[0].fee,
@@ -15399,7 +15420,8 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
15399
15420
  amountInMaximum: amountIn,
15400
15421
  amountOut,
15401
15422
  sqrtPriceLimitX96: 0,
15402
- }]);
15423
+ },
15424
+ ]);
15403
15425
  }
15404
15426
  function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract) {
15405
15427
  const path = encodeRouteToPath(route, trade.tradeType === TradeType.EXACT_OUTPUT);
@@ -15408,19 +15430,25 @@ function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn
15408
15430
  recipient: fee.recipient,
15409
15431
  }));
15410
15432
  if (trade.tradeType === TradeType.EXACT_INPUT) {
15411
- return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [secondaryFeeValues, {
15433
+ return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [
15434
+ secondaryFeeValues,
15435
+ {
15412
15436
  path,
15413
15437
  recipient: fromAddress,
15414
15438
  amountIn,
15415
15439
  amountOutMinimum: amountOut,
15416
- }]);
15440
+ },
15441
+ ]);
15417
15442
  }
15418
- return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [secondaryFeeValues, {
15443
+ return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [
15444
+ secondaryFeeValues,
15445
+ {
15419
15446
  path,
15420
15447
  recipient: fromAddress,
15421
15448
  amountInMaximum: amountIn,
15422
15449
  amountOut,
15423
- }]);
15450
+ },
15451
+ ]);
15424
15452
  }
15425
15453
  /**
15426
15454
  * Builds swap parameters
@@ -15445,7 +15473,10 @@ function buildSwapParameters(fromAddress, trade, options, secondaryFees, seconda
15445
15473
  function createSwapCallParametersWithFees(trade, fromAddress, swapOptions, secondaryFees) {
15446
15474
  const secondaryFeeContract = SecondaryFee__factory.createInterface();
15447
15475
  const swapWithFeesCalldata = buildSwapParameters(fromAddress, trade, swapOptions, secondaryFees, secondaryFeeContract);
15448
- return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [swapOptions.deadlineOrPreviousBlockhash, [swapWithFeesCalldata]]);
15476
+ return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [
15477
+ swapOptions.deadlineOrPreviousBlockhash,
15478
+ [swapWithFeesCalldata],
15479
+ ]);
15449
15480
  }
15450
15481
  function createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, secondaryFees) {
15451
15482
  // Create an unchecked trade to be used in generating swap parameters.
@@ -15485,7 +15516,7 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
15485
15516
  const adjustAmountIn = (ourQuote, amountSpecified, fees, nativeTokenService) => {
15486
15517
  if (ourQuote.tradeType === TradeType.EXACT_OUTPUT) {
15487
15518
  // when doing exact output, calculate the fees based on the amountIn
15488
- const amountToAdd = nativeTokenService.isNativeToken(fees.token)
15519
+ const amountToAdd = canUnwrapToken(fees.token)
15489
15520
  ? nativeTokenService.unwrapAmount(ourQuote.amountIn)
15490
15521
  : ourQuote.amountIn;
15491
15522
  fees.addAmount(amountToAdd);
@@ -15602,8 +15633,8 @@ class ExchangeConfiguration {
15602
15633
  }
15603
15634
 
15604
15635
  const toPublicQuote = (amount, amountWithMaxSlippage, slippage, fees) => ({
15605
- amount,
15606
- amountWithMaxSlippage,
15636
+ amount: toPublicAmount(amount),
15637
+ amountWithMaxSlippage: toPublicAmount(amountWithMaxSlippage),
15607
15638
  slippage,
15608
15639
  fees: fees.withAmounts().map((fee) => ({
15609
15640
  ...fee,
@@ -15638,8 +15669,8 @@ class Exchange {
15638
15669
  }
15639
15670
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
15640
15671
  assert(isValidNonZeroAddress(fromAddress), new InvalidAddressError('invalid from address'));
15641
- assert(isValidNonZeroAddress(tokenInAddress), new InvalidAddressError('invalid token in address'));
15642
- assert(isValidNonZeroAddress(tokenOutAddress), new InvalidAddressError('invalid token out address'));
15672
+ assert(isValidTokenLiteral(tokenInAddress), new InvalidAddressError('invalid token in address'));
15673
+ assert(isValidTokenLiteral(tokenOutAddress), new InvalidAddressError('invalid token out address'));
15643
15674
  assert(tokenInAddress.toLocaleLowerCase() !== tokenOutAddress.toLocaleLowerCase(), new DuplicateAddressesError());
15644
15675
  assert(maxHops <= MAX_MAX_HOPS, new InvalidMaxHopsError('max hops must be less than or equal to 10'));
15645
15676
  assert(maxHops >= MIN_MAX_HOPS, new InvalidMaxHopsError('max hops must be greater than or equal to 1'));
@@ -15657,61 +15688,63 @@ class Exchange {
15657
15688
  }
15658
15689
  return this.secondaryFees;
15659
15690
  }
15660
- async getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, amount, slippagePercent, maxHops, deadline, tradeType) {
15661
- Exchange.validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress);
15691
+ parseTokenLiteral(tokenLiteral, decimals) {
15692
+ if (tokenLiteral === 'native') {
15693
+ return this.nativeToken;
15694
+ }
15695
+ return {
15696
+ type: 'erc20',
15697
+ address: tokenLiteral,
15698
+ chainId: this.chainId,
15699
+ decimals,
15700
+ };
15701
+ }
15702
+ async getUnsignedSwapTx(fromAddress, tokenInLiteral, tokenOutLiteral, amount, slippagePercent, maxHops, deadline, tradeType) {
15703
+ Exchange.validate(tokenInLiteral, tokenOutLiteral, maxHops, slippagePercent, fromAddress);
15662
15704
  // get the decimals of the tokens that will be swapped
15663
15705
  const [tokenInDecimals, tokenOutDecimals, secondaryFees] = await Promise.all([
15664
- getERC20Decimals(tokenInAddress, this.provider),
15665
- getERC20Decimals(tokenOutAddress, this.provider),
15706
+ getTokenDecimals(tokenInLiteral, this.provider, this.nativeToken),
15707
+ getTokenDecimals(tokenOutLiteral, this.provider, this.nativeToken),
15666
15708
  this.getSecondaryFees(),
15667
15709
  ]);
15668
- const tokenIn = {
15669
- type: 'erc20',
15670
- address: tokenInAddress,
15671
- chainId: this.chainId,
15672
- decimals: tokenInDecimals,
15673
- };
15674
- const tokenOut = {
15675
- type: 'erc20',
15676
- address: tokenOutAddress,
15677
- chainId: this.chainId,
15678
- decimals: tokenOutDecimals,
15679
- };
15710
+ const tokenIn = this.parseTokenLiteral(tokenInLiteral, tokenInDecimals);
15711
+ const tokenOut = this.parseTokenLiteral(tokenOutLiteral, tokenOutDecimals);
15680
15712
  // determine which amount was specified for the swap from the TradeType
15681
15713
  const [tokenSpecified, otherToken] = tradeType === TradeType.EXACT_INPUT ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
15682
15714
  const amountSpecified = newAmount(amount, tokenSpecified);
15683
15715
  const fees = new Fees(secondaryFees, tokenIn);
15684
15716
  const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
15685
- // get quote and gas details
15717
+ // Quotes will always use ERC20s. If the user-specified token is Native, we use the Wrapped Native Token pool
15686
15718
  const [ourQuote, gasPrice] = await Promise.all([
15687
- this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
15719
+ this.router.findOptimalRoute(ourQuoteReqAmount, this.nativeTokenService.maybeWrapToken(otherToken), tradeType, maxHops),
15688
15720
  fetchGasPrice(this.provider, this.nativeToken),
15689
15721
  ]);
15690
15722
  const adjustedQuote = adjustQuoteWithFees(ourQuote, amountSpecified, fees, this.nativeTokenService);
15691
15723
  const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.routerContractAddress, this.secondaryFeeContractAddress, gasPrice, secondaryFees, this.nativeTokenService);
15692
- const quotedAmount = getQuoteAmountFromTradeType(adjustedQuote);
15693
- const amountWithMaxSlippage = newAmount(applySlippage(adjustedQuote.tradeType, quotedAmount.value, slippagePercent), otherToken);
15694
- const preparedApproval = prepareApproval(tradeType, amountSpecified, amountWithMaxSlippage, {
15724
+ const { quotedAmount, quotedAmountWithMaxSlippage } = prepareUserQuote(this.nativeTokenService, adjustedQuote, slippagePercent, otherToken);
15725
+ const preparedApproval = prepareApproval(tradeType, amountSpecified, quotedAmountWithMaxSlippage, {
15695
15726
  routerAddress: this.routerContractAddress,
15696
15727
  secondaryFeeAddress: this.secondaryFeeContractAddress,
15697
15728
  }, secondaryFees);
15698
15729
  // preparedApproval always uses the tokenIn address because we are always selling the tokenIn
15699
- const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice);
15700
- const quote = toPublicQuote(quotedAmount, amountWithMaxSlippage, slippagePercent, fees);
15730
+ const approval = preparedApproval
15731
+ ? await getApproval(this.provider, fromAddress, preparedApproval, gasPrice)
15732
+ : null;
15733
+ const quote = toPublicQuote(quotedAmount, quotedAmountWithMaxSlippage, slippagePercent, fees);
15701
15734
  return { quote, approval, swap };
15702
15735
  }
15703
15736
  /**
15704
15737
  * Get the unsigned swap transaction given the amount to sell.
15705
15738
  * Includes quote details for the swap.
15706
15739
  *
15707
- * @param {string} fromAddress The public address that will sign and submit the transaction.
15708
- * @param {string} tokenInAddress Token address to sell.
15709
- * @param {string} tokenOutAddress Token address to buy.
15710
- * @param {ethers.BigNumberish} amountIn Amount to sell.
15711
- * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0.
15712
- * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2.
15713
- * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes.
15714
- * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap.
15740
+ * @param {string} fromAddress The public address that will sign and submit the transaction
15741
+ * @param {string} tokenInAddress Token address or 'native' to sell
15742
+ * @param {string} tokenOutAddress Token address or 'native' to buy
15743
+ * @param {ethers.BigNumberish} amountIn Amount to sell in the smallest unit of the token-in
15744
+ * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
15745
+ * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
15746
+ * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
15747
+ * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap
15715
15748
  */
15716
15749
  async getUnsignedSwapTxFromAmountIn(fromAddress, tokenInAddress, tokenOutAddress, amountIn, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
15717
15750
  return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.BigNumber.from(amountIn), slippagePercent, maxHops, deadline, TradeType.EXACT_INPUT);
@@ -15720,14 +15753,14 @@ class Exchange {
15720
15753
  * Get the unsigned swap transaction given the amount to buy.
15721
15754
  * Includes quote details for the swap.
15722
15755
  *
15723
- * @param {string} fromAddress The public address that will sign and submit the transaction.
15724
- * @param {string} tokenInAddress Token address to sell.
15725
- * @param {string} tokenOutAddress Token address to buy.
15726
- * @param {ethers.BigNumberish} amountOut Amount to buy.
15727
- * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0.
15728
- * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2.
15729
- * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes.
15730
- * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap.
15756
+ * @param {string} fromAddress The public address that will sign and submit the transaction
15757
+ * @param {string} tokenInAddress ERC20 contract address or 'native' to sell
15758
+ * @param {string} tokenOutAddress ERC20 contract address or 'native' to buy
15759
+ * @param {ethers.BigNumberish} amountOut Amount to buy in the smallest unit of the token-out
15760
+ * @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
15761
+ * @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
15762
+ * @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
15763
+ * @return {TransactionResponse} The result containing the unsigned transaction and details of the swap
15731
15764
  */
15732
15765
  async getUnsignedSwapTxFromAmountOut(fromAddress, tokenInAddress, tokenOutAddress, amountOut, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
15733
15766
  return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.BigNumber.from(amountOut), slippagePercent, maxHops, deadline, TradeType.EXACT_OUTPUT);
@@ -20554,7 +20587,7 @@ class APIError extends Error {
20554
20587
 
20555
20588
  /* eslint-disable implicit-arrow-linebreak */
20556
20589
  const defaultHeaders = {
20557
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.10',
20590
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.11',
20558
20591
  };
20559
20592
  /**
20560
20593
  * createAPIConfiguration to create a custom Configuration
@@ -21180,6 +21213,14 @@ const $d85ad1457a3f1a83$export$fc55ed5a42b458ba = {
21180
21213
  [($0472f23319457bfb$export$c06e1e7429de6283).IMTBL_ZKEVM_MAINNET]: {
21181
21214
  url: "https://explorer.mainnet.immutable.com",
21182
21215
  nativeToken: $d85ad1457a3f1a83$export$6f24f3cef7d501c4.get(($0472f23319457bfb$export$c06e1e7429de6283).IMTBL_ZKEVM_MAINNET).nativeCurrency
21216
+ },
21217
+ [($0472f23319457bfb$export$c06e1e7429de6283).SEPOLIA]: {
21218
+ url: "https://eth-sepolia.blockscout.com",
21219
+ nativeToken: $d85ad1457a3f1a83$export$3e81fc0987227f10.get(($0472f23319457bfb$export$c06e1e7429de6283).SEPOLIA).nativeCurrency
21220
+ },
21221
+ [($0472f23319457bfb$export$c06e1e7429de6283).ETHEREUM]: {
21222
+ url: "https://eth.blockscout.com/",
21223
+ nativeToken: $d85ad1457a3f1a83$export$6f24f3cef7d501c4.get(($0472f23319457bfb$export$c06e1e7429de6283).ETHEREUM).nativeCurrency
21183
21224
  }
21184
21225
  };
21185
21226
  const $d85ad1457a3f1a83$export$db5daa1b5156ccfe = [
@@ -21779,6 +21820,7 @@ const $efe60cea83bfc4e8$export$473cec51305fdae8 = async (config, { type: type =
21779
21820
 
21780
21821
 
21781
21822
 
21823
+
21782
21824
  const $fd8a8472dcc3ec2b$var$CACHE_DATA_TTL = 60; // seconds
21783
21825
  class $fd8a8472dcc3ec2b$export$ef140a6b05dfc786 {
21784
21826
  url;
@@ -21951,18 +21993,23 @@ async function $1564e43dde50bb61$export$60e0fe116a0e6ed0(web3Provider, walletAdd
21951
21993
  type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_ERC20_BALANCE_ERROR
21952
21994
  });
21953
21995
  }
21954
- // Blockscout client singleton
21955
- let $1564e43dde50bb61$var$blockscoutClient;
21956
- const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId, rename)=>{
21996
+ // Blockscout client singleton per chain id
21997
+ const $1564e43dde50bb61$var$blockscoutClientMap = new Map();
21998
+ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId, filterTokens)=>{
21957
21999
  // Shuffle the mapping of the tokens configuration so it is a hashmap
21958
22000
  // for faster access to tokens config objects.
21959
- const mapRename = Object.assign({}, ...rename.map((t)=>({
22001
+ const shouldFilter = filterTokens.length > 0;
22002
+ const mapFilterTokens = Object.assign({}, ...filterTokens.map((t)=>({
21960
22003
  [t.address || ""]: t
21961
22004
  })));
21962
- // Ensure singleton is present and match the selected chain
21963
- if (!$1564e43dde50bb61$var$blockscoutClient || $1564e43dde50bb61$var$blockscoutClient.chainId !== chainId) $1564e43dde50bb61$var$blockscoutClient = new ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786)({
21964
- chainId: chainId
21965
- });
22005
+ // Get blockscout client for the given chain
22006
+ let blockscoutClient = $1564e43dde50bb61$var$blockscoutClientMap.get(chainId);
22007
+ if (!blockscoutClient) {
22008
+ blockscoutClient = new ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786)({
22009
+ chainId: chainId
22010
+ });
22011
+ $1564e43dde50bb61$var$blockscoutClientMap.set(chainId, blockscoutClient);
22012
+ }
21966
22013
  // Hold the items in an array for post-fetching processing
21967
22014
  const items = [];
21968
22015
  const tokenType = ($887a00f8f72d61f0$export$5bd1ea2b3d18210).ERC20;
@@ -21972,7 +22019,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
21972
22019
  try {
21973
22020
  do {
21974
22021
  // eslint-disable-next-line no-await-in-loop
21975
- resp = await $1564e43dde50bb61$var$blockscoutClient.getTokensByWalletAddress({
22022
+ resp = await blockscoutClient.getTokensByWalletAddress({
21976
22023
  walletAddress: walletAddress,
21977
22024
  tokenType: tokenType,
21978
22025
  nextPage: resp?.next_page_params
@@ -21990,7 +22037,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
21990
22037
  if (err?.code !== (HttpStatusCode).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getTokensByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
21991
22038
  }
21992
22039
  try {
21993
- const respNative = await $1564e43dde50bb61$var$blockscoutClient.getNativeTokenByWalletAddress({
22040
+ const respNative = await blockscoutClient.getNativeTokenByWalletAddress({
21994
22041
  walletAddress: walletAddress
21995
22042
  });
21996
22043
  items.push(respNative);
@@ -22004,24 +22051,26 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
22004
22051
  // or simply an incorrect wallet address was provided.
22005
22052
  if (err?.code !== (HttpStatusCode).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getNativeTokenByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
22006
22053
  }
22054
+ const balances = [];
22055
+ items.forEach((item)=>{
22056
+ if (shouldFilter && !mapFilterTokens[item.token.address]) return;
22057
+ const tokenData = item.token || {};
22058
+ const balance = (BigNumber$1).from(item.value);
22059
+ let decimals = parseInt(tokenData.decimals, 10);
22060
+ if (Number.isNaN(decimals)) decimals = ($d85ad1457a3f1a83$export$903389470ba9433c);
22061
+ const token = {
22062
+ ...tokenData,
22063
+ decimals: decimals
22064
+ };
22065
+ const formattedBalance = (utils).formatUnits(item.value, token.decimals);
22066
+ balances.push({
22067
+ balance: balance,
22068
+ formattedBalance: formattedBalance,
22069
+ token: token
22070
+ });
22071
+ });
22007
22072
  return {
22008
- balances: items.map((item)=>{
22009
- const tokenData = item.token || {};
22010
- const balance = (BigNumber$1).from(item.value);
22011
- const renamed = mapRename[tokenData.address] || {};
22012
- const token = {
22013
- ...tokenData,
22014
- name: renamed.name ?? tokenData.name,
22015
- symbol: renamed.symbol ?? tokenData.symbol,
22016
- decimals: parseInt(tokenData.decimals, 10)
22017
- };
22018
- const formattedBalance = (utils).formatUnits(item.value, token.decimals);
22019
- return {
22020
- balance: balance,
22021
- formattedBalance: formattedBalance,
22022
- token: token
22023
- };
22024
- })
22073
+ balances: balances
22025
22074
  };
22026
22075
  };
22027
22076
  const $1564e43dde50bb61$export$a3238cee431627c6 = async (config, web3Provider, walletAddress, tokens)=>{
@@ -22052,7 +22101,15 @@ const $1564e43dde50bb61$export$fee49741664a4d7e = async (config, web3Provider, w
22052
22101
  // eslint-disable-next-line no-console
22053
22102
  console.error(err);
22054
22103
  }
22055
- if (flag && ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786).isChainSupported(chainId)) return await $1564e43dde50bb61$export$8c978679845804d4(walletAddress, chainId, tokens);
22104
+ if (flag && ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786).isChainSupported(chainId)) {
22105
+ // This is a hack because the widgets are still using the tokens symbol
22106
+ // to drive the conversions. If we remove all the token symbols from e.g. zkevm
22107
+ // then we would not have fiat conversions.
22108
+ // Please remove this hack once https://immutable.atlassian.net/browse/WT-1710
22109
+ // is done.
22110
+ const isL1Chain = ($4013c5c91bb535f6$export$9b794d067cdd1af6)(config) === chainId;
22111
+ return await $1564e43dde50bb61$export$8c978679845804d4(walletAddress, chainId, isL1Chain ? tokens : []);
22112
+ }
22056
22113
  // This fallback to use ERC20s calls which is a best effort solution
22057
22114
  // Fails in fetching data from the RCP calls might result in some
22058
22115
  // missing data.
@@ -25026,7 +25083,7 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
25026
25083
  const tokenList = await $efe60cea83bfc4e8$export$473cec51305fdae8(this.config, {
25027
25084
  type: ($08d5ddc39acd6833$export$fd9b17d87f4121d2).ONRAMP
25028
25085
  });
25029
- const token = tokenList.tokens.find((t)=>t.address?.toLowerCase() === params.tokenAddress?.toLowerCase());
25086
+ const token = tokenList.tokens?.find((t)=>t.address?.toLowerCase() === params.tokenAddress?.toLowerCase());
25030
25087
  if (token) {
25031
25088
  tokenAmount = params.tokenAmount;
25032
25089
  tokenSymbol = token.symbol;
@@ -25618,7 +25618,7 @@ declare enum IMTBLWidgetEvents {
25618
25618
  IMTBL_SWAP_WIDGET_EVENT = "imtbl-swap-widget",
25619
25619
  IMTBL_BRIDGE_WIDGET_EVENT = "imtbl-bridge-widget",
25620
25620
  IMTBL_ONRAMP_WIDGET_EVENT = "imtbl-onramp-widget",
25621
- IMTBL_PRIMARY_REVENUE_WIDGET_EVENT = "imtbl-sale-widget"
25621
+ IMTBL_SALE_WIDGET_EVENT = "imtbl-sale-widget"
25622
25622
  }
25623
25623
  /**
25624
25624
  * Represents an event emitted by a widget.
@@ -25,7 +25,7 @@ var $045213b18e9f1f94$export$75be0f6af9650f2c;
25
25
  })($045213b18e9f1f94$export$75be0f6af9650f2c || ($045213b18e9f1f94$export$75be0f6af9650f2c = {}));
26
26
 
27
27
 
28
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.10";
28
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.11";
29
29
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
30
30
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
31
31
 
@@ -159,7 +159,7 @@ var $207ed853f11d19d5$export$5a0ace85cae72d45;
159
159
  IMTBLWidgetEvents["IMTBL_SWAP_WIDGET_EVENT"] = "imtbl-swap-widget";
160
160
  IMTBLWidgetEvents["IMTBL_BRIDGE_WIDGET_EVENT"] = "imtbl-bridge-widget";
161
161
  IMTBLWidgetEvents["IMTBL_ONRAMP_WIDGET_EVENT"] = "imtbl-onramp-widget";
162
- IMTBLWidgetEvents["IMTBL_PRIMARY_REVENUE_WIDGET_EVENT"] = "imtbl-sale-widget";
162
+ IMTBLWidgetEvents["IMTBL_SALE_WIDGET_EVENT"] = "imtbl-sale-widget";
163
163
  })($207ed853f11d19d5$export$5a0ace85cae72d45 || ($207ed853f11d19d5$export$5a0ace85cae72d45 = {}));
164
164
 
165
165
 
@@ -16,7 +16,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
16
16
  chainID,
17
17
  coreContractAddress,
18
18
  registrationContractAddress,
19
- sdkVersion: 'ts-immutable-sdk-0.27.10',
19
+ sdkVersion: 'ts-immutable-sdk-0.27.11',
20
20
  });
21
21
  /**
22
22
  * Sets `sdkVersion` at the time of build