@imtbl/sdk 0.27.6 → 0.27.8

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.6' };
3634
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.27.8' };
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.6',
3694
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.8',
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.6',
4105
+ sdkVersion: 'ts-immutable-sdk-0.27.8',
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,23 +28034,36 @@ 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 addERC20Amount = (a, b) => {
28058
+ // Make sure the ERC20s have the same address
28030
28059
  if (a.token.address !== b.token.address)
28031
- throw new Error('Token mismatch');
28060
+ throw new Error('Token mismatch: token addresses must be the same');
28032
28061
  return { value: a.value.add(b.value), token: a.token };
28033
28062
  };
28034
- const subtractAmount = (a, b) => {
28063
+ const subtractERC20Amount = (a, b) => {
28064
+ // Make sure the ERC20s have the same address
28035
28065
  if (a.token.address !== b.token.address)
28036
- throw new Error('Token mismatch');
28066
+ throw new Error('Token mismatch: token addresses must be the same');
28037
28067
  return { value: a.value.sub(b.value), token: a.token };
28038
28068
  };
28039
28069
 
@@ -28073,10 +28103,12 @@ async function getQuotesForRoutes(multicallContract, quoterContractAddress, rout
28073
28103
  const quoteAmount = decodedQuoteResult[amountIndex];
28074
28104
  if (!(quoteAmount instanceof ethers.BigNumber))
28075
28105
  throw new Error('Expected BigNumber');
28106
+ const input = uniswapTokenToERC20(routes[i].input);
28107
+ const output = uniswapTokenToERC20(routes[i].output);
28076
28108
  decodedQuoteResults.push({
28077
28109
  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,
28110
+ amountIn: tradeType === sdkCore.TradeType.EXACT_INPUT ? amountSpecified : newAmount(quoteAmount, input),
28111
+ amountOut: tradeType === sdkCore.TradeType.EXACT_INPUT ? newAmount(quoteAmount, output) : amountSpecified,
28080
28112
  gasEstimate: ethers.ethers.BigNumber.from(decodedQuoteResult[gasEstimateIndex]),
28081
28113
  tradeType,
28082
28114
  });
@@ -28207,7 +28239,7 @@ const fetchValidPools = async (multicallContract, erc20Pair, commonRoutingERC20s
28207
28239
  if (zeroPrice || zeroLiquidity) {
28208
28240
  return;
28209
28241
  }
28210
- const validPool = new v3Sdk.Pool(tokenInfoToUniswapToken(poolID.erc20Pair[0]), tokenInfoToUniswapToken(poolID.erc20Pair[1]), poolID.fee, poolSlot0.sqrtPriceX96.toString(), poolLiquidity.toString(), poolSlot0.tick);
28242
+ const validPool = new v3Sdk.Pool(erc20ToUniswapToken(poolID.erc20Pair[0]), erc20ToUniswapToken(poolID.erc20Pair[1]), poolID.fee, poolSlot0.sqrtPriceX96.toString(), poolLiquidity.toString(), poolSlot0.tick);
28211
28243
  validPools.push(validPool);
28212
28244
  });
28213
28245
  return validPools;
@@ -28293,9 +28325,9 @@ maxHops, // the maximum number of pools that can be traversed
28293
28325
  currentRoute = [], // list of pools already traversed
28294
28326
  routes = [], // list of all routes found so far
28295
28327
  startTokenIn = tokenIn) => {
28296
- const currencyIn = tokenInfoToUniswapToken(tokenIn);
28297
- const currencyOut = tokenInfoToUniswapToken(tokenOut);
28298
- const startCurrencyIn = tokenInfoToUniswapToken(startTokenIn);
28328
+ const currencyIn = erc20ToUniswapToken(tokenIn);
28329
+ const currencyOut = erc20ToUniswapToken(tokenOut);
28330
+ const startCurrencyIn = erc20ToUniswapToken(startTokenIn);
28299
28331
  for (const pool of pools) {
28300
28332
  // if the pool doesn't have the tokenIn or if it has already been traversed,
28301
28333
  // skip to the next pool
@@ -28314,7 +28346,7 @@ startTokenIn = tokenIn) => {
28314
28346
  else if (maxHops > 1) {
28315
28347
  // otherwise, if we haven't exceeded the maximum number of pools that can be traversed,
28316
28348
  // recursively call this function with the output token as the new starting currency
28317
- generateAllAcyclicPaths(outputToken, tokenOut, pools, maxHops - 1, [...currentRoute, pool], routes, startTokenIn);
28349
+ generateAllAcyclicPaths(uniswapTokenToERC20(outputToken), tokenOut, pools, maxHops - 1, [...currentRoute, pool], routes, startTokenIn);
28318
28350
  }
28319
28351
  }
28320
28352
  return routes;
@@ -28444,7 +28476,7 @@ async function getApproveGasEstimate(provider, ownerAddress, spenderAddress, tok
28444
28476
  from: ownerAddress,
28445
28477
  });
