@imtbl/sdk 0.27.7 → 0.27.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3631,7 +3631,7 @@ class MultiRollupApiClients {
3631
3631
  }
3632
3632
 
3633
3633
  // eslint-disable-next-line @typescript-eslint/naming-convention
3634
- const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.7' };
3634
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.9' };
3635
3635
  const createConfig = ({ basePath, headers, }) => {
3636
3636
  if (!basePath.trim()) {
3637
3637
  throw Error('basePath can not be empty');
@@ -3691,7 +3691,7 @@ class APIError extends Error {
3691
3691
 
3692
3692
  /* eslint-disable implicit-arrow-linebreak */
3693
3693
  const defaultHeaders = {
3694
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.7',
3694
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.9',
3695
3695
  };
3696
3696
  /**
3697
3697
  * createAPIConfiguration to create a custom Configuration
@@ -4102,7 +4102,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
4102
4102
  chainID,
4103
4103
  coreContractAddress,
4104
4104
  registrationContractAddress,
4105
- sdkVersion: 'ts-immutable-sdk-0.27.7',
4105
+ sdkVersion: 'ts-immutable-sdk-0.27.9',
4106
4106
  });
4107
4107
  /**
4108
4108
  * Sets `sdkVersion` at the time of build
@@ -11793,9 +11793,6 @@ class Seaport {
11793
11793
  };
11794
11794
  }
11795
11795
  async fulfillBulkOrders(fulfillingOrders, account) {
11796
- // TODO: this function right now does not handle errors from the seaport.js
11797
- // we should figure out why orders are rejected and return a submission
11798
- // transaction on best efforts basis
11799
11796
  const fulfillOrderDetails = fulfillingOrders.map((o) => {
11800
11797
  const { orderComponents, tips } = this.mapImmutableOrderToSeaportOrderComponents(o.order);
11801
11798
  return {
@@ -12214,14 +12211,34 @@ class Orderbook {
12214
12211
  recipient: fee.recipient,
12215
12212
  })),
12216
12213
  })));
12217
- return {
12218
- ...(await this.seaport.fulfillBulkOrders(fulfillmentDataRes.result.fulfillable_orders, takerAddress)),
12219
- fulfillableOrders: fulfillmentDataRes.result.fulfillable_orders.map((o) => mapFromOpenApiOrder(o.order)),
12220
- unfulfillableOrders: fulfillmentDataRes.result.unfulfillable_orders.map((o) => ({
12221
- orderId: o.order_id,
12222
- reason: o.reason,
12223
- })),
12224
- };
12214
+ try {
12215
+ return {
12216
+ ...(await this.seaport.fulfillBulkOrders(fulfillmentDataRes.result.fulfillable_orders, takerAddress)),
12217
+ fulfillableOrders: fulfillmentDataRes.result.fulfillable_orders.map((o) => mapFromOpenApiOrder(o.order)),
12218
+ unfulfillableOrders: fulfillmentDataRes.result.unfulfillable_orders.map((o) => ({
12219
+ orderId: o.order_id,
12220
+ reason: o.reason,
12221
+ })),
12222
+ sufficientBalance: true,
12223
+ };
12224
+ }
12225
+ catch (e) {
12226
+ // if insufficient balance error, we return FulfillBulkOrdersInsufficientBalanceResponse
12227
+ if (String(e).includes('The fulfiller does not have the balances needed to fulfill.')) {
12228
+ return {
12229
+ fulfillableOrders: fulfillmentDataRes.result.fulfillable_orders.map((o) => mapFromOpenApiOrder(o.order)),
12230
+ unfulfillableOrders: fulfillmentDataRes.result.unfulfillable_orders.map((o) => ({
12231
+ orderId: o.order_id,
12232
+ reason: o.reason,
12233
+ })),
12234
+ sufficientBalance: false,
12235
+ };
12236
+ }
12237
+ // if some other error is thrown,
12238
+ // there likely is a race condition of the original order validity
12239
+ // we throw the error back out
12240
+ throw e;
12241
+ }
12225
12242
  }
12226
12243
  /**
12227
12244
  * Get an unsigned cancel order transaction. Orders can only be cancelled by
@@ -28017,25 +28034,65 @@ function isValidNonZeroAddress(address) {
28017
28034
  return false;
28018
28035
  }
28019
28036
  }
28020
- const tokenInfoToUniswapToken = (tokenInfo) => new sdkCore.Token(tokenInfo.chainId, tokenInfo.address, tokenInfo.decimals, tokenInfo.symbol, tokenInfo.name);
28037
+ const erc20ToUniswapToken = (token) =>
28038
+ // eslint-disable-next-line implicit-arrow-linebreak
28039
+ new sdkCore.Token(token.chainId, token.address, token.decimals, token.symbol, token.name);
28040
+ const uniswapTokenToERC20 = (token) => ({
28041
+ chainId: token.chainId,
28042
+ address: token.address,
28043
+ decimals: token.decimals,
28044
+ symbol: token.symbol,
28045
+ name: token.name,
28046
+ type: 'erc20',
28047
+ });
28021
28048
  const toCurrencyAmount = (amount) => {
28022
- const token = tokenInfoToUniswapToken(amount.token);
28049
+ const token = erc20ToUniswapToken(amount.token);
28023
28050
  return sdkCore.CurrencyAmount.fromRawAmount(token, amount.value.toString());
28024
28051
  };
28025
28052
  const newAmount = (amount, token) => ({
28026
28053
  value: amount,
28027
28054
  token,
28028
28055
  });
28029
- const addAmount = (a, b) => {
28056
+ const isERC20Amount = (amount) => amount.token.type === 'erc20';
28057
+ const isNativeAmount = (amount) => amount.token.type === 'native';
28058
+ const addERC20Amount = (a, b) => {
28059
+ // Make sure the ERC20s have the same address
28030
28060
  if (a.token.address !== b.token.address)
28031
- throw new Error('Token mismatch');
28061
+ throw new Error('Token mismatch: token addresses must be the same');
28032
28062
  return { value: a.value.add(b.value), token: a.token };
28033
28063
  };
28034
- const subtractAmount = (a, b) => {
28064
+ const addNativeAmount = (a, b) => ({
28065
+ value: a.value.add(b.value),
28066
+ token: a.token,
28067
+ });
28068
+ const addAmount = (a, b) => {
28069
+ if (isERC20Amount(a) && isERC20Amount(b)) {
28070
+ return addERC20Amount(a, b);
28071
+ }
28072
+ if (isNativeAmount(a) && isNativeAmount(b)) {
28073
+ return addNativeAmount(a, b);
28074
+ }
28075
+ throw new Error('Token mismatch: token types must be the same');
28076
+ };
28077
+ const subtractERC20Amount = (a, b) => {
28078
+ // Make sure the ERC20s have the same address
28035
28079
  if (a.token.address !== b.token.address)
28036
- throw new Error('Token mismatch');
28080
+ throw new Error('Token mismatch: token addresses must be the same');
28037
28081
  return { value: a.value.sub(b.value), token: a.token };
28038
28082
  };
28083
+ const subtractNativeAmount = (a, b) => ({
28084
+ value: a.value.sub(b.value),
28085
+ token: a.token,
28086
+ });
28087
+ const subtractAmount = (a, b) => {
28088
+ if (isERC20Amount(a) && isERC20Amount(b)) {
28089
+ return subtractERC20Amount(a, b);
28090
+ }
28091
+ if (isNativeAmount(a) && isNativeAmount(b)) {
28092
+ return subtractNativeAmount(a, b);
28093
+ }
28094
+ throw new Error('Token mismatch: token types must be the same');
28095
+ };
28039
28096
 
28040
28097
  const amountIndex = 0;
28041
28098
  const gasEstimateIndex = 3;
@@ -28073,10 +28130,12 @@ async function getQuotesForRoutes(multicallContract, quoterContractAddress, rout
28073
28130
  const quoteAmount = decodedQuoteResult[amountIndex];
28074
28131
  if (!(quoteAmount instanceof ethers.BigNumber))
28075
28132
  throw new Error('Expected BigNumber');
28133
+ const input = uniswapTokenToERC20(routes[i].input);
28134
+ const output = uniswapTokenToERC20(routes[i].output);
28076
28135
  decodedQuoteResults.push({
28077
28136
  route: routes[i],
28078
- amountIn: tradeType === sdkCore.TradeType.EXACT_INPUT ? amountSpecified : newAmount(quoteAmount, routes[i].input),
28079
- amountOut: tradeType === sdkCore.TradeType.EXACT_INPUT ? newAmount(quoteAmount, routes[i].output) : amountSpecified,
28137
+ amountIn: tradeType === sdkCore.TradeType.EXACT_INPUT ? amountSpecified : newAmount(quoteAmount, input),
28138
+ amountOut: tradeType === sdkCore.TradeType.EXACT_INPUT ? newAmount(quoteAmount, output) : amountSpecified,
28080
28139
  gasEstimate: ethers.ethers.BigNumber.from(decodedQuoteResult[gasEstimateIndex]),
28081
28140
  tradeType,
28082
28141
  });
@@ -28207,7 +28266,7 @@ const fetchValidPools = async (multicallContract, erc20Pair, commonRoutingERC20s
28207
28266
  if (zeroPrice || zeroLiquidity) {
28208
28267
  return;
28209
28268
  }
28210
- const validPool = new v3Sdk.Pool(tokenInfoToUniswapToken(poolID.erc20Pair[0]), tokenInfoToUniswapToken(poolID.erc20Pair[1]), poolID.fee, poolSlot0.sqrtPriceX96.toString(), poolLiquidity.toString(), poolSlot0.tick);
28269
+ const validPool = new v3Sdk.Pool(erc20ToUniswapToken(poolID.erc20Pair[0]), erc20ToUniswapToken(poolID.erc20Pair[1]), poolID.fee, poolSlot0.sqrtPriceX96.toString(), poolLiquidity.toString(), poolSlot0.tick);
28211
28270
  validPools.push(validPool);
28212
28271
  });
28213
28272
  return validPools;
@@ -28293,9 +28352,9 @@ maxHops, // the maximum number of pools that can be traversed
28293
28352
  currentRoute = [], // list of pools already traversed
28294
28353
  routes = [], // list of all routes found so far
28295
28354
  startTokenIn = tokenIn) => {
28296
- const currencyIn = tokenInfoToUniswapToken(tokenIn);
28297
- const currencyOut = tokenInfoToUniswapToken(tokenOut);
28298
- const startCurrencyIn = tokenInfoToUniswapToken(startTokenIn);
28355
+ const currencyIn = erc20ToUniswapToken(tokenIn);
28356
+ const currencyOut = erc20ToUniswapToken(tokenOut);
28357
+ const startCurrencyIn = erc20ToUniswapToken(startTokenIn);
28299
28358
  for (const pool of pools) {
28300
28359
  // if the pool doesn't have the tokenIn or if it has already been traversed,
28301
28360
  // skip to the next pool
@@ -28314,7 +28373,7 @@ startTokenIn = tokenIn) => {
28314
28373
  else if (maxHops > 1) {
28315
28374
  // otherwise, if we haven't exceeded the maximum number of pools that can be traversed,
28316
28375
  // recursively call this function with the output token as the new starting currency
28317
- generateAllAcyclicPaths(outputToken, tokenOut, pools, maxHops - 1, [...currentRoute, pool], routes, startTokenIn);
28376
+ generateAllAcyclicPaths(uniswapTokenToERC20(outputToken), tokenOut, pools, maxHops - 1, [...currentRoute, pool], routes, startTokenIn);
28318
28377
  }
28319
28378
  }
28320
28379
  return routes;
@@ -28407,11 +28466,11 @@ const getUnsignedERC20ApproveTransaction = (ownerAddress, tokenAmount, spenderAd
28407
28466
  from: ownerAddress,
28408
28467
  };
28409
28468
  };
28410
- const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, routingContracts, secondaryFees) => {
28469
+ const prepareApproval = (tradeType, amountSpecified, amountWithSlippage, contracts, secondaryFees) => {
28411
28470
  const amountOfTokenIn = tradeType === sdkCore.TradeType.EXACT_INPUT ? amountSpecified : amountWithSlippage;
28412
28471
  const spender = secondaryFees.length === 0
28413
- ? routingContracts.peripheryRouterAddress
28414
- : routingContracts.secondaryFeeAddress;
28472
+ ? contracts.routerAddress
28473
+ : contracts.secondaryFeeAddress;
28415
28474
  return { spender, amount: amountOfTokenIn };
28416
28475
  };
28417
28476
  /**
@@ -28444,7 +28503,7 @@ async function getApproveGasEstimate(provider, ownerAddress, spenderAddress, tok
28444
28503
  from: ownerAddress,
28445
28504
  });
28446
28505
  }
28447
- const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) => {
28506
+ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice, nativeTokenService) => {
28448
28507
  const approveTransaction = await getApproveTransaction(provider, ownerAddress, preparedApproval.amount, preparedApproval.spender);
28449
28508
  if (!approveTransaction) {
28450
28509
  return null;
@@ -28453,7 +28512,8 @@ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) =
28453
28512
  const gasFeeEstimate = gasPrice ? calculateGasFee(gasPrice, gasEstimate) : null;
28454
28513
  return {
28455
28514
  transaction: approveTransaction,
28456
- gasFeeEstimate,
28515
+ // TODO: TP-1649: Remove the wrapping here
28516
+ gasFeeEstimate: gasFeeEstimate ? nativeTokenService.maybeWrapAmount(gasFeeEstimate) : null,
28457
28517
  };
28458
28518
  };
28459
28519
 
@@ -28489,7 +28549,7 @@ function applySlippage(tradeType, amount, slippage) {
28489
28549
  const amountWithSlippage = maybeInverted.multiply(amount.toString()).quotient;
28490
28550
  return ethers.ethers.BigNumber.from(amountWithSlippage.toString());
28491
28551
  }
28492
- function prepareUserQuote(otherToken, tradeInfo, slippage, fees) {
28552
+ function prepareUserQuote(otherToken, tradeInfo, slippage, fees, nativeTokenService) {
28493
28553
  const quote = getQuoteAmountFromTradeType(tradeInfo);
28494
28554
  const amountWithSlippage = applySlippage(tradeInfo.tradeType, quote.value, slippage);
28495
28555
  return {
@@ -28499,16 +28559,20 @@ function prepareUserQuote(otherToken, tradeInfo, slippage, fees) {
28499
28559
  value: amountWithSlippage,
28500
28560
  },
28501
28561
  slippage,
28502
- fees: fees.withAmounts(),
28562
+ fees: fees.withAmounts().map((fee) => ({
28563
+ ...fee,
28564
+ amount: nativeTokenService.maybeWrapAmount(fee.amount),
28565
+ })),
28503
28566
  };
28504
28567
  }
28505
- function getOurQuoteReqAmount(amount, fees, tradeType) {
28568
+ function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
28569
+ fees, tradeType, nativeTokenService) {
28506
28570
  if (tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
28507
28571
  // For an exact output swap, we do not need to subtract fees from the given amount
28508
- return amount;
28572
+ return nativeTokenService.maybeWrapAmount(amountSpecified);
28509
28573
  }
28510
- fees.addAmount(amount);
28511
- return fees.amountLessFees();
28574
+ fees.addAmount(amountSpecified);
28575
+ return nativeTokenService.maybeWrapAmount(fees.amountLessFees());
28512
28576
  }
28513
28577
 
28514
28578
  // 0.1% default slippage
@@ -28524,7 +28588,7 @@ const MIN_MAX_HOPS = 1;
28524
28588
  // precision used to calculate percentage from basis points
28525
28589
  const BASIS_POINT_PRECISION = 10000;
28526
28590
  // 10% maximum secondary fee
28527
- const MAX_SECONDARY_FEE_BASIS_POINTS = 10000;
28591
+ const MAX_SECONDARY_FEE_BASIS_POINTS = 1000;
28528
28592
 
28529
28593
  class Fees {
28530
28594
  secondaryFees;
@@ -28533,6 +28597,9 @@ class Fees {
28533
28597
  this.secondaryFees = secondaryFees;
28534
28598
  this.amount = newAmount(ethers.BigNumber.from(0), token);
28535
28599
  }
28600
+ get token() {
28601
+ return this.amount.token;
28602
+ }
28536
28603
  addAmount(amount) {
28537
28604
  this.amount = addAmount(this.amount, amount);
28538
28605
  }
@@ -28565,18 +28632,65 @@ class Fees {
28565
28632
  }
28566
28633
  }
28567
28634
 
28635
+ class NativeTokenService {
28636
+ nativeToken;
28637
+ wrappedToken;
28638
+ constructor(nativeToken, wrappedToken) {
28639
+ this.nativeToken = nativeToken;
28640
+ this.wrappedToken = wrappedToken;
28641
+ }
28642
+ wrapAmount(amount) {
28643
+ return newAmount(amount.value, this.wrappedToken);
28644
+ }
28645
+ unwrapAmount(amount) {
28646
+ if (amount.token !== this.wrappedToken) {
28647
+ throw new Error(`token ${amount.token.address} is not wrapped`);
28648
+ }
28649
+ return newAmount(amount.value, this.nativeToken);
28650
+ }
28651
+ maybeWrapToken(token) {
28652
+ if (this.isNativeToken(token)) {
28653
+ return this.wrappedToken;
28654
+ }
28655
+ return token;
28656
+ }
28657
+ maybeWrapAmount(amount) {
28658
+ return newAmount(amount.value, this.maybeWrapToken(amount.token));
28659
+ }
28660
+ isNativeToken(token) {
28661
+ return token === this.nativeToken;
28662
+ }
28663
+ }
28664
+
28568
28665
  const IMMUTABLE_TESTNET_RPC_URL = 'https://rpc.testnet.immutable.com';
28569
28666
  const IMMUTABLE_TESTNET_CHAIN_ID = 13472;
28570
28667
 
28668
+ const NATIVE_IMX_IMMUTABLE_TESTNET = {
28669
+ chainId: IMMUTABLE_TESTNET_CHAIN_ID,
28670
+ decimals: 18,
28671
+ symbol: 'tIMX',
28672
+ name: 'Immutable Testnet Token',
28673
+ type: 'native',
28674
+ };
28571
28675
  const TIMX_IMMUTABLE_TESTNET = {
28572
28676
  chainId: IMMUTABLE_TESTNET_CHAIN_ID,
28573
28677
  address: '0x0000000000000000000000000000000000001010',
28574
28678
  decimals: 18,
28575
28679
  symbol: 'tIMX',
28576
28680
  name: 'Immutable Testnet Token',
28681
+ type: 'erc20',
28682
+ };
28683
+ const WIMX_IMMUTABLE_TESTNET = {
28684
+ chainId: IMMUTABLE_TESTNET_CHAIN_ID,
28685
+ address: '0xAf7cf5D4Af0BFAa85d384d42b8D410762Ccbce69',
28686
+ decimals: 18,
28687
+ symbol: 'WIMX',
28688
+ name: 'Wrapped Immutable Testnet Token',
28689
+ type: 'erc20',
28577
28690
  };
28578
28691
  const IMMUTABLE_TESTNET_COMMON_ROUTING_TOKENS = [
28579
28692
  TIMX_IMMUTABLE_TESTNET,
28693
+ WIMX_IMMUTABLE_TESTNET,
28580
28694
  ];
28581
28695
 
28582
28696
  const zeroNativeCurrencyValue = '0x00';
@@ -28673,7 +28787,7 @@ function createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, se
28673
28787
  }
28674
28788
  return createSwapCallParametersWithFees(uncheckedTrade, fromAddress, options, secondaryFees);
28675
28789
  }
28676
- function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouterAddress, secondaryFeesAddress, gasPrice, secondaryFees) {
28790
+ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouterAddress, secondaryFeesAddress, gasPrice, secondaryFees, nativeTokenService) {
28677
28791
  const calldata = createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, secondaryFees);
28678
28792
  // TODO: Add additional gas fee estimates for secondary fees
28679
28793
  const gasFeeEstimate = gasPrice ? calculateGasFee(gasPrice, adjustedQuote.gasEstimate) : null;
@@ -28684,24 +28798,37 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
28684
28798
  value: zeroNativeCurrencyValue,
28685
28799
  from: fromAddress,
28686
28800
  },
28687
- gasFeeEstimate,
28801
+ // TODO: TP-1649: Remove the wrapping here
28802
+ gasFeeEstimate: gasFeeEstimate ? nativeTokenService.maybeWrapAmount(gasFeeEstimate) : null,
28688
28803
  };
28689
28804
  }
28690
- function prepareSwap(ourQuote, amountSpecified, fees) {
28805
+ const adjustAmountIn = (ourQuote, amountSpecified, fees, nativeTokenService) => {
28691
28806
  if (ourQuote.tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
28692
- fees.addAmount(ourQuote.amountIn);
28693
- return {
28694
- gasEstimate: ourQuote.gasEstimate,
28695
- route: ourQuote.route,
28696
- amountIn: fees.amountWithFeesApplied(),
28697
- amountOut: amountSpecified,
28698
- tradeType: ourQuote.tradeType,
28699
- };
28807
+ // when doing exact output, calculate the fees based on the amountIn
28808
+ const amountToAdd = nativeTokenService.isNativeToken(fees.token)
28809
+ ? nativeTokenService.unwrapAmount(ourQuote.amountIn)
28810
+ : ourQuote.amountIn;
28811
+ fees.addAmount(amountToAdd);
28812
+ return nativeTokenService.maybeWrapAmount(fees.amountWithFeesApplied());
28700
28813
  }
28814
+ return nativeTokenService.maybeWrapAmount(amountSpecified);
28815
+ };
28816
+ /**
28817
+ * adjustQuoteWithFees adjusts the amountIn of the quote to account for fees
28818
+ * EXACT_OUTPUT swaps will have the fees added to the amountIn if there are fees specified
28819
+ * EXACT_INPUT swaps will have amountIn set to the user-specified amount
28820
+ * @param ourQuote The quote from calling the Quoter contract
28821
+ * @param amountSpecified The user-specified amount for the swap (EXACT...)
28822
+ * @param fees The fees applied to the swap
28823
+ * @param tokenWrapper Helper class for the native token and associated ERC20
28824
+ * @returns {QuoteResult} The adjusted quote
28825
+ */
28826
+ function adjustQuoteWithFees(ourQuote, amountSpecified, fees, nativeTokenService) {
28827
+ const adjustedAmountIn = adjustAmountIn(ourQuote, amountSpecified, fees, nativeTokenService);
28701
28828
  return {
28702
28829
  gasEstimate: ourQuote.gasEstimate,
28703
28830
  route: ourQuote.route,
28704
- amountIn: amountSpecified,
28831
+ amountIn: adjustedAmountIn,
28705
28832
  amountOut: ourQuote.amountOut,
28706
28833
  tradeType: ourQuote.tradeType,
28707
28834
  };
@@ -28722,7 +28849,8 @@ const SUPPORTED_SANDBOX_CHAINS = {
28722
28849
  rpcUrl: IMMUTABLE_TESTNET_RPC_URL,
28723
28850
  contracts: CONTRACTS_FOR_CHAIN_ID[IMMUTABLE_TESTNET_CHAIN_ID],
28724
28851
  commonRoutingTokens: IMMUTABLE_TESTNET_COMMON_ROUTING_TOKENS,
28725
- nativeToken: TIMX_IMMUTABLE_TESTNET,
28852
+ nativeToken: NATIVE_IMX_IMMUTABLE_TESTNET,
28853
+ wrappedNativeToken: TIMX_IMMUTABLE_TESTNET, // TODO: TP-1649: Change to WIMX when ready.
28726
28854
  },
28727
28855
  };
28728
28856
  const SUPPORTED_PRODUCTION_CHAINS = {};
@@ -28780,6 +28908,7 @@ class ExchangeConfiguration {
28780
28908
  contracts: overrides.exchangeContracts,
28781
28909
  commonRoutingTokens: overrides.commonRoutingTokens,
28782
28910
  nativeToken: overrides.nativeToken,
28911
+ wrappedNativeToken: overrides.wrappedNativeToken,
28783
28912
  };
28784
28913
  this.secondaryFees = secondaryFees || [];
28785
28914
  return;
@@ -28797,19 +28926,25 @@ class Exchange {
28797
28926
  router;
28798
28927
  chainId;
28799
28928
  nativeToken;
28929
+ wrappedNativeToken;
28800
28930
  secondaryFees;
28931
+ nativeTokenService;
28932
+ secondaryFeeContractAddress;
28933
+ routerContractAddress;
28801
28934
  constructor(configuration) {
28802
28935
  const config = new ExchangeConfiguration(configuration);
28803
28936
  this.chainId = config.chain.chainId;
28804
28937
  this.nativeToken = config.chain.nativeToken;
28938
+ this.wrappedNativeToken = config.chain.wrappedNativeToken;
28939
+ this.nativeTokenService = new NativeTokenService(this.nativeToken, this.wrappedNativeToken);
28805
28940
  this.secondaryFees = config.secondaryFees;
28941
+ this.routerContractAddress = config.chain.contracts.peripheryRouter;
28942
+ this.secondaryFeeContractAddress = config.chain.contracts.secondaryFee;
28806
28943
  this.provider = new ethers.ethers.providers.JsonRpcProvider(config.chain.rpcUrl);
28807
28944
  this.router = new Router(this.provider, config.chain.commonRoutingTokens, {
28808
28945
  multicallAddress: config.chain.contracts.multicall,
28809
28946
  factoryAddress: config.chain.contracts.coreFactory,
28810
28947
  quoterAddress: config.chain.contracts.quoterV2,
28811
- peripheryRouterAddress: config.chain.contracts.peripheryRouter,
28812
- secondaryFeeAddress: config.chain.contracts.secondaryFee,
28813
28948
  });
28814
28949
  }
28815
28950
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
@@ -28826,7 +28961,7 @@ class Exchange {
28826
28961
  if (this.secondaryFees.length === 0) {
28827
28962
  return [];
28828
28963
  }
28829
- const secondaryFeeContract = SecondaryFee__factory.connect(this.router.routingContracts.secondaryFeeAddress, this.provider);
28964
+ const secondaryFeeContract = SecondaryFee__factory.connect(this.secondaryFeeContractAddress, this.provider);
28830
28965
  if (await secondaryFeeContract.paused()) {
28831
28966
  // Do not use secondary fees if the contract is paused
28832
28967
  return [];
@@ -28842,32 +28977,36 @@ class Exchange {
28842
28977
  this.getSecondaryFees(),
28843
28978
  ]);
28844
28979
  const tokenIn = {
28980
+ type: 'erc20',
28845
28981
  address: tokenInAddress,
28846
28982
  chainId: this.chainId,
28847
28983
  decimals: tokenInDecimals,
28848
28984
  };
28849
28985
  const tokenOut = {
28986
+ type: 'erc20',
28850
28987
  address: tokenOutAddress,
28851
28988
  chainId: this.chainId,
28852
28989
  decimals: tokenOutDecimals,
28853
28990
  };
28854
28991
  // determine which amount was specified for the swap from the TradeType
28855
- const [tokenSpecified, otherToken] = tradeType === sdkCore.TradeType.EXACT_INPUT
28856
- ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
28992
+ const [tokenSpecified, otherToken] = tradeType === sdkCore.TradeType.EXACT_INPUT ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
28857
28993
  const amountSpecified = newAmount(amount, tokenSpecified);
28858
28994
  const fees = new Fees(secondaryFees, tokenIn);
28859
- const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType);
28995
+ const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
28860
28996
  // get quote and gas details
28861
28997
  const [ourQuote, gasPrice] = await Promise.all([
28862
28998
  this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
28863
28999
  fetchGasPrice(this.provider, this.nativeToken),
28864
29000
  ]);
28865
- const adjustedQuote = prepareSwap(ourQuote, amountSpecified, fees);
28866
- const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.router.routingContracts.peripheryRouterAddress, this.router.routingContracts.secondaryFeeAddress, gasPrice, secondaryFees);
28867
- const userQuote = prepareUserQuote(otherToken, adjustedQuote, slippagePercent, fees);
28868
- const preparedApproval = prepareApproval(tradeType, amountSpecified, userQuote.amountWithMaxSlippage, this.router.routingContracts, secondaryFees);
29001
+ const adjustedQuote = adjustQuoteWithFees(ourQuote, amountSpecified, fees, this.nativeTokenService);
29002
+ const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.routerContractAddress, this.secondaryFeeContractAddress, gasPrice, secondaryFees, this.nativeTokenService);
29003
+ const userQuote = prepareUserQuote(otherToken, adjustedQuote, slippagePercent, fees, this.nativeTokenService);
29004
+ const preparedApproval = prepareApproval(tradeType, amountSpecified, userQuote.amountWithMaxSlippage, {
29005
+ routerAddress: this.routerContractAddress,
29006
+ secondaryFeeAddress: this.secondaryFeeContractAddress,
29007
+ }, secondaryFees);
28869
29008
  // preparedApproval always uses the tokenIn address because we are always selling the tokenIn
28870
- const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice);
29009
+ const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice, this.nativeTokenService);
28871
29010
  return {
28872
29011
  approval,
28873
29012
  swap,
@@ -31045,8 +31184,6 @@ const $5e9bcae98dc8ff19$export$1165ca270f090a66 = (isDevelopment, isProduction)=
31045
31184
  return ($d85ad1457a3f1a83$export$89133ca13c5ee30)[(Environment$1).SANDBOX];
31046
31185
  };
