@imtbl/sdk 0.27.9 → 0.27.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blockchain_data.js +1 -1
- package/dist/browser/checkout.js +2 -2
- package/dist/checkout_sdk.d.ts +19 -5
- package/dist/checkout_sdk.js +222 -159
- package/dist/checkout_widgets.d.ts +1 -1
- package/dist/checkout_widgets.js +2 -2
- package/dist/immutablex_client.js +1 -1
- package/dist/index.browser.js +4 -4
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +356 -264
- package/dist/index.d.ts +21 -6
- package/dist/index.js +340 -248
- package/dist/passport.d.ts +1 -0
- package/dist/passport.js +116 -87
- package/package.json +1 -1
package/dist/checkout_sdk.js
CHANGED
|
@@ -2,7 +2,8 @@ import { ethers, ContractFactory, utils, Contract as Contract$1, BigNumber as Bi
|
|
|
2
2
|
import globalAxios, { HttpStatusCode } from 'axios';
|
|
3
3
|
import { Web3Provider, JsonRpcProvider } from '@ethersproject/providers';
|
|
4
4
|
import $7v2Z6$metamaskdetectprovider from '@metamask/detect-provider';
|
|
5
|
-
import
|
|
5
|
+
import * as Uniswap from '@uniswap/sdk-core';
|
|
6
|
+
import { TradeType, Percent } from '@uniswap/sdk-core';
|
|
6
7
|
import assert from 'assert';
|
|
7
8
|
import { FeeAmount, Route, SwapQuoter, Pool, Trade, toHex as toHex$1, encodeRouteToPath } from '@uniswap/v3-sdk';
|
|
8
9
|
import { keccak256 as keccak256$1 } from '@ethersproject/solidity';
|
|
@@ -14681,13 +14682,14 @@ const quoteReturnMapping = {
|
|
|
14681
14682
|
* @param poolB the other pool
|
|
14682
14683
|
*/
|
|
14683
14684
|
function poolEquals(poolA, poolB) {
|
|
14684
|
-
return (poolA === poolB
|
|
14685
|
-
|
|
14686
|
-
&& poolA.token1.equals(poolB.token1)
|
|
14687
|
-
&& poolA.fee === poolB.fee));
|
|
14685
|
+
return (poolA === poolB ||
|
|
14686
|
+
(poolA.token0.equals(poolB.token0) && poolA.token1.equals(poolB.token1) && poolA.fee === poolB.fee));
|
|
14688
14687
|
}
|
|
14689
|
-
|
|
14690
|
-
|
|
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
|
+
}
|
|
14691
14693
|
try {
|
|
14692
14694
|
const decimalsResult = await provider.call({
|
|
14693
14695
|
to: tokenAddress,
|
|
@@ -14715,9 +14717,10 @@ function isValidNonZeroAddress(address) {
|
|
|
14715
14717
|
return false;
|
|
14716
14718
|
}
|
|
14717
14719
|
}
|
|
14720
|
+
const isValidTokenLiteral = (address) => address === 'native' ? true : isValidNonZeroAddress(address);
|
|
14718
14721
|
const erc20ToUniswapToken = (token) =>
|
|
14719
14722
|
// eslint-disable-next-line implicit-arrow-linebreak
|
|
14720
|
-
new Token(token.chainId, token.address, token.decimals, token.symbol, token.name);
|
|
14723
|
+
new Uniswap.Token(token.chainId, token.address, token.decimals, token.symbol, token.name);
|
|
14721
14724
|
const uniswapTokenToERC20 = (token) => ({
|
|
14722
14725
|
chainId: token.chainId,
|
|
14723
14726
|
address: token.address,
|
|
@@ -14728,7 +14731,7 @@ const uniswapTokenToERC20 = (token) => ({
|
|
|
14728
14731
|
});
|
|
14729
14732
|
const toCurrencyAmount = (amount) => {
|
|
14730
14733
|
const token = erc20ToUniswapToken(amount.token);
|
|
14731
|
-
return CurrencyAmount.fromRawAmount(token, amount.value.toString());
|
|
14734
|
+
return Uniswap.CurrencyAmount.fromRawAmount(token, amount.value.toString());
|
|
14732
14735
|
};
|
|
14733
14736
|
const newAmount = (amount, token) => ({
|
|
14734
14737
|
value: amount,
|
|
@@ -14774,6 +14777,28 @@ const subtractAmount = (a, b) => {
|
|
|
14774
14777
|
}
|
|
14775
14778
|
throw new Error('Token mismatch: token types must be the same');
|
|
14776
14779
|
};
|
|
14780
|
+
/**
|
|
14781
|
+
* Converts our internal token type which could be ERC20 or Native
|
|
14782
|
+
* into a format consumable by Checkout. They require an address to be
|
|
14783
|
+
* present. We populate the address with empty string if it's Native.
|
|
14784
|
+
* If it's ERC20, we don't need to change it.
|
|
14785
|
+
*/
|
|
14786
|
+
const toPublicTokenType = (token) => {
|
|
14787
|
+
if (token.type === 'native') {
|
|
14788
|
+
return {
|
|
14789
|
+
address: '',
|
|
14790
|
+
chainId: token.chainId,
|
|
14791
|
+
decimals: token.decimals,
|
|
14792
|
+
symbol: token.symbol,
|
|
14793
|
+
name: token.name,
|
|
14794
|
+
};
|
|
14795
|
+
}
|
|
14796
|
+
return token;
|
|
14797
|
+
};
|
|
14798
|
+
const toPublicAmount = (amount) => ({
|
|
14799
|
+
token: toPublicTokenType(amount.token),
|
|
14800
|
+
value: amount.value,
|
|
14801
|
+
});
|
|
14777
14802
|
|
|
14778
14803
|
const amountIndex = 0;
|
|
14779
14804
|
const gasEstimateIndex = 3;
|
|
@@ -15147,12 +15172,13 @@ const getUnsignedERC20ApproveTransaction = (ownerAddress, tokenAmount, spenderAd
|
|
|
15147
15172
|
from: ownerAddress,
|
|
15148
15173
|
};
|
|
15149
15174
|
};
|
|
15150
|
-
const prepareApproval = (tradeType,
|
|
15151
|
-
const
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
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 };
|
|
15156
15182
|
};
|
|
15157
15183
|
/**
|
|
15158
15184
|
* Get an unsigned approval transaction if needed
|
|
@@ -15184,7 +15210,7 @@ async function getApproveGasEstimate(provider, ownerAddress, spenderAddress, tok
|
|
|
15184
15210
|
from: ownerAddress,
|
|
15185
15211
|
});
|
|
15186
15212
|
}
|
|
15187
|
-
const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice
|
|
15213
|
+
const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice) => {
|
|
15188
15214
|
const approveTransaction = await getApproveTransaction(provider, ownerAddress, preparedApproval.amount, preparedApproval.spender);
|
|
15189
15215
|
if (!approveTransaction) {
|
|
15190
15216
|
return null;
|
|
@@ -15193,11 +15219,42 @@ const getApproval = async (provider, ownerAddress, preparedApproval, gasPrice, n
|
|
|
15193
15219
|
const gasFeeEstimate = gasPrice ? calculateGasFee(gasPrice, gasEstimate) : null;
|
|
15194
15220
|
return {
|
|
15195
15221
|
transaction: approveTransaction,
|
|
15196
|
-
|
|
15197
|
-
gasFeeEstimate: gasFeeEstimate ? nativeTokenService.maybeWrapAmount(gasFeeEstimate) : null,
|
|
15222
|
+
gasFeeEstimate: gasFeeEstimate ? toPublicAmount(gasFeeEstimate) : null,
|
|
15198
15223
|
};
|
|
15199
15224
|
};
|
|
15200
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
|
+
|
|
15201
15258
|
// slippageToPercent takes the slippage as a percentage (e.g. 0.1) and
|
|
15202
15259
|
// converts it to the Uniswap equivalent type
|
|
15203
15260
|
const slippageToFraction = (slippage) => {
|
|
@@ -15217,11 +15274,11 @@ const slippageToFraction = (slippage) => {
|
|
|
15217
15274
|
return new Percent(numerator, denominator);
|
|
15218
15275
|
};
|
|
15219
15276
|
|
|
15220
|
-
function getQuoteAmountFromTradeType(
|
|
15221
|
-
if (
|
|
15222
|
-
return
|
|
15277
|
+
function getQuoteAmountFromTradeType(routerQuote) {
|
|
15278
|
+
if (routerQuote.tradeType === TradeType.EXACT_INPUT) {
|
|
15279
|
+
return routerQuote.amountOut;
|
|
15223
15280
|
}
|
|
15224
|
-
return
|
|
15281
|
+
return routerQuote.amountIn;
|
|
15225
15282
|
}
|
|
15226
15283
|
function applySlippage(tradeType, amount, slippage) {
|
|
15227
15284
|
const slippageTolerance = slippageToFraction(slippage);
|
|
@@ -15230,22 +15287,18 @@ function applySlippage(tradeType, amount, slippage) {
|
|
|
15230
15287
|
const amountWithSlippage = maybeInverted.multiply(amount.toString()).quotient;
|
|
15231
15288
|
return ethers.BigNumber.from(amountWithSlippage.toString());
|
|
15232
15289
|
}
|
|
15233
|
-
|
|
15234
|
-
const
|
|
15235
|
-
|
|
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);
|
|
15236
15297
|
return {
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
token: otherToken,
|
|
15240
|
-
value: amountWithSlippage,
|
|
15241
|
-
},
|
|
15242
|
-
slippage,
|
|
15243
|
-
fees: fees.withAmounts().map((fee) => ({
|
|
15244
|
-
...fee,
|
|
15245
|
-
amount: nativeTokenService.maybeWrapAmount(fee.amount),
|
|
15246
|
-
})),
|
|
15298
|
+
quotedAmount,
|
|
15299
|
+
quotedAmountWithMaxSlippage,
|
|
15247
15300
|
};
|
|
15248
|
-
}
|
|
15301
|
+
};
|
|
15249
15302
|
function getOurQuoteReqAmount(amountSpecified, // the amount specified by the user, either exactIn or exactOut
|
|
15250
15303
|
fees, tradeType, nativeTokenService) {
|
|
15251
15304
|
if (tradeType === TradeType.EXACT_OUTPUT) {
|
|
@@ -15313,46 +15366,8 @@ class Fees {
|
|
|
15313
15366
|
}
|
|
15314
15367
|
}
|
|
15315
15368
|
|
|
15316
|
-
class NativeTokenService {
|
|
15317
|
-
nativeToken;
|
|
15318
|
-
wrappedToken;
|
|
15319
|
-
constructor(nativeToken, wrappedToken) {
|
|
15320
|
-
this.nativeToken = nativeToken;
|
|
15321
|
-
this.wrappedToken = wrappedToken;
|
|
15322
|
-
}
|
|
15323
|
-
wrapAmount(amount) {
|
|
15324
|
-
return newAmount(amount.value, this.wrappedToken);
|
|
15325
|
-
}
|
|
15326
|
-
unwrapAmount(amount) {
|
|
15327
|
-
if (amount.token !== this.wrappedToken) {
|
|
15328
|
-
throw new Error(`token ${amount.token.address} is not wrapped`);
|
|
15329
|
-
}
|
|
15330
|
-
return newAmount(amount.value, this.nativeToken);
|
|
15331
|
-
}
|
|
15332
|
-
maybeWrapToken(token) {
|
|
15333
|
-
if (this.isNativeToken(token)) {
|
|
15334
|
-
return this.wrappedToken;
|
|
15335
|
-
}
|
|
15336
|
-
return token;
|
|
15337
|
-
}
|
|
15338
|
-
maybeWrapAmount(amount) {
|
|
15339
|
-
return newAmount(amount.value, this.maybeWrapToken(amount.token));
|
|
15340
|
-
}
|
|
15341
|
-
isNativeToken(token) {
|
|
15342
|
-
return token === this.nativeToken;
|
|
15343
|
-
}
|
|
15344
|
-
}
|
|
15345
|
-
|
|
15346
15369
|
const IMMUTABLE_TESTNET_RPC_URL = 'https://rpc.testnet.immutable.com';
|
|
15347
15370
|
const IMMUTABLE_TESTNET_CHAIN_ID = 13472;
|
|
15348
|
-
|
|
15349
|
-
const NATIVE_IMX_IMMUTABLE_TESTNET = {
|
|
15350
|
-
chainId: IMMUTABLE_TESTNET_CHAIN_ID,
|
|
15351
|
-
decimals: 18,
|
|
15352
|
-
symbol: 'tIMX',
|
|
15353
|
-
name: 'Immutable Testnet Token',
|
|
15354
|
-
type: 'native',
|
|
15355
|
-
};
|
|
15356
15371
|
const TIMX_IMMUTABLE_TESTNET = {
|
|
15357
15372
|
chainId: IMMUTABLE_TESTNET_CHAIN_ID,
|
|
15358
15373
|
address: '0x0000000000000000000000000000000000001010',
|
|
@@ -15382,7 +15397,9 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
|
|
|
15382
15397
|
recipient: fee.recipient,
|
|
15383
15398
|
}));
|
|
15384
15399
|
if (trade.tradeType === TradeType.EXACT_INPUT) {
|
|
15385
|
-
return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [
|
|
15400
|
+
return secondaryFeeContract.encodeFunctionData('exactInputSingleWithSecondaryFee', [
|
|
15401
|
+
secondaryFeeValues,
|
|
15402
|
+
{
|
|
15386
15403
|
tokenIn: route.tokenPath[0].address,
|
|
15387
15404
|
tokenOut: route.tokenPath[1].address,
|
|
15388
15405
|
fee: route.pools[0].fee,
|
|
@@ -15390,9 +15407,12 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
|
|
|
15390
15407
|
amountIn,
|
|
15391
15408
|
amountOutMinimum: amountOut,
|
|
15392
15409
|
sqrtPriceLimitX96: 0,
|
|
15393
|
-
}
|
|
15410
|
+
},
|
|
15411
|
+
]);
|
|
15394
15412
|
}
|
|
15395
|
-
return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [
|
|
15413
|
+
return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithSecondaryFee', [
|
|
15414
|
+
secondaryFeeValues,
|
|
15415
|
+
{
|
|
15396
15416
|
tokenIn: route.tokenPath[0].address,
|
|
15397
15417
|
tokenOut: route.tokenPath[1].address,
|
|
15398
15418
|
fee: route.pools[0].fee,
|
|
@@ -15400,7 +15420,8 @@ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountI
|
|
|
15400
15420
|
amountInMaximum: amountIn,
|
|
15401
15421
|
amountOut,
|
|
15402
15422
|
sqrtPriceLimitX96: 0,
|
|
15403
|
-
}
|
|
15423
|
+
},
|
|
15424
|
+
]);
|
|
15404
15425
|
}
|
|
15405
15426
|
function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract) {
|
|
15406
15427
|
const path = encodeRouteToPath(route, trade.tradeType === TradeType.EXACT_OUTPUT);
|
|
@@ -15409,19 +15430,25 @@ function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn
|
|
|
15409
15430
|
recipient: fee.recipient,
|
|
15410
15431
|
}));
|
|
15411
15432
|
if (trade.tradeType === TradeType.EXACT_INPUT) {
|
|
15412
|
-
return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [
|
|
15433
|
+
return secondaryFeeContract.encodeFunctionData('exactInputWithSecondaryFee', [
|
|
15434
|
+
secondaryFeeValues,
|
|
15435
|
+
{
|
|
15413
15436
|
path,
|
|
15414
15437
|
recipient: fromAddress,
|
|
15415
15438
|
amountIn,
|
|
15416
15439
|
amountOutMinimum: amountOut,
|
|
15417
|
-
}
|
|
15440
|
+
},
|
|
15441
|
+
]);
|
|
15418
15442
|
}
|
|
15419
|
-
return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [
|
|
15443
|
+
return secondaryFeeContract.encodeFunctionData('exactOutputWithSecondaryFee', [
|
|
15444
|
+
secondaryFeeValues,
|
|
15445
|
+
{
|
|
15420
15446
|
path,
|
|
15421
15447
|
recipient: fromAddress,
|
|
15422
15448
|
amountInMaximum: amountIn,
|
|
15423
15449
|
amountOut,
|
|
15424
|
-
}
|
|
15450
|
+
},
|
|
15451
|
+
]);
|
|
15425
15452
|
}
|
|
15426
15453
|
/**
|
|
15427
15454
|
* Builds swap parameters
|
|
@@ -15446,7 +15473,10 @@ function buildSwapParameters(fromAddress, trade, options, secondaryFees, seconda
|
|
|
15446
15473
|
function createSwapCallParametersWithFees(trade, fromAddress, swapOptions, secondaryFees) {
|
|
15447
15474
|
const secondaryFeeContract = SecondaryFee__factory.createInterface();
|
|
15448
15475
|
const swapWithFeesCalldata = buildSwapParameters(fromAddress, trade, swapOptions, secondaryFees, secondaryFeeContract);
|
|
15449
|
-
return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [
|
|
15476
|
+
return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [
|
|
15477
|
+
swapOptions.deadlineOrPreviousBlockhash,
|
|
15478
|
+
[swapWithFeesCalldata],
|
|
15479
|
+
]);
|
|
15450
15480
|
}
|
|
15451
15481
|
function createSwapParameters(adjustedQuote, fromAddress, slippage, deadline, secondaryFees) {
|
|
15452
15482
|
// Create an unchecked trade to be used in generating swap parameters.
|
|
@@ -15486,7 +15516,7 @@ function getSwap(adjustedQuote, fromAddress, slippage, deadline, peripheryRouter
|
|
|
15486
15516
|
const adjustAmountIn = (ourQuote, amountSpecified, fees, nativeTokenService) => {
|
|
15487
15517
|
if (ourQuote.tradeType === TradeType.EXACT_OUTPUT) {
|
|
15488
15518
|
// when doing exact output, calculate the fees based on the amountIn
|
|
15489
|
-
const amountToAdd =
|
|
15519
|
+
const amountToAdd = canUnwrapToken(fees.token)
|
|
15490
15520
|
? nativeTokenService.unwrapAmount(ourQuote.amountIn)
|
|
15491
15521
|
: ourQuote.amountIn;
|
|
15492
15522
|
fees.addAmount(amountToAdd);
|
|
@@ -15530,7 +15560,7 @@ const SUPPORTED_SANDBOX_CHAINS = {
|
|
|
15530
15560
|
rpcUrl: IMMUTABLE_TESTNET_RPC_URL,
|
|
15531
15561
|
contracts: CONTRACTS_FOR_CHAIN_ID[IMMUTABLE_TESTNET_CHAIN_ID],
|
|
15532
15562
|
commonRoutingTokens: IMMUTABLE_TESTNET_COMMON_ROUTING_TOKENS,
|
|
15533
|
-
nativeToken:
|
|
15563
|
+
nativeToken: TIMX_IMMUTABLE_TESTNET,
|
|
15534
15564
|
wrappedNativeToken: TIMX_IMMUTABLE_TESTNET, // TODO: TP-1649: Change to WIMX when ready.
|
|
15535
15565
|
},
|
|
15536
15566
|
};
|
|
@@ -15602,6 +15632,15 @@ class ExchangeConfiguration {
|
|
|
15602
15632
|
}
|
|
15603
15633
|
}
|
|
15604
15634
|
|
|
15635
|
+
const toPublicQuote = (amount, amountWithMaxSlippage, slippage, fees) => ({
|
|
15636
|
+
amount: toPublicAmount(amount),
|
|
15637
|
+
amountWithMaxSlippage: toPublicAmount(amountWithMaxSlippage),
|
|
15638
|
+
slippage,
|
|
15639
|
+
fees: fees.withAmounts().map((fee) => ({
|
|
15640
|
+
...fee,
|
|
15641
|
+
amount: toPublicAmount(fee.amount),
|
|
15642
|
+
})),
|
|
15643
|
+
});
|
|
15605
15644
|
class Exchange {
|
|
15606
15645
|
provider;
|
|
15607
15646
|
router;
|
|
@@ -15630,8 +15669,8 @@ class Exchange {
|
|
|
15630
15669
|
}
|
|
15631
15670
|
static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
|
|
15632
15671
|
assert(isValidNonZeroAddress(fromAddress), new InvalidAddressError('invalid from address'));
|
|
15633
|
-
assert(
|
|
15634
|
-
assert(
|
|
15672
|
+
assert(isValidTokenLiteral(tokenInAddress), new InvalidAddressError('invalid token in address'));
|
|
15673
|
+
assert(isValidTokenLiteral(tokenOutAddress), new InvalidAddressError('invalid token out address'));
|
|
15635
15674
|
assert(tokenInAddress.toLocaleLowerCase() !== tokenOutAddress.toLocaleLowerCase(), new DuplicateAddressesError());
|
|
15636
15675
|
assert(maxHops <= MAX_MAX_HOPS, new InvalidMaxHopsError('max hops must be less than or equal to 10'));
|
|
15637
15676
|
assert(maxHops >= MIN_MAX_HOPS, new InvalidMaxHopsError('max hops must be greater than or equal to 1'));
|
|
@@ -15649,63 +15688,63 @@ class Exchange {
|
|
|
15649
15688
|
}
|
|
15650
15689
|
return this.secondaryFees;
|
|
15651
15690
|
}
|
|
15652
|
-
|
|
15653
|
-
|
|
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);
|
|
15654
15704
|
// get the decimals of the tokens that will be swapped
|
|
15655
15705
|
const [tokenInDecimals, tokenOutDecimals, secondaryFees] = await Promise.all([
|
|
15656
|
-
|
|
15657
|
-
|
|
15706
|
+
getTokenDecimals(tokenInLiteral, this.provider, this.nativeToken),
|
|
15707
|
+
getTokenDecimals(tokenOutLiteral, this.provider, this.nativeToken),
|
|
15658
15708
|
this.getSecondaryFees(),
|
|
15659
15709
|
]);
|
|
15660
|
-
const tokenIn =
|
|
15661
|
-
|
|
15662
|
-
address: tokenInAddress,
|
|
15663
|
-
chainId: this.chainId,
|
|
15664
|
-
decimals: tokenInDecimals,
|
|
15665
|
-
};
|
|
15666
|
-
const tokenOut = {
|
|
15667
|
-
type: 'erc20',
|
|
15668
|
-
address: tokenOutAddress,
|
|
15669
|
-
chainId: this.chainId,
|
|
15670
|
-
decimals: tokenOutDecimals,
|
|
15671
|
-
};
|
|
15710
|
+
const tokenIn = this.parseTokenLiteral(tokenInLiteral, tokenInDecimals);
|
|
15711
|
+
const tokenOut = this.parseTokenLiteral(tokenOutLiteral, tokenOutDecimals);
|
|
15672
15712
|
// determine which amount was specified for the swap from the TradeType
|
|
15673
15713
|
const [tokenSpecified, otherToken] = tradeType === TradeType.EXACT_INPUT ? [tokenIn, tokenOut] : [tokenOut, tokenIn];
|
|
15674
15714
|
const amountSpecified = newAmount(amount, tokenSpecified);
|
|
15675
15715
|
const fees = new Fees(secondaryFees, tokenIn);
|
|
15676
15716
|
const ourQuoteReqAmount = getOurQuoteReqAmount(amountSpecified, fees, tradeType, this.nativeTokenService);
|
|
15677
|
-
//
|
|
15717
|
+
// Quotes will always use ERC20s. If the user-specified token is Native, we use the Wrapped Native Token pool
|
|
15678
15718
|
const [ourQuote, gasPrice] = await Promise.all([
|
|
15679
|
-
this.router.findOptimalRoute(ourQuoteReqAmount, otherToken, tradeType, maxHops),
|
|
15719
|
+
this.router.findOptimalRoute(ourQuoteReqAmount, this.nativeTokenService.maybeWrapToken(otherToken), tradeType, maxHops),
|
|
15680
15720
|
fetchGasPrice(this.provider, this.nativeToken),
|
|
15681
15721
|
]);
|
|
15682
15722
|
const adjustedQuote = adjustQuoteWithFees(ourQuote, amountSpecified, fees, this.nativeTokenService);
|
|
15683
15723
|
const swap = getSwap(adjustedQuote, fromAddress, slippagePercent, deadline, this.routerContractAddress, this.secondaryFeeContractAddress, gasPrice, secondaryFees, this.nativeTokenService);
|
|
15684
|
-
const
|
|
15685
|
-
const preparedApproval = prepareApproval(tradeType, amountSpecified,
|
|
15724
|
+
const { quotedAmount, quotedAmountWithMaxSlippage } = prepareUserQuote(this.nativeTokenService, adjustedQuote, slippagePercent, otherToken);
|
|
15725
|
+
const preparedApproval = prepareApproval(tradeType, amountSpecified, quotedAmountWithMaxSlippage, {
|
|
15686
15726
|
routerAddress: this.routerContractAddress,
|
|
15687
15727
|
secondaryFeeAddress: this.secondaryFeeContractAddress,
|
|
15688
15728
|
}, secondaryFees);
|
|
15689
15729
|
// preparedApproval always uses the tokenIn address because we are always selling the tokenIn
|
|
15690
|
-
const approval =
|
|
15691
|
-
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
};
|
|
15730
|
+
const approval = preparedApproval
|
|
15731
|
+
? await getApproval(this.provider, fromAddress, preparedApproval, gasPrice)
|
|
15732
|
+
: null;
|
|
15733
|
+
const quote = toPublicQuote(quotedAmount, quotedAmountWithMaxSlippage, slippagePercent, fees);
|
|
15734
|
+
return { quote, approval, swap };
|
|
15696
15735
|
}
|
|
15697
15736
|
/**
|
|
15698
15737
|
* Get the unsigned swap transaction given the amount to sell.
|
|
15699
15738
|
* Includes quote details for the swap.
|
|
15700
15739
|
*
|
|
15701
|
-
* @param {string} fromAddress The public address that will sign and submit the transaction
|
|
15702
|
-
* @param {string} tokenInAddress Token address to sell
|
|
15703
|
-
* @param {string} tokenOutAddress Token address to buy
|
|
15704
|
-
* @param {ethers.BigNumberish} amountIn Amount to sell
|
|
15705
|
-
* @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
|
|
15706
|
-
* @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
|
|
15707
|
-
* @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
|
|
15708
|
-
* @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
|
|
15709
15748
|
*/
|
|
15710
15749
|
async getUnsignedSwapTxFromAmountIn(fromAddress, tokenInAddress, tokenOutAddress, amountIn, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
|
|
15711
15750
|
return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.BigNumber.from(amountIn), slippagePercent, maxHops, deadline, TradeType.EXACT_INPUT);
|
|
@@ -15714,14 +15753,14 @@ class Exchange {
|
|
|
15714
15753
|
* Get the unsigned swap transaction given the amount to buy.
|
|
15715
15754
|
* Includes quote details for the swap.
|
|
15716
15755
|
*
|
|
15717
|
-
* @param {string} fromAddress The public address that will sign and submit the transaction
|
|
15718
|
-
* @param {string} tokenInAddress
|
|
15719
|
-
* @param {string} tokenOutAddress
|
|
15720
|
-
* @param {ethers.BigNumberish} amountOut Amount to buy
|
|
15721
|
-
* @param {number} slippagePercent (optional) The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0
|
|
15722
|
-
* @param {number} maxHops (optional) Maximum hops allowed in optimal route. Default is 2
|
|
15723
|
-
* @param {number} deadline (optional) Latest time swap can execute. Default is 15 minutes
|
|
15724
|
-
* @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
|
|
15725
15764
|
*/
|
|
15726
15765
|
async getUnsignedSwapTxFromAmountOut(fromAddress, tokenInAddress, tokenOutAddress, amountOut, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
|
|
15727
15766
|
return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, ethers.BigNumber.from(amountOut), slippagePercent, maxHops, deadline, TradeType.EXACT_OUTPUT);
|
|
@@ -20548,7 +20587,7 @@ class APIError extends Error {
|
|
|
20548
20587
|
|
|
20549
20588
|
/* eslint-disable implicit-arrow-linebreak */
|
|
20550
20589
|
const defaultHeaders = {
|
|
20551
|
-
sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.
|
|
20590
|
+
sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.27.11',
|
|
20552
20591
|
};
|
|
20553
20592
|
/**
|
|
20554
20593
|
* createAPIConfiguration to create a custom Configuration
|
|
@@ -21174,6 +21213,14 @@ const $d85ad1457a3f1a83$export$fc55ed5a42b458ba = {
|
|
|
21174
21213
|
[($0472f23319457bfb$export$c06e1e7429de6283).IMTBL_ZKEVM_MAINNET]: {
|
|
21175
21214
|
url: "https://explorer.mainnet.immutable.com",
|
|
21176
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
|
|
21177
21224
|
}
|
|
21178
21225
|
};
|
|
21179
21226
|
const $d85ad1457a3f1a83$export$db5daa1b5156ccfe = [
|
|
@@ -21773,6 +21820,7 @@ const $efe60cea83bfc4e8$export$473cec51305fdae8 = async (config, { type: type =
|
|
|
21773
21820
|
|
|
21774
21821
|
|
|
21775
21822
|
|
|
21823
|
+
|
|
21776
21824
|
const $fd8a8472dcc3ec2b$var$CACHE_DATA_TTL = 60; // seconds
|
|
21777
21825
|
class $fd8a8472dcc3ec2b$export$ef140a6b05dfc786 {
|
|
21778
21826
|
url;
|
|
@@ -21945,18 +21993,23 @@ async function $1564e43dde50bb61$export$60e0fe116a0e6ed0(web3Provider, walletAdd
|
|
|
21945
21993
|
type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_ERC20_BALANCE_ERROR
|
|
21946
21994
|
});
|
|
21947
21995
|
}
|
|
21948
|
-
// Blockscout client singleton
|
|
21949
|
-
|
|
21950
|
-
const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
|
|
21996
|
+
// Blockscout client singleton per chain id
|
|
21997
|
+
const $1564e43dde50bb61$var$blockscoutClientMap = new Map();
|
|
21998
|
+
const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId, filterTokens)=>{
|
|
21951
21999
|
// Shuffle the mapping of the tokens configuration so it is a hashmap
|
|
21952
22000
|
// for faster access to tokens config objects.
|
|
21953
|
-
const
|
|
22001
|
+
const shouldFilter = filterTokens.length > 0;
|
|
22002
|
+
const mapFilterTokens = Object.assign({}, ...filterTokens.map((t)=>({
|
|
21954
22003
|
[t.address || ""]: t
|
|
21955
22004
|
})));
|
|
21956
|
-
//
|
|
21957
|
-
|
|
21958
|
-
|
|
21959
|
-
|
|
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
|
+
}
|
|
21960
22013
|
// Hold the items in an array for post-fetching processing
|
|
21961
22014
|
const items = [];
|
|
21962
22015
|
const tokenType = ($887a00f8f72d61f0$export$5bd1ea2b3d18210).ERC20;
|
|
@@ -21966,7 +22019,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
|
|
|
21966
22019
|
try {
|
|
21967
22020
|
do {
|
|
21968
22021
|
// eslint-disable-next-line no-await-in-loop
|
|
21969
|
-
resp = await
|
|
22022
|
+
resp = await blockscoutClient.getTokensByWalletAddress({
|
|
21970
22023
|
walletAddress: walletAddress,
|
|
21971
22024
|
tokenType: tokenType,
|
|
21972
22025
|
nextPage: resp?.next_page_params
|
|
@@ -21984,7 +22037,7 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
|
|
|
21984
22037
|
if (err?.code !== (HttpStatusCode).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getTokensByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
|
|
21985
22038
|
}
|
|
21986
22039
|
try {
|
|
21987
|
-
const respNative = await
|
|
22040
|
+
const respNative = await blockscoutClient.getNativeTokenByWalletAddress({
|
|
21988
22041
|
walletAddress: walletAddress
|
|
21989
22042
|
});
|
|
21990
22043
|
items.push(respNative);
|
|
@@ -21998,24 +22051,26 @@ const $1564e43dde50bb61$export$8c978679845804d4 = async (walletAddress, chainId,
|
|
|
21998
22051
|
// or simply an incorrect wallet address was provided.
|
|
21999
22052
|
if (err?.code !== (HttpStatusCode).NotFound) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(err.message || "InternalServerError | getNativeTokenByWalletAddress", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_INDEXER_BALANCE_ERROR, err);
|
|
22000
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
|
+
});
|
|
22001
22072
|
return {
|
|
22002
|
-
balances:
|
|
22003
|
-
const tokenData = item.token || {};
|
|
22004
|
-
const balance = (BigNumber$1).from(item.value);
|
|
22005
|
-
const renamed = mapRename[tokenData.address] || {};
|
|
22006
|
-
const token = {
|
|
22007
|
-
...tokenData,
|
|
22008
|
-
name: renamed.name ?? tokenData.name,
|
|
22009
|
-
symbol: renamed.symbol ?? tokenData.symbol,
|
|
22010
|
-
decimals: parseInt(tokenData.decimals, 10)
|
|
22011
|
-
};
|
|
22012
|
-
const formattedBalance = (utils).formatUnits(item.value, token.decimals);
|
|
22013
|
-
return {
|
|
22014
|
-
balance: balance,
|
|
22015
|
-
formattedBalance: formattedBalance,
|
|
22016
|
-
token: token
|
|
22017
|
-
};
|
|
22018
|
-
})
|
|
22073
|
+
balances: balances
|
|
22019
22074
|
};
|
|
22020
22075
|
};
|
|
22021
22076
|
const $1564e43dde50bb61$export$a3238cee431627c6 = async (config, web3Provider, walletAddress, tokens)=>{
|
|
@@ -22046,7 +22101,15 @@ const $1564e43dde50bb61$export$fee49741664a4d7e = async (config, web3Provider, w
|
|
|
22046
22101
|
// eslint-disable-next-line no-console
|
|
22047
22102
|
console.error(err);
|
|
22048
22103
|
}
|
|
22049
|
-
if (flag && ($fd8a8472dcc3ec2b$export$ef140a6b05dfc786).isChainSupported(chainId))
|
|
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
|
+
}
|
|
22050
22113
|
// This fallback to use ERC20s calls which is a best effort solution
|
|
22051
22114
|
// Fails in fetching data from the RCP calls might result in some
|
|
22052
22115
|
// missing data.
|
|
@@ -25020,7 +25083,7 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
|
|
|
25020
25083
|
const tokenList = await $efe60cea83bfc4e8$export$473cec51305fdae8(this.config, {
|
|
25021
25084
|
type: ($08d5ddc39acd6833$export$fd9b17d87f4121d2).ONRAMP
|
|
25022
25085
|
});
|
|
25023
|
-
const token = tokenList.tokens
|
|
25086
|
+
const token = tokenList.tokens?.find((t)=>t.address?.toLowerCase() === params.tokenAddress?.toLowerCase());
|
|
25024
25087
|
if (token) {
|
|
25025
25088
|
tokenAmount = params.tokenAmount;
|
|
25026
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
|
-
|
|
25621
|
+
IMTBL_SALE_WIDGET_EVENT = "imtbl-sale-widget"
|
|
25622
25622
|
}
|
|
25623
25623
|
/**
|
|
25624
25624
|
* Represents an event emitted by a widget.
|