28446
28478
  }
28447
- const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) => {
28479
+ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice, nativeTokenService) => {
28448
28480
  const approveTransaction = await getApproveTransaction(provider, ownerAddress, preparedApproval.amount, preparedApproval.spender);
28449
28481
  if (!approveTransaction) {
28450
28482
  return null;
@@ -28453,7 +28485,8 @@ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) =
28453
28485
  const gasFeeEstimate = gasPrice ? calculateGasFee(gasPrice, gasEstimate) : null;
28454
28486
  return {
28455
28487
  transaction: approveTransaction,
28456
- gasFeeEstimate,
28488
+ // TODO: TP-1649: Remove the wrapping here
28489
+ gasFeeEstimate: gasFeeEstimate ? nativeTokenService.maybeWrapAmount(gasFeeEstimate) : null,
28457
28490
  };
28458
28491
  };
28459
28492
 
@@ -28502,13 +28535,18 @@ function prepareUserQuote(otherToken, tradeInfo, slippage, fees) {
28502
28535
  fees: fees.withAmounts(),
28503
28536
  };
28504
28537
  }
28505
- function getOurQuoteReqAmount(amount, fees, tradeType) {
28538
+ function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
28539
+ fees, tradeType, nativeTokenService) {
28540
+ // TODO: TP-1649: Remove this when we support Native
28541
+ if (!isERC20Amount(amountSpecified)) {
28542
+ throw new Error('Not implemented yet!');
28543
+ }
28506
28544
  if (tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
28507
28545
  // For an exact output swap, we do not need to subtract fees from the given amount
28508
- return amount;
28546
+ return nativeTokenService.maybeWrapAmount(amountSpecified);
28509
28547
  }
28510
- fees.addAmount(amount);
28511
- return fees.amountLessFees();
28548
+ fees.addAmount(amountSpecified);
28549
+ return nativeTokenService.maybeWrapAmount(fees.amountLessFees());
28512
28550
  }
28513
28551
 
28514
28552
  // 0.1% default slippage
@@ -28524,7 +28562,7 @@ const MIN_MAX_HOPS = 1;
28524
28562
  // precision used to calculate percentage from basis points
28525
28563
  const BASIS_POINT_PRECISION = 10000;
28526
28564
  // 10% maximum secondary fee
28527
- const MAX_SECONDARY_FEE_BASIS_POINTS = 10000;
28565
+ const MAX_SECONDARY_FEE_BASIS_POINTS = 1000;
28528
28566
 