31047
31186
  const checkDexAvailability = async ()=>{
31048
- // TEMP FIX: Returns true for sandbox environment
31049
- if (!isDevelopment && !isProduction) return true;
31050
31187
  let response;
31051
31188
  try {
31052
31189
  response = await (0, globalAxios$1).post(`${postEndpoint()}/v1/availability/checkout/swap`);
@@ -31211,7 +31348,7 @@ const $049bba630af05555$export$6946a1f17c2bbf26 = async (config, chainId, wallet
31211
31348
  const swappableToken = fromToken[index];
31212
31349
  dexQuotes.set(swappableToken, {
31213
31350
  quote: response.value.quote,
31214
- approval: response.value.approval?.gasFeeEstimate,
31351
+ approval: response.value.approval?.gasFeeEstimate ?? null,
31215
31352
  swap: response.value.swap.gasFeeEstimate
31216
31353
  });
31217
31354
  });
@@ -33066,7 +33203,7 @@ var $045213b18e9f1f94$export$75be0f6af9650f2c;
33066
33203
  })($045213b18e9f1f94$export$75be0f6af9650f2c || ($045213b18e9f1f94$export$75be0f6af9650f2c = {}));
33067
33204
 
33068
33205
 
33069
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.7";
33206
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.9";
33070
33207
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
33071
33208
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
33072
33209
 
