@imtbl/sdk 0.37.0 → 0.39.0

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
@@ -61,7 +61,7 @@ class ImmutableConfiguration {
61
61
  }
62
62
  }
63
63
  const API_KEY_PREFIX = 'sk_imapik-';
64
- const PUBLISHABLE_KEY_PREFIX = 'pk_imapik-';
64
+ const PUBLISHABLE_KEY_PREFIX$1 = 'pk_imapik-';
65
65
  const addApiKeyToAxiosHeader = (apiKey) => {
66
66
  if (!apiKey.startsWith(API_KEY_PREFIX)) {
67
67
  throw new Error('Invalid API key. Create your api key in Immutable developer hub. https://hub.immutable.com');
@@ -69,7 +69,7 @@ const addApiKeyToAxiosHeader = (apiKey) => {
69
69
  globalAxios$1.defaults.headers.common['x-immutable-api-key'] = apiKey;
70
70
  };
71
71
  const addPublishableKeyToAxiosHeader = (publishableKey) => {
72
- if (!publishableKey.startsWith(PUBLISHABLE_KEY_PREFIX)) {
72
+ if (!publishableKey.startsWith(PUBLISHABLE_KEY_PREFIX$1)) {
73
73
  throw new Error('Invalid Publishable key. Create your Publishable key in Immutable developer hub.'
74
74
  + ' https://hub.immutable.com');
75
75
  }
@@ -4256,7 +4256,7 @@ class MultiRollupApiClients {
4256
4256
  }
4257
4257
 
4258
4258
  // eslint-disable-next-line @typescript-eslint/naming-convention
4259
- const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.37.0' };
4259
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.39.0' };
4260
4260
  const createConfig = ({ basePath, headers, }) => {
4261
4261
  if (!basePath.trim()) {
4262
4262
  throw Error('basePath can not be empty');
@@ -4316,7 +4316,7 @@ class APIError extends Error {
4316
4316
 
4317
4317
  /* eslint-disable implicit-arrow-linebreak */
4318
4318
  const defaultHeaders = {
4319
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.37.0',
4319
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.39.0',
4320
4320
  };
4321
4321
  /**
4322
4322
  * createAPIConfiguration to create a custom Configuration
@@ -4755,7 +4755,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
4755
4755
  chainID,
4756
4756
  coreContractAddress,
4757
4757
  registrationContractAddress,
4758
- sdkVersion: 'ts-immutable-sdk-0.37.0',
4758
+ sdkVersion: 'ts-immutable-sdk-0.39.0',
4759
4759
  });
4760
4760
  /**
4761
4761
  * Sets `sdkVersion` at the time of build
@@ -34802,6 +34802,7 @@ var ConnectEventType;
34802
34802
  ConnectEventType["CLOSE_WIDGET"] = "close-widget";
34803
34803
  ConnectEventType["SUCCESS"] = "success";
34804
34804
  ConnectEventType["FAILURE"] = "failure";
34805
+ ConnectEventType["LANGUAGE_CHANGED"] = "language-changed";
34805
34806
  })(ConnectEventType || (ConnectEventType = {}));
34806
34807
 
34807
34808
  /**
@@ -34812,6 +34813,7 @@ var WalletEventType;
34812
34813
  WalletEventType["CLOSE_WIDGET"] = "close-widget";
34813
34814
  WalletEventType["NETWORK_SWITCH"] = "network-switch";
34814
34815
  WalletEventType["DISCONNECT_WALLET"] = "disconnect-wallet";
34816
+ WalletEventType["LANGUAGE_CHANGED"] = "language-changed";
34815
34817
  })(WalletEventType || (WalletEventType = {}));
34816
34818
 
34817
34819
  /**
@@ -34823,6 +34825,7 @@ var SwapEventType;
34823
34825
  SwapEventType["SUCCESS"] = "success";
34824
34826
  SwapEventType["FAILURE"] = "failure";
34825
34827
  SwapEventType["REJECTED"] = "rejected";
34828
+ SwapEventType["LANGUAGE_CHANGED"] = "language-changed";
34826
34829
  })(SwapEventType || (SwapEventType = {}));
34827
34830
 
34828
34831
  /**
@@ -34835,6 +34838,7 @@ var SaleEventType;
34835
34838
  SaleEventType["FAILURE"] = "failure";
34836
34839
  SaleEventType["REJECTED"] = "rejected";
34837
34840
  SaleEventType["TRANSACTION_SUCCESS"] = "transaction-success";
34841
+ SaleEventType["LANGUAGE_CHANGED"] = "language-changed";
34838
34842
  })(SaleEventType || (SaleEventType = {}));
34839
34843
 
34840
34844
  /**
@@ -34845,6 +34849,7 @@ var BridgeEventType;
34845
34849
  BridgeEventType["CLOSE_WIDGET"] = "close-widget";
34846
34850
  BridgeEventType["FAILURE"] = "failure";
34847
34851
  BridgeEventType["TRANSACTION_SENT"] = "transaction-sent";
34852
+ BridgeEventType["LANGUAGE_CHANGED"] = "language-changed";
34848
34853
  })(BridgeEventType || (BridgeEventType = {}));
34849
34854
 
34850
34855
  /**
@@ -34867,6 +34872,7 @@ var OnRampEventType;
34867
34872
  OnRampEventType["CLOSE_WIDGET"] = "close-widget";
34868
34873
  OnRampEventType["SUCCESS"] = "success";
34869
34874
  OnRampEventType["FAILURE"] = "failure";
34875
+ OnRampEventType["LANGUAGE_CHANGED"] = "language-changed";
34870
34876
  })(OnRampEventType || (OnRampEventType = {}));
34871
34877
 
34872
34878
  /**
@@ -35255,7 +35261,11 @@ async function addNetworkToWallet(networkMap, web3Provider, chainId) {
35255
35261
  async function getNetworkAllowList(config, { type = NetworkFilterTypes.ALL, exclude }) {
35256
35262
  const { networkMap } = config;
35257
35263
  const allowedNetworkConfig = (await config.remote.getConfig('allowedNetworks'));
35258
- const list = allowedNetworkConfig.filter((network) => {
35264
+ if (!allowedNetworkConfig) {
35265
+ // eslint-disable-next-line no-console
35266
+ console.warn('No allowed networks configured');
35267
+ }
35268
+ const list = (allowedNetworkConfig || []).filter((network) => {
35259
35269
  const allowAllTokens = type === NetworkFilterTypes.ALL;
35260
35270
  const networkNotExcluded = !(exclude || [])
35261
35271
  .map((exc) => exc.chainId)
@@ -35695,32 +35705,21 @@ const GAS_OVERRIDES = {
35695
35705
  maxPriorityFeePerGas: ethers.BigNumber.from(101e9),
35696
35706
  };
35697
35707
 
35698
- const SDK_VERSION_MARKER = '0.37.0';
35708
+ const SDK_VERSION_MARKER = '0.39.0';
35699
35709
  // This SDK version is replaced by the `yarn build` command ran on the root level
35700
35710
  const globalPackageVersion = () => SDK_VERSION_MARKER;
35701
35711
 
35702
35712
  class RemoteConfigFetcher {
35713
+ httpClient;
35703
35714
  isDevelopment;
35704
35715
  isProduction;
35705
35716
  configCache;
35706
35717
  tokensCache;
35707
35718
  version = 'v1';
35708
- constructor(params) {
35719
+ constructor(httpClient, params) {
35709
35720
  this.isDevelopment = params.isDevelopment;
35710
35721
  this.isProduction = params.isProduction;
35711
- }
35712
- static async makeHttpRequest(url) {
35713
- let response;
35714
- try {
35715
- response = await globalAxios$1.get(url);
35716
- }
35717
- catch (error) {
35718
- throw new CheckoutError(`Error fetching from api: ${error.message}`, CheckoutErrorType.API_ERROR);
35719
- }
35720
- if (response.status !== 200) {
35721
- throw new CheckoutError(`Error fetching from api: ${response.status} ${response.statusText}`, CheckoutErrorType.API_ERROR);
35722
- }
35723
- return response;
35722
+ this.httpClient = httpClient;
35724
35723
  }
35725
35724
  getEndpoint = () => {
35726
35725
  if (this.isDevelopment)
@@ -35729,18 +35728,33 @@ class RemoteConfigFetcher {
35729
35728
  return CHECKOUT_CDN_BASE_URL[Environment$1.PRODUCTION];
35730
35729
  return CHECKOUT_CDN_BASE_URL[Environment$1.SANDBOX];
35731
35730
  };
35731
+ // eslint-disable-next-line class-methods-use-this
35732
+ parseResponse(response) {
35733
+ let responseData = response.data;
35734
+ if (response.data && typeof response.data !== 'object') {
35735
+ try {
35736
+ responseData = JSON.parse(response.data);
35737
+ }
35738
+ catch (jsonError) {
35739
+ throw new CheckoutError('Invalid configuration', CheckoutErrorType.API_ERROR);
35740
+ }
35741
+ }
35742
+ return responseData;
35743
+ }
35732
35744
  async loadConfig() {
35733
35745
  if (this.configCache)
35734
35746
  return this.configCache;
35735
- const response = await RemoteConfigFetcher.makeHttpRequest(`${this.getEndpoint()}/${this.version}/config`);
35736
- this.configCache = response.data;
35747
+ const response = await this.httpClient.get(`${this.getEndpoint()}/${this.version}/config`);
35748
+ // Ensure that the configuration is valid
35749
+ this.configCache = this.parseResponse(response);
35737
35750
  return this.configCache;
35738
35751
  }
35739
35752
  async loadConfigTokens() {
35740
35753
  if (this.tokensCache)
35741
35754
  return this.tokensCache;
35742
- const response = await RemoteConfigFetcher.makeHttpRequest(`${this.getEndpoint()}/${this.version}/config/tokens`);
35743
- this.tokensCache = response.data;
35755
+ const response = await this.httpClient.get(`${this.getEndpoint()}/${this.version}/config/tokens`);
35756
+ // Ensure that the configuration is valid
35757
+ this.tokensCache = this.parseResponse(response);
35744
35758
  return this.tokensCache;
35745
35759
  }
35746
35760
  async getConfig(key) {
@@ -35757,6 +35771,7 @@ class RemoteConfigFetcher {
35757
35771
  return {};
35758
35772
  return config[chainId] ?? [];
35759
35773
  }
35774
+ getHttpClient = () => this.httpClient;
35760
35775
  }
35761
35776
 
35762
35777
  class CheckoutConfigurationError extends Error {
@@ -35807,7 +35822,7 @@ class CheckoutConfiguration {
35807
35822
  remote;
35808
35823
  environment;
35809
35824
  networkMap;
35810
- constructor(config) {
35825
+ constructor(config, httpClient) {
35811
35826
  if (!Object.values(Environment$1).includes(config.baseConfig.environment)) {
35812
35827
  throw new CheckoutConfigurationError('Invalid checkout configuration of environment');
35813
35828
  }
@@ -35818,7 +35833,7 @@ class CheckoutConfiguration {
35818
35833
  this.isSwapEnabled = config.swap?.enable ?? DEFAULT_SWAP_ENABLED;
35819
35834
  this.isBridgeEnabled = config.bridge?.enable ?? DEFAULT_BRIDGE_ENABLED;
35820
35835
  this.networkMap = networkMap(this.isProduction, this.isDevelopment);
35821
- this.remote = new RemoteConfigFetcher({
35836
+ this.remote = new RemoteConfigFetcher(httpClient, {
35822
35837
  isDevelopment: this.isDevelopment,
35823
35838
  isProduction: this.isProduction,
35824
35839
  });
@@ -35883,9 +35898,7 @@ class Blockscout {
35883
35898
  ttl;
35884
35899
  chainId;
35885
35900
  cacheMap;
35886
- static async makeHttpRequest(url) {
35887
- return globalAxios$1.get(url);
35888
- }
35901
+ httpClient;
35889
35902
  setCache(key, data) {
35890
35903
  this.cacheMap[key] = { data, ttl: new Date().getTime() + this.ttl * 1000 };
35891
35904
  }
@@ -35897,11 +35910,13 @@ class Blockscout {
35897
35910
  }
35898
35911
  /**
35899
35912
  * Blockscout constructor
35913
+ * @param httpClient Client used for http requests
35900
35914
  * @param chainId target chain
35901
35915
  * @param ttl cache TTL
35902
35916
  */
35903
- constructor(params) {
35904
- this.chainId = params.chainId;
35917
+ constructor(httpClient, chainId, ttl) {
35918
+ this.httpClient = httpClient;
35919
+ this.chainId = chainId;
35905
35920
  this.url = BLOCKSCOUT_CHAIN_URL_MAP[this.chainId].url;
35906
35921
  const native = BLOCKSCOUT_CHAIN_URL_MAP[this.chainId].nativeToken;
35907
35922
  this.nativeToken = {
@@ -35911,7 +35926,7 @@ class Blockscout {
35911
35926
  symbol: native.symbol,
35912
35927
  };
35913
35928
  this.cacheMap = {};
35914
- this.ttl = params.ttl !== undefined ? params.ttl : CACHE_DATA_TTL;
35929
+ this.ttl = ttl !== undefined ? ttl : CACHE_DATA_TTL;
35915
35930
  }
35916
35931
  /**
35917
35932
  * isChainSupported verifies if the chain is supported by Blockscout
@@ -35939,7 +35954,7 @@ class Blockscout {
35939
35954
  const cached = this.getCache(url);
35940
35955
  if (cached)
35941
35956
  return Promise.resolve(cached);
35942
- const response = await Blockscout.makeHttpRequest(url);
35957
+ const response = await this.httpClient.get(url);
35943
35958
  if (response.status >= 400) {
35944
35959
  return Promise.reject({
35945
35960
  code: response.status,
@@ -35980,7 +35995,7 @@ class Blockscout {
35980
35995
  const cached = this.getCache(url);
35981
35996
  if (cached)
35982
35997
  return Promise.resolve(cached);
35983
- const response = await Blockscout.makeHttpRequest(url);
35998
+ const response = await this.httpClient.get(url);
35984
35999
  if (response.status >= 400) {
35985
36000
  return Promise.reject({
35986
36001
  code: response.status,
@@ -36065,7 +36080,7 @@ const blockscoutClientMap = new Map();
36065
36080
  // This function is a utility function that can be used to reset the
36066
36081
  // blockscout map and therefore clear all the cache.
36067
36082
  const resetBlockscoutClientMap = () => blockscoutClientMap.clear();
36068
- const getIndexerBalance = async (walletAddress, chainId, filterTokens) => {
36083
+ const getIndexerBalance = async (config, walletAddress, chainId, filterTokens) => {
36069
36084
  // Shuffle the mapping of the tokens configuration so it is a hashmap
36070
36085
  // for faster access to tokens config objects.
36071
36086
  const shouldFilter = filterTokens !== undefined;
@@ -36073,7 +36088,8 @@ const getIndexerBalance = async (walletAddress, chainId, filterTokens) => {
36073
36088
  // Get blockscout client for the given chain
36074
36089
  let blockscoutClient = blockscoutClientMap.get(chainId);
36075
36090
  if (!blockscoutClient) {
36076
- blockscoutClient = new Blockscout({ chainId });
36091
+ const httpClient = config.remote.getHttpClient();
36092
+ blockscoutClient = new Blockscout(httpClient, chainId);
36077
36093
  blockscoutClientMap.set(chainId, blockscoutClient);
36078
36094
  }
36079
36095
  // Hold the items in an array for post-fetching processing
@@ -36208,7 +36224,7 @@ const getAllBalances = async (config, web3Provider, walletAddress, chainId) => {
36208
36224
  const isL1Chain = getL1ChainId(config) === chainId;
36209
36225
  if (!address)
36210
36226
  address = await web3Provider?.getSigner().getAddress();
36211
- return await measureAsyncExecution(config, `Time to fetch balances using blockscout for ${chainId}`, getIndexerBalance(address, chainId, isL1Chain ? tokens : undefined));
36227
+ return await measureAsyncExecution(config, `Time to fetch balances using blockscout for ${chainId}`, getIndexerBalance(config, address, chainId, isL1Chain ? tokens : undefined));
36212
36228
  }
36213
36229
  if (!web3Provider) {
36214
36230
  throw new CheckoutError('indexer is disabled for this chain, you must provide a provider.', CheckoutErrorType.MISSING_PARAMS);
@@ -37892,8 +37908,8 @@ const bridgeRoute = async (config, readOnlyProviders, availableRoutingOptions, b
37892
37908
  if (tokenBalanceResult === undefined || tokenBalanceResult.success === false)
37893
37909
  return undefined;
37894
37910
  // todo: revert this back to using the allowlist
37895
- const allowedTokenList = await allowListCheckForBridge(config, tokenBalanceResults, availableRoutingOptions);
37896
- if (allowedTokenList.length === 0)
37911
+ const allowedL1TokenList = await allowListCheckForBridge(config, tokenBalanceResults, availableRoutingOptions);
37912
+ if (allowedL1TokenList.length === 0)
37897
37913
  return undefined;
37898
37914
  const l1RepresentationResult = await fetchL1Representation(config, bridgeRequirement.l2address);
37899
37915
  if (!l1RepresentationResult)
@@ -37901,10 +37917,10 @@ const bridgeRoute = async (config, readOnlyProviders, availableRoutingOptions, b
37901
37917
  // Ensure l1address is in the allowed token list
37902
37918
  const { l1address } = l1RepresentationResult;
37903
37919
  if (isNativeToken(l1address)) {
37904
- if (!allowedTokenList.find((token) => !('address' in token)))
37920
+ if (!allowedL1TokenList.find((token) => isNativeToken(token.address)))
37905
37921
  return undefined;
37906
37922
  }
37907
- else if (!allowedTokenList.find((token) => token.address === l1address)) {
37923
+ else if (!allowedL1TokenList.find((token) => token.address === l1address)) {
37908
37924
  return undefined;
37909
37925
  }
37910
37926
  const feesFromBridge = await getBridgeFeeEstimate(config, readOnlyProviders, l1ChainId, l2ChainId);
@@ -39201,6 +39217,90 @@ function loadUnresolved(version) {
39201
39217
  return { loaded: false, element: tag };
39202
39218
  }
39203
39219
 
39220
+ const PUBLISHABLE_KEY_PREFIX = 'pk_imapik-';
39221
+ const publishableKeyDomainAllowlist = [
39222
+ 'https://checkout-api.dev.immutable.com',
39223
+ 'https://checkout-api.sandbox.immutable.com',
39224
+ 'https://checkout-api.immutable.com',
39225
+ ];
39226
+ class HttpClient {
39227
+ config;
39228
+ axiosInstance;
39229
+ constructor(config) {
39230
+ this.config = config;
39231
+ this.axiosInstance = globalAxios$1.create();
39232
+ this.setupInterceptors();
39233
+ }
39234
+ // eslint-disable-next-line class-methods-use-this
39235
+ shouldAddPublishableKey(url) {
39236
+ // Check if the request is going to a whitelisted domain
39237
+ return publishableKeyDomainAllowlist.some((domain) => url.startsWith(domain));
39238
+ }
39239
+ setupInterceptors() {
39240
+ this.axiosInstance.interceptors.request.use((config) => {
39241
+ const publishableKey = this.config?.baseConfig?.publishableKey;
39242
+ if (publishableKey && this.shouldAddPublishableKey(config.url || '')) {
39243
+ if (!publishableKey.startsWith(PUBLISHABLE_KEY_PREFIX)) {
39244
+ throw new Error('Invalid Publishable key. Create your Publishable key in Immutable developer hub.'
39245
+ + ' https://hub.immutable.com');
39246
+ }
39247
+ // Add publishable key header for whitelisted domains
39248
+ // eslint-disable-next-line no-param-reassign
39249
+ config.headers['x-immutable-publishable-key'] = publishableKey;
39250
+ }
39251
+ return config;
39252
+ }, (error) => Promise.reject(error));
39253
+ }
39254
+ // eslint-disable-next-line class-methods-use-this
39255
+ processResponse(response) {
39256
+ if (response && response?.status !== 200) {
39257
+ throw new CheckoutError(`Error: ${response.status} ${response.statusText}`, CheckoutErrorType.API_ERROR);
39258
+ }
39259
+ }
39260
+ async request(config) {
39261
+ let response;
39262
+ try {
39263
+ response = await this.axiosInstance.request(config);
39264
+ }
39265
+ catch (error) {
39266
+ throw new CheckoutError(error.message, CheckoutErrorType.API_ERROR);
39267
+ }
39268
+ this.processResponse(response);
39269
+ return response;
39270
+ }
39271
+ async get(url, config) {
39272
+ const requestConfig = {
39273
+ ...config,
39274
+ url,
39275
+ };
39276
+ return await this.request(requestConfig);
39277
+ }
39278
+ async post(url, data, config) {
39279
+ const requestConfig = {
39280
+ ...config,
39281
+ data,
39282
+ url,
39283
+ };
39284
+ return await this.request(requestConfig);
39285
+ }
39286
+ async put(url, data, config) {
39287
+ const requestConfig = {
39288
+ ...config,
39289
+ data,
39290
+ url,
39291
+ };
39292
+ return await this.request(requestConfig);
39293
+ }
39294
+ async delete(url, data, config) {
39295
+ const requestConfig = {
39296
+ ...config,
39297
+ data,
39298
+ url,
39299
+ };
39300
+ return await this.request(requestConfig);
39301
+ }
39302
+ }
39303
+
39204
39304
  const SANDBOX_CONFIGURATION = {
39205
39305
  baseConfig: {
39206
39306
  environment: Environment$1.SANDBOX,
@@ -39211,6 +39311,7 @@ const WIDGETS_SCRIPT_TIMEOUT = 100;
39211
39311
  // Checkout SDK
39212
39312
  class Checkout {
39213
39313
  readOnlyProviders;
39314
+ httpClient;
39214
39315
  config;
39215
39316
  fiatRampService;
39216
39317
  availability;
@@ -39220,7 +39321,8 @@ class Checkout {
39220
39321
  * @param {CheckoutModuleConfiguration} [config=SANDBOX_CONFIGURATION] - The configuration object for the CheckoutModule.
39221
39322
  */
39222
39323
  constructor(config = SANDBOX_CONFIGURATION) {
39223
- this.config = new CheckoutConfiguration(config);
39324
+ this.httpClient = new HttpClient(config);
39325
+ this.config = new CheckoutConfiguration(config, this.httpClient);
39224
39326
  this.fiatRampService = new FiatRampService(this.config);
39225
39327
  this.readOnlyProviders = new Map();
39226
39328
  this.availability = availabilityService(this.config.isDevelopment, this.config.isProduction);