28529
28567
  class Fees {
28530
28568
  secondaryFees;
@@ -28534,13 +28572,13 @@ class Fees {
28534
28572
  this.amount = newAmount(ethers.BigNumber.from(0), token);
28535
28573
  }
28536
28574
  addAmount(amount) {
28537
- this.amount = addAmount(this.amount, amount);
28575
+ this.amount = addERC20Amount(this.amount, amount);
28538
28576
  }
28539
28577
  amountWithFeesApplied() {
28540
- return addAmount(this.amount, this.total());
28578
+ return addERC20Amount(this.amount, this.total());
28541
28579
  }
28542
28580
  amountLessFees() {
28543
- return subtractAmount(this.amount, this.total());
28581
+ return subtractERC20Amount(this.amount, this.total());
28544
28582
  }
28545
28583
  withAmounts() {
28546
28584
  return this.secondaryFees.map((fee) => {
@@ -28559,24 +28597,71 @@ class Fees {
28559
28597
  const feeAmount = this.amount.value
28560
28598
  .mul(fee.basisPoints)
28561
28599
  .div(BASIS_POINT_PRECISION);
28562
- totalFees = addAmount(totalFees, newAmount(feeAmount, this.amount.token));
28600
+ totalFees = addERC20Amount(totalFees, newAmount(feeAmount, this.amount.token));
28563
28601
  }
28564
28602
  return totalFees;
28565
28603
  }
28566
28604
  }
28567
28605
 
28606
+ class NativeTokenService {
28607
+ nativeToken;
28608
+ wrappedToken;
28609
+ constructor(nativeToken, wrappedToken) {
28610
+ this.nativeToken = nativeToken;
28611
+ this.wrappedToken = wrappedToken;
28612
+ }
28613
+ wrapAmount(amount) {
28614
+ return newAmount(amount.value, this.wrappedToken);
28615
+ }
28616
+ unwrapAmount(amount) {
28617
+ if (amount.token !== this.wrappedToken) {
28618
+ throw new Error(`token ${amount.token.address} is not wrapped`);
28619
+ }
28620
+ return newAmount(amount.value, this.nativeToken);
28621
+ }
28622
+ maybeWrapToken(token) {
28623
+ if (this.isNativeToken(token)) {
28624
+ return this.wrappedToken;
28625
+ }
28626
+ return token;
28627
+ }
28628
+ maybeWrapAmount(amount) {
28629
+ return newAmount(amount.value, this.maybeWrapToken(amount.token));
28630
+ }
28631
+ isNativeToken(token) {
28632
+ return token === this.nativeToken;
28633
+ }
28634
+ }
28635
+
28568
28636
  const IMMUTABLE_TESTNET_RPC_URL = 'https://rpc.testnet.immutable.com';
28569
28637
  const IMMUTABLE_TESTNET_CHAIN_ID = 13472;
28570
28638
 
28639
+ const NATIVE_IMX_IMMUTABLE_TESTNET = {
28640
+ chainId: IMMUTABLE_TESTNET_CHAIN_ID,
28641
+ decimals: 18,
28642
+ symbol: 'tIMX',
28643
+ name: 'Immutable Testnet Token',
28644
+ type: 'native',
28645
+ };
28571
28646
  const TIMX_IMMUTABLE_TESTNET = {
28572
28647
  chainId: IMMUTABLE_TESTNET_CHAIN_ID,
28573
28648
  address: '0x0000000000000000000000000000000000001010',
28574
28649
  decimals: 18,
28575
28650
  symbol: 'tIMX',
28576
28651
  name: 'Immutable Testnet Token',
28652
+ type: 'erc20',
28653
+ };
28654
+ const WIMX_IMMUTABLE_TESTNET = {
28655
+ chainId: IMMUTABLE_TESTNET_CHAIN_ID,
28656
+ address: '0xAf7cf5D4Af0BFAa85d384d42b8D410762Ccbce69',
28657
+ decimals: 18,
28658
+ symbol: 'WIMX',
28659
+ name: 'Wrapped Immutable Testnet Token',
28660
+ type: 'erc20',
28577
28661
  };
28578
28662
  const IMMUTABLE_TESTNET_COMMON_ROUTING_TOKENS = [
28579
28663
  TIMX_IMMUTABLE_TESTNET,
28664
+ WIMX_IMMUTABLE_TESTNET,
28580
28665
  ];
28581
28666
 
28582
28667
  const zeroNativeCurrencyValue = '0x00';
@@ -28673,7 +28758,7 @@ function createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, se
28673
28758
  }
28674
28759
  return createSwapCallParametersWithFees(uncheckedTrade, fromAddress, options, secondaryFees);
28675
28760
  }
28676
- function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouterAddress, secondaryFeesAddress, gasPrice, secondaryFees) {
28761
+ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouterAddress, secondaryFeesAddress, gasPrice, secondaryFees, nativeTokenService) {
28677
28762
  const calldata = createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, secondaryFees);
28678
28763
  // TODO: Add additional gas fee estimates for secondary fees
28679
28764
  const gasFeeEstimate = gasPrice ? calculateGasFee(gasPrice, adjustedQuote.gasEstimate) : null;
@@ -28684,7 +28769,8 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
28684
28769
  value: zeroNativeCurrencyValue,
28685
28770
  from: fromAddress,
28686
28771
  },
28687
- gasFeeEstimate,
28772
+ // TODO: TP-1649: Remove the wrapping here
28773
+ gasFeeEstimate: gasFeeEstimate ? nativeTokenService.maybeWrapAmount(gasFeeEstimate) : null,
28688
28774
  };
28689
28775
  }
28690
28776
  function prepareSwap(ourQuote, amountSpecified, fees) {
@@ -28712,7 +28798,7 @@ const CONTRACTS_FOR_CHAIN_ID = {
28712
28798
  multicall: '0xD17c98b38bA28c7eA1080317EB9AB2b9663BEd92',
28713
28799
  coreFactory: '0x8AC26EfCbf5D700b37A27aA00E6934e6904e7B8e',
28714
28800
  quoterV2: '0x0Afe6F5f4DC34461A801420634239FFaD50A2e44',
28715
- peripheryRouter: '0x5893A5c7bc615Dfd36D7383366d00FFFca5f7178',
28801
+ peripheryRouter: '0x57c73281f2697a632AEF1A48CD6ff600f49ee344',
28716
28802
  secondaryFee: '0x5893A5c7bc615Dfd36D7383366d00FFFca5f7178',
28717
28803
  },
28718
28804
  };