package/dist/index.d.ts CHANGED
@@ -15784,12 +15784,19 @@ interface FulfillmentListing {
15784
15784
  listingId: string;
15785
15785
  takerFees: Array<FeeValue>;
15786
15786
  }
15787
- interface FulfillBulkOrdersResponse {
15787
+ type FulfillBulkOrdersResponse = FulfillBulkOrdersInsufficientBalanceResponse | FulfillBulkOrdersSufficientBalanceResponse;
15788
+ interface FulfillBulkOrdersSufficientBalanceResponse {
15789
+ sufficientBalance: true;
15788
15790
  actions: Action[];
15789
15791
  expiration: string;
15790
15792
  fulfillableOrders: Order[];
15791
15793
  unfulfillableOrders: UnfulfillableOrder[];
15792
15794
  }
15795
+ interface FulfillBulkOrdersInsufficientBalanceResponse {
15796
+ sufficientBalance: false;
15797
+ fulfillableOrders: Order[];
15798
+ unfulfillableOrders: UnfulfillableOrder[];
15799
+ }
15793
15800
  interface UnfulfillableOrder {
15794
15801
  orderId: string;
15795
15802
  reason: string;
@@ -15989,7 +15996,9 @@ type orderbook_d_ERC721Item = ERC721Item;
15989
15996
  type orderbook_d_FeeType = FeeType;
15990
15997
  declare const orderbook_d_FeeType: typeof FeeType;
15991
15998
  type orderbook_d_FeeValue = FeeValue;
15999
+ type orderbook_d_FulfillBulkOrdersInsufficientBalanceResponse = FulfillBulkOrdersInsufficientBalanceResponse;
15992
16000
  type orderbook_d_FulfillBulkOrdersResponse = FulfillBulkOrdersResponse;
16001
+ type orderbook_d_FulfillBulkOrdersSufficientBalanceResponse = FulfillBulkOrdersSufficientBalanceResponse;
15993
16002
  type orderbook_d_FulfillOrderResponse = FulfillOrderResponse;
15994
16003
  type orderbook_d_FulfillmentListing = FulfillmentListing;
15995
16004
  type orderbook_d_ListListingsParams = ListListingsParams;
@@ -16029,7 +16038,9 @@ declare namespace orderbook_d {
16029
16038
  Fee$1 as Fee,
16030
16039
  orderbook_d_FeeType as FeeType,
16031
16040
  orderbook_d_FeeValue as FeeValue,
16041
+ orderbook_d_FulfillBulkOrdersInsufficientBalanceResponse as FulfillBulkOrdersInsufficientBalanceResponse,
16032
16042
  orderbook_d_FulfillBulkOrdersResponse as FulfillBulkOrdersResponse,
16043
+ orderbook_d_FulfillBulkOrdersSufficientBalanceResponse as FulfillBulkOrdersSufficientBalanceResponse,
16033
16044
  orderbook_d_FulfillOrderResponse as FulfillOrderResponse,
16034
16045
  orderbook_d_FulfillmentListing as FulfillmentListing,
16035
16046
  orderbook_d_ListListingsParams as ListListingsParams,
@@ -16074,25 +16085,41 @@ declare namespace provider_d {
16074
16085
  }
16075
16086
 
16076
16087
  /**
16077
- * Interface representing a token
16088
+ * Interface representing an ERC20 token
16078
16089
  * @property {number} chainId - The chain ID
16079
16090
  * @property {string} address - The token address
16080
16091
  * @property {number} decimals - The token decimals
16081
16092
  * @property {string | undefined} symbol - The token symbol or undefined if it is not available
16082
16093
  * @property {string | undefined} name - The token name or undefined if it is not available
16083
16094
  */
16084
- type TokenInfo$1 = {
16095
+ type ERC20 = {
16096
+ type: 'erc20';
16085
16097
  chainId: number;
16086
16098
  address: string;
16087
16099
  decimals: number;
16088
16100
  symbol?: string;
16089
16101
  name?: string;
16090
16102
  };
16103
+ /**
16104
+ * Interface representing a native token
16105
+ * @property {number} chainId - The chain ID
16106
+ * @property {number} decimals - The token decimals
16107
+ * @property {string | undefined} symbol - The token symbol or undefined if it is not available
16108
+ * @property {string | undefined} name - The token name or undefined if it is not available
16109
+ */
16110
+ type Native = {
16111
+ type: 'native';
16112
+ chainId: number;
16113
+ decimals: number;
16114
+ symbol?: string;
16115
+ name?: string;
16116
+ };
16091
16117
  interface ExchangeOverrides {
16092
16118
  rpcURL: string;
16093
16119
  exchangeContracts: ExchangeContracts;
16094
- commonRoutingTokens: TokenInfo$1[];
16095
- nativeToken: TokenInfo$1;
16120
+ commonRoutingTokens: ERC20[];
16121
+ nativeToken: Native;
16122
+ wrappedNativeToken: ERC20;
16096
16123
  }
16097
16124
 
16098
16125
  /**