@@ -28722,7 +28808,8 @@ const SUPPORTED_SANDBOX_CHAINS = {
28722
28808
  rpcUrl: IMMUTABLE_TESTNET_RPC_URL,
28723
28809
  contracts: CONTRACTS_FOR_CHAIN_ID[IMMUTABLE_TESTNET_CHAIN_ID],
28724
28810
  commonRoutingTokens: IMMUTABLE_TESTNET_COMMON_ROUTING_TOKENS,
28725
- nativeToken: TIMX_IMMUTABLE_TESTNET,
28811
+ nativeToken: NATIVE_IMX_IMMUTABLE_TESTNET,
28812
+ wrappedNativeToken: TIMX_IMMUTABLE_TESTNET, // TODO: TP-1649: Change to WIMX when ready.
28726
28813
  },
28727
28814
  };
28728
28815
  const SUPPORTED_PRODUCTION_CHAINS = {};
@@ -28780,6 +28867,7 @@ class ExchangeConfiguration {
28780
28867
  contracts: overrides.exchangeContracts,
28781
28868
  commonRoutingTokens: overrides.commonRoutingTokens,
28782
28869
  nativeToken: overrides.nativeToken,
28870
+ wrappedNativeToken: overrides.wrappedNativeToken,
28783
28871
  };
28784
28872
  this.secondaryFees = secondaryFees || [];
28785
28873
  return;
@@ -28797,11 +28885,15 @@ class Exchange {
28797
28885
  router;
28798
28886
  chainId;
28799
28887
  nativeToken;
28888
+ wrappedNativeToken;
28800
28889
  secondaryFees;
28890
+ nativeTokenService;
28801
28891
  constructor(configuration) {
28802
28892
  const config = new ExchangeConfiguration(configuration);
28803
28893
  this.chainId = config.chain.chainId;
28804
28894
  this.nativeToken = config.chain.nativeToken;
28895
+ this.wrappedNativeToken = config.chain.wrappedNativeToken;
28896
+ this.nativeTokenService = new NativeTokenService(this.nativeToken, this.wrappedNativeToken);
28805
28897
  this.secondaryFees = config.secondaryFees;
28806
28898
  this.provider = new ethers.ethers.providers.JsonRpcProvider(config.chain.rpcUrl);
28807
28899
  this.router = new Router(this.provider, config.chain.commonRoutingTokens, {
@@ -28842,11 +28934,13 @@ class Exchange {
28842
28934
  this.getSecondaryFees(),
28843
28935
  ]);
28844
28936
  const tokenIn = {
28937
+ type: 'erc20',
28845
28938
  address: tokenInAddress,
28846
28939
  chainId: this.chainId,
28847
28940
  decimals: tokenInDecimals,
28848
28941
  };
28849
28942
  const tokenOut = {
28943
+ type: 'erc20',
28850
28944
  address: tokenOutAddress,
28851
28945
  chainId: this.chainId,
28852
28946
  decimals: tokenOutDecimals,
@@ -28856,18 +28950,18 @@ class Exchange {
28856
28950
  ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
28857
28951
  const amountSpecified = newAmount(amount, tokenSpecified);
28858
28952
  const fees = new Fees(secondaryFees, tokenIn);
28859
- const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType);
28953
+ const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
28860
28954
  // get quote and gas details
28861
28955
  const [ourQuote, gasPrice] = await Promise.all([
28862
28956
  this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
28863
28957
  fetchGasPrice(this.provider, this.nativeToken),
28864
28958
  ]);
28865
28959
  const adjustedQuote = prepareSwap(ourQuote, amountSpecified, fees);
28866
- const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.router.routingContracts.peripheryRouterAddress, this.router.routingContracts.secondaryFeeAddress, gasPrice, secondaryFees);
28960
+ const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.router.routingContracts.peripheryRouterAddress, this.router.routingContracts.secondaryFeeAddress, gasPrice, secondaryFees, this.nativeTokenService);
28867
28961
  const userQuote = prepareUserQuote(otherToken, adjustedQuote, slippagePercent, fees);
28868
28962
  const preparedApproval = prepareApproval(tradeType, amountSpecified, userQuote.amountWithMaxSlippage, this.router.routingContracts, secondaryFees);
28869
28963
  // preparedApproval always uses the tokenIn address because we are always selling the tokenIn
28870
- const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice);
28964
+ const approval = await getApproval(this.provider, fromAddress, preparedApproval, gasPrice, this.nativeTokenService);
28871
28965
  return {
28872
28966
  approval,
28873
28967
  swap,
@@ -31045,8 +31139,6 @@ const $5e9bcae98dc8ff19$export$1165ca270f090a66 = (isDevelopment, isProduction)=
31045
31139
  return ($d85ad1457a3f1a83$export$89133ca13c5ee30)[(Environment$1).SANDBOX];
31046
31140
  };
31047
31141
  const checkDexAvailability = async ()=>{
31048
- // TEMP FIX: Returns true for sandbox environment
31049
- if (!isDevelopment && !isProduction) return true;
31050
31142
  let response;
31051
31143
  try {
31052
31144
  response = await (0, globalAxios$1).post(`${postEndpoint()}/v1/availability/checkout/swap`);
@@ -31211,7 +31303,7 @@ const $049bba630af05555$export$6946a1f17c2bbf26 = async (config, chainId, wallet
31211
31303
  const swappableToken = fromToken[index];
31212
31304
  dexQuotes.set(swappableToken, {
31213
31305
  quote: response.value.quote,
31214
- approval: response.value.approval?.gasFeeEstimate,
31306
+ approval: response.value.approval?.gasFeeEstimate ?? null,
31215
31307
  swap: response.value.swap.gasFeeEstimate
31216
31308
  });
31217
31309
  });
@@ -32923,9 +33015,6 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
32923
33015
  * Determines the requirements for performing a buy.
32924
33016
  * @param {BuyParams} params - The parameters for the buy.
32925
33017
  */ async buy(params) {
32926
- if (this.config.isProduction) throw new Error("This endpoint is not currently available.");
32927
- // eslint-disable-next-line no-console
32928
- console.warn("This endpoint is currently under construction.");
32929
33018
  if (params.orders.length > 1) // eslint-disable-next-line no-console
32930
33019
  console.warn("This endpoint currently only processes the first order in the array.");
32931
33020
  const web3Provider = await $bb88265fe45a0393$export$9e1fd9cc88c637a0(this.config, params.provider);
@@ -32937,9 +33026,6 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
32937
33026
  * Only currently actions the first order in the array until we support batch processing.
32938
33027
  * Only currently actions the first fee in the fees array of each order until we support multiple fees.
32939
33028
  */ async sell(params) {
32940
- if (this.config.isProduction) throw new Error("This endpoint is not currently available.");
32941
- // eslint-disable-next-line no-console
32942
- console.warn("This endpoint is currently under construction.");
32943
33029
  if (params.orders.length > 1) // eslint-disable-next-line no-console
32944
33030
  console.warn("This endpoint currently only processes the first order in the array.");
32945
33031
  const web3Provider = await $bb88265fe45a0393$export$9e1fd9cc88c637a0(this.config, params.provider);
@@ -32949,9 +33035,6 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
32949
33035
  * Cancels a sell.
32950
33036
  * @param {CancelParams} params - The parameters for the cancel.
32951
33037
  */ async cancel(params) {
32952
- if (this.config.isProduction) throw new Error("This endpoint is not currently available.");
32953
- // eslint-disable-next-line no-console
32954
- console.warn("This endpoint is currently under construction.");
32955
33038
  // eslint-disable-next-line no-console
32956
33039
  console.warn("This endpoint currently only processes the first order in the array.");
32957
33040
  const web3Provider = await $bb88265fe45a0393$export$9e1fd9cc88c637a0(this.config, params.provider);
@@ -32961,9 +33044,6 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
32961
33044
  * Determines the transaction requirements to complete a purchase.
32962
33045
  * @params {SmartCheckoutParams} params - The parameters for smart checkout.
32963
33046
  */ async smartCheckout(params) {
32964
- if (this.config.isProduction) throw new Error("This endpoint is not currently available.");
32965
- // eslint-disable-next-line no-console
32966
- console.warn("This endpoint is currently under construction.");
32967
33047
  const web3Provider = await $bb88265fe45a0393$export$9e1fd9cc88c637a0(this.config, params.provider);
32968
33048
  let itemRequirements = [];
32969
33049
  try {
@@ -33078,7 +33158,7 @@ var $045213b18e9f1f94$export$75be0f6af9650f2c;
33078
33158
  })($045213b18e9f1f94$export$75be0f6af9650f2c || ($045213b18e9f1f94$export$75be0f6af9650f2c = {}));
33079
33159
 
33080
33160
 
33081
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.6";
33161
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.27.8";
33082
33162
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
33083
33163
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
33084
33164
 
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
  /**