@imtbl/sdk 0.1.10-alpha.4 → 0.2.1-alpha

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.js CHANGED
@@ -2,6 +2,7 @@ import axios$2 from 'axios';
2
2
  import { ImmutableX, Config, generateLegacyStarkPrivateKey, createStarkSigner, TransfersApi, OrdersApi as OrdersApi$1, UsersApi, Contracts, TradesApi, ExchangesApi, WithdrawalsApi, MintsApi, DepositsApi, EncodingApi, TokensApi as TokensApi$1 } from '@imtbl/core-sdk';
3
3
  export { createStarkSigner as imxClientCreateStarkSigner, generateLegacyStarkPrivateKey as imxClientGenerateLegacyStarkPrivateKey } from '@imtbl/core-sdk';
4
4
  import { UserManager } from 'oidc-client-ts';
5
+ import jwt_decode from 'jwt-decode';
5
6
  import { Magic } from 'magic-sdk';
6
7
  import { OpenIdExtension } from '@magic-ext/oidc';
7
8
  import BN$2 from 'bn.js';
@@ -9,7 +10,6 @@ import * as encUtils from 'enc-utils';
9
10
  import { Web3Provider, JsonRpcProvider } from '@ethersproject/providers';
10
11
  import FormData$2 from 'form-data';
11
12
  import { providers, BigNumber as BigNumber$1, constants, utils as utils$2, Contract as Contract$1, ethers, ContractFactory } from 'ethers';
12
- import dotenv from 'dotenv';
13
13
  import { Seaport as Seaport$1 } from '@opensea/seaport-js';
14
14
  import { parseUnits } from '@ethersproject/units';
15
15
  import { BigNumber as BigNumber$2 } from '@ethersproject/bignumber';
@@ -5437,7 +5437,7 @@ class APIError extends Error {
5437
5437
 
5438
5438
  /* eslint-disable implicit-arrow-linebreak */
5439
5439
  const defaultHeaders = {
5440
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.1.10-alpha.4',
5440
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.2.1-alpha',
5441
5441
  };
5442
5442
  /**
5443
5443
  * createAPIConfiguration to create a custom Configuration
@@ -5703,7 +5703,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
5703
5703
  chainID,
5704
5704
  coreContractAddress,
5705
5705
  registrationContractAddress,
5706
- sdkVersion: 'ts-immutable-sdk-0.1.10-alpha.4',
5706
+ sdkVersion: 'ts-immutable-sdk-0.2.1-alpha',
5707
5707
  });
5708
5708
  /**
5709
5709
  * Sets `sdkVersion` at the time of build
@@ -9980,6 +9980,43 @@ const withPassportError = async (fn, customErrorType) => {
9980
9980
  }
9981
9981
  };
9982
9982
 
9983
+ const keyCrendentials = 'passport_credentials';
9984
+ const validCredentialsMinTtlSec = 3600; // 1 hour
9985
+ class DeviceCredentialsManager {
9986
+ saveCredentials(tokenResponse) {
9987
+ localStorage.setItem(keyCrendentials, JSON.stringify(tokenResponse));
9988
+ }
9989
+ getCredentials() {
9990
+ const credentialsJson = localStorage.getItem(keyCrendentials);
9991
+ if (credentialsJson) {
9992
+ return JSON.parse(credentialsJson);
9993
+ }
9994
+ return null;
9995
+ }
9996
+ areValid(tokenResponse) {
9997
+ if (tokenResponse) {
9998
+ const accessTokenValid = this.isTokenValid(tokenResponse.access_token);
9999
+ const idTokenValid = this.isTokenValid(tokenResponse.id_token);
10000
+ return accessTokenValid && idTokenValid;
10001
+ }
10002
+ return false;
10003
+ }
10004
+ isTokenValid(jwt) {
10005
+ const tokenPayload = jwt_decode(jwt);
10006
+ const expiresAt = tokenPayload.exp ?? 0;
10007
+ const now = (Date.now() / 1000) + validCredentialsMinTtlSec;
10008
+ return expiresAt > now;
10009
+ }
10010
+ clearCredentials() {
10011
+ localStorage.removeItem(keyCrendentials);
10012
+ }
10013
+ }
10014
+
10015
+ const formUrlEncodedHeader = {
10016
+ headers: {
10017
+ 'Content-Type': 'application/x-www-form-urlencoded',
10018
+ },
10019
+ };
9983
10020
  const getAuthConfiguration = ({ oidcConfiguration, authenticationDomain, }) => {
9984
10021
  const baseConfiguration = {
9985
10022
  authority: authenticationDomain,
@@ -10005,12 +10042,19 @@ const getAuthConfiguration = ({ oidcConfiguration, authenticationDomain, }) => {
10005
10042
  }
10006
10043
  return baseConfiguration;
10007
10044
  };
10045
+ function wait$1(ms) {
10046
+ return new Promise((resolve) => {
10047
+ setTimeout(resolve, ms);
10048
+ });
10049
+ }
10008
10050
  class AuthManager {
10009
10051
  userManager;
10010
10052
  config;
10053
+ deviceCredentialsManager;
10011
10054
  constructor(config) {
10012
10055
  this.config = config;
10013
10056
  this.userManager = new UserManager(getAuthConfiguration(config));
10057
+ this.deviceCredentialsManager = new DeviceCredentialsManager();
10014
10058
  }
10015
10059
  static mapOidcUserToDomainModel = (oidcUser) => {
10016
10060
  const passport = oidcUser.profile?.passport;
@@ -10040,6 +10084,27 @@ class AuthManager {
10040
10084
  }
10041
10085
  return user;
10042
10086
  };
10087
+ static mapDeviceTokenResponseToDomainUserModel = (tokenResponse) => {
10088
+ const idTokenPayload = jwt_decode(tokenResponse.id_token);
10089
+ const user = {
10090
+ idToken: tokenResponse.id_token,
10091
+ accessToken: tokenResponse.access_token,
10092
+ refreshToken: tokenResponse.refresh_token,
10093
+ profile: {
10094
+ sub: idTokenPayload.sub,
10095
+ email: idTokenPayload.email,
10096
+ nickname: idTokenPayload.nickname,
10097
+ },
10098
+ };
10099
+ if (idTokenPayload?.passport?.imx_eth_address) {
10100
+ user.imx = {
10101
+ ethAddress: idTokenPayload?.passport?.imx_eth_address,
10102
+ starkAddress: idTokenPayload?.passport?.imx_stark_address,
10103
+ userAdminAddress: idTokenPayload?.passport?.imx_user_admin_address,
10104
+ };
10105
+ }
10106
+ return user;
10107
+ };
10043
10108
  async login() {
10044
10109
  return withPassportError(async () => {
10045
10110
  const popupWindowFeatures = { width: 410, height: 450 };
@@ -10052,9 +10117,104 @@ class AuthManager {
10052
10117
  async loginCallback() {
10053
10118
  return withPassportError(async () => this.userManager.signinPopupCallback(), PassportErrorType.AUTHENTICATION_ERROR);
10054
10119
  }
10120
+ async loginWithDeviceFlow() {
10121
+ return withPassportError(async () => {
10122
+ const response = await axios$2.post(`${this.config.authenticationDomain}/oauth/device/code`, {
10123
+ client_id: this.config.oidcConfiguration.clientId,
10124
+ scope: this.config.oidcConfiguration.scope,
10125
+ audience: this.config.oidcConfiguration.audience,
10126
+ }, formUrlEncodedHeader);
10127
+ return {
10128
+ code: response.data.user_code,
10129
+ deviceCode: response.data.device_code,
10130
+ url: response.data.verification_uri_complete,
10131
+ interval: response.data.interval,
10132
+ };
10133
+ }, PassportErrorType.AUTHENTICATION_ERROR);
10134
+ }
10135
+ /* eslint-disable no-await-in-loop */
10136
+ async connectImxDeviceFlow(deviceCode, interval, timeoutMs) {
10137
+ return withPassportError(async () => {
10138
+ const startTime = Date.now();
10139
+ const loopCondition = true;
10140
+ while (loopCondition) {
10141
+ if (timeoutMs != null && Date.now() - startTime > timeoutMs) {
10142
+ throw new Error('Timed out');
10143
+ }
10144
+ await wait$1(interval * 1000);
10145
+ try {
10146
+ const tokenResponse = await this.getDeviceFlowToken(deviceCode);
10147
+ const user = AuthManager.mapDeviceTokenResponseToDomainUserModel(tokenResponse);
10148
+ // Only persist credentials that contain the necessary data
10149
+ if (user.imx?.ethAddress && user.imx?.starkAddress && user.imx?.userAdminAddress) {
10150
+ this.deviceCredentialsManager.saveCredentials(tokenResponse);
10151
+ }
10152
+ return user;
10153
+ }
10154
+ catch (error) {
10155
+ if (axios$2.isAxiosError(error)) {
10156
+ const responseError = error.response?.data;
10157
+ switch (responseError.error) {
10158
+ case 'authorization_pending':
10159
+ break;
10160
+ case 'slow_down':
10161
+ break;
10162
+ case 'expired_token':
10163
+ throw new Error('Token expired, please log in again');
10164
+ case 'access_denied':
10165
+ throw new Error('User denied access');
10166
+ default:
10167
+ throw new Error('Error getting token');
10168
+ }
10169
+ }
10170
+ else {
10171
+ throw error;
10172
+ }
10173
+ }
10174
+ }
10175
+ throw new Error('Failed to get credentials');
10176
+ }, PassportErrorType.AUTHENTICATION_ERROR);
10177
+ }
10178
+ /* eslint-enable no-await-in-loop */
10179
+ async getDeviceFlowToken(deviceCode) {
10180
+ const response = await axios$2.post(`${this.config.authenticationDomain}/oauth/token`, {
10181
+ client_id: this.config.oidcConfiguration.clientId,
10182
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
10183
+ device_code: deviceCode,
10184
+ }, formUrlEncodedHeader);
10185
+ return response.data;
10186
+ }
10187
+ async connectImxWithCredentials(tokenResponse) {
10188
+ return withPassportError(async () => {
10189
+ if (this.deviceCredentialsManager.areValid(tokenResponse)) {
10190
+ // Credentials exist and are still valid
10191
+ return AuthManager.mapDeviceTokenResponseToDomainUserModel(tokenResponse);
10192
+ }
10193
+ const refreshToken = tokenResponse?.refresh_token ?? null;
10194
+ if (refreshToken) {
10195
+ // Token is no longer valid, but refresh token can be used to a new one
10196
+ const newTokenResponse = await this.refreshToken(refreshToken);
10197
+ return AuthManager.mapDeviceTokenResponseToDomainUserModel(newTokenResponse);
10198
+ }
10199
+ return null;
10200
+ }, PassportErrorType.AUTHENTICATION_ERROR);
10201
+ }
10202
+ async refreshToken(refreshToken) {
10203
+ const response = await axios$2.post(`${this.config.authenticationDomain}/oauth/token`, {
10204
+ client_id: this.config.oidcConfiguration.clientId,
10205
+ grant_type: 'refresh_token',
10206
+ refresh_token: refreshToken,
10207
+ }, formUrlEncodedHeader);
10208
+ return response.data;
10209
+ }
10055
10210
  async logout() {
10056
10211
  return withPassportError(async () => this.userManager.signoutRedirect(), PassportErrorType.LOGOUT_ERROR);
10057
10212
  }
10213
+ async logoutDeviceFlow() {
10214
+ return withPassportError(async () => {
10215
+ this.deviceCredentialsManager.clearCredentials();
10216
+ }, PassportErrorType.LOGOUT_ERROR);
10217
+ }
10058
10218
  async loginSilent() {
10059
10219
  return withPassportError(async () => {
10060
10220
  const existedUser = await this.getUser();
@@ -10071,12 +10231,28 @@ class AuthManager {
10071
10231
  async getUser() {
10072
10232
  return withPassportError(async () => {
10073
10233
  const oidcUser = await this.userManager.getUser();
10074
- if (!oidcUser) {
10075
- return null;
10234
+ if (oidcUser) {
10235
+ return AuthManager.mapOidcUserToDomainModel(oidcUser);
10076
10236
  }
10077
- return AuthManager.mapOidcUserToDomainModel(oidcUser);
10237
+ const deviceToken = this.deviceCredentialsManager.getCredentials();
10238
+ if (deviceToken) {
10239
+ return AuthManager.mapDeviceTokenResponseToDomainUserModel(deviceToken);
10240
+ }
10241
+ return null;
10078
10242
  }, PassportErrorType.NOT_LOGGED_IN_ERROR);
10079
10243
  }
10244
+ async getUserDeviceFlow() {
10245
+ return withPassportError(async () => {
10246
+ const deviceToken = this.deviceCredentialsManager.getCredentials();
10247
+ if (deviceToken) {
10248
+ return AuthManager.mapDeviceTokenResponseToDomainUserModel(deviceToken);
10249
+ }
10250
+ return null;
10251
+ }, PassportErrorType.NOT_LOGGED_IN_ERROR);
10252
+ }
10253
+ checkStoredDeviceFlowCredentials() {
10254
+ return this.deviceCredentialsManager.getCredentials();
10255
+ }
10080
10256
  }
10081
10257
 
10082
10258
  class MagicAdapter {
@@ -10604,6 +10780,17 @@ class PassportImxProviderFactory {
10604
10780
  }
10605
10781
  return this.createProviderInstance(user);
10606
10782
  }
10783
+ async getProviderWithDeviceFlow(deviceCode, interval, timeoutMs) {
10784
+ const user = await this.authManager.connectImxDeviceFlow(deviceCode, interval, timeoutMs);
10785
+ return this.createProviderInstance(user);
10786
+ }
10787
+ async getProviderWithCredentials(tokenResponse) {
10788
+ const user = await this.authManager.connectImxWithCredentials(tokenResponse);
10789
+ if (!user) {
10790
+ return null;
10791
+ }
10792
+ return this.createProviderInstance(user);
10793
+ }
10607
10794
  async createProviderInstance(user) {
10608
10795
  if (!user.idToken) {
10609
10796
  throw new PassportError('Failed to initialise', PassportErrorType.WALLET_CONNECTION_ERROR);
@@ -10911,16 +11098,38 @@ class Passport {
10911
11098
  async connectImx() {
10912
11099
  return this.passportImxProviderFactory.getProvider();
10913
11100
  }
11101
+ async loginWithDeviceFlow() {
11102
+ return this.authManager.loginWithDeviceFlow();
11103
+ }
11104
+ async connectImxDeviceFlow(deviceCode, interval, timeoutMs) {
11105
+ return this.passportImxProviderFactory.getProviderWithDeviceFlow(deviceCode, interval, timeoutMs);
11106
+ }
11107
+ /**
11108
+ * @returns {boolean} the stored device flow credentials if they exist
11109
+ */
11110
+ checkStoredDeviceFlowCredentials() {
11111
+ return this.authManager.checkStoredDeviceFlowCredentials();
11112
+ }
11113
+ async connectImxWithCredentials(tokenResponse) {
11114
+ return this.passportImxProviderFactory.getProviderWithCredentials(tokenResponse);
11115
+ }
10914
11116
  async loginCallback() {
10915
11117
  return this.authManager.loginCallback();
10916
11118
  }
10917
11119
  async logout() {
10918
11120
  return this.authManager.logout();
10919
11121
  }
11122
+ async logoutDeviceFlow() {
11123
+ return this.authManager.logoutDeviceFlow();
11124
+ }
10920
11125
  async getUserInfo() {
10921
11126
  const user = await this.authManager.getUser();
10922
11127
  return user?.profile;
10923
11128
  }
11129
+ async getUserInfoDeviceFlow() {
11130
+ const user = await this.authManager.getUserDeviceFlow();
11131
+ return user?.profile;
11132
+ }
10924
11133
  async getIdToken() {
10925
11134
  const user = await this.authManager.getUser();
10926
11135
  return user?.idToken;
@@ -11826,49 +12035,11 @@ class ImmutableApiClientFactory {
11826
12035
  }
11827
12036
  }
11828
12037
 
11829
- // eslint-disable-next-line
11830
- dotenv.config();
11831
- function getConfigFromEnv() {
11832
- if (!process.env.ORDERBOOK_MR_API_URL
11833
- || !process.env.SEAPORT_CONTRACT_ADDRESS
11834
- || !process.env.ZONE_CONTRACT_ADDRESS) {
11835
- throw new Error('missing config');
11836
- }
11837
- return {
11838
- apiUrl: process.env.ORDERBOOK_MR_API_URL,
11839
- seaportContractAddress: process.env.SEAPORT_CONTRACT_ADDRESS,
11840
- zoneContractAddress: process.env.ZONE_CONTRACT_ADDRESS,
11841
- };
11842
- }
11843
-
11844
- dotenv.config();
11845
- function getLocalhostProvider() {
11846
- const endpoint = process.env.LOCAL_RPC_ENDPOINT;
11847
- if (!endpoint) {
11848
- throw new Error('LOCAL_RPC_ENDPOINT not set');
11849
- }
11850
- return new providers.JsonRpcProvider(endpoint);
11851
- }
11852
-
11853
- dotenv.config();
11854
-
11855
- const LOCAL_CHAIN_NAME = 'imtbl-zkevm-local';
11856
12038
  const DEVNET_CHAIN_NAME = 'imtbl-zkevm-devnet';
11857
12039
  const TESTNET_CHAIN_NAME = 'imtbl-zkevm-testnet';
11858
12040
  const MAINNET_CHAIN_NAME = 'imtbl-zkevm-mainnet';
11859
- function localChainConfig() {
11860
- const localConfig = getConfigFromEnv();
11861
- return {
11862
- seaportContractAddress: localConfig.seaportContractAddress,
11863
- zoneContractAddress: localConfig.zoneContractAddress,
11864
- apiEndpoint: localConfig.apiUrl,
11865
- provider: getLocalhostProvider(),
11866
- };
11867
- }
11868
12041
  function getOrderbookConfig(chainName) {
11869
12042
  switch (chainName) {
11870
- case LOCAL_CHAIN_NAME:
11871
- return localChainConfig();
11872
12043
  case DEVNET_CHAIN_NAME:
11873
12044
  return {
11874
12045
  seaportContractAddress: '0x41388404Efb7a68Fd31d75CEf71dF91e2BDBa2fb',
@@ -12844,24 +13015,26 @@ class SeaportLibFactory {
12844
13015
  * @param {OrderbookModuleConfiguration} config - Configuration for Immutable services.
12845
13016
  */
12846
13017
  class Orderbook {
12847
- config;
12848
13018
  apiClient;
12849
13019
  seaport;
12850
- constructor(config) {
12851
- this.config = config;
12852
- const orderbookConfig = getOrderbookConfig(config.overrides?.chainName);
12853
- const apiEndpoint = orderbookConfig?.apiEndpoint;
13020
+ orderbookConfig;
13021
+ constructor(config, localConfig) {
13022
+ // either use preconfigured config or local config passed in
13023
+ const maybeConfig = getOrderbookConfig(config.overrides?.chainName) || localConfig;
13024
+ if (!maybeConfig) {
13025
+ throw new Error('Orderbook configuration not passed, either select one of the preseet chainNames or pass in localConfig');
13026
+ }
13027
+ const { chainName, provider } = config.overrides;
13028
+ maybeConfig.provider = provider
13029
+ || maybeConfig.provider;
13030
+ this.orderbookConfig = maybeConfig;
13031
+ const { apiEndpoint } = this.orderbookConfig;
12854
13032
  if (!apiEndpoint) {
12855
13033
  throw new Error('API endpoint must be provided as an override');
12856
13034
  }
12857
- // TODO: Move chainId lookup to a map based on env. Just using override to get dev started
12858
- const chainName = config.overrides?.chainName;
12859
- if (!chainName) {
12860
- throw new Error('chainName must be provided as an override');
12861
- }
12862
- this.apiClient = new ImmutableApiClientFactory(apiEndpoint, chainName, orderbookConfig.seaportContractAddress).create();
12863
- const seaportLibFactory = new SeaportLibFactory(orderbookConfig.seaportContractAddress, orderbookConfig.provider);
12864
- this.seaport = new Seaport(seaportLibFactory, orderbookConfig.provider, orderbookConfig.seaportContractAddress, orderbookConfig.zoneContractAddress);
13035
+ this.apiClient = new ImmutableApiClientFactory(apiEndpoint, chainName, this.orderbookConfig.seaportContractAddress).create();
13036
+ const seaportLibFactory = new SeaportLibFactory(this.orderbookConfig.seaportContractAddress, this.orderbookConfig.provider);
13037
+ this.seaport = new Seaport(seaportLibFactory, this.orderbookConfig.provider, this.orderbookConfig.seaportContractAddress, this.orderbookConfig.zoneContractAddress);
12865
13038
  }
12866
13039
  /**
12867
13040
  * Get an order by ID
@@ -12889,8 +13062,7 @@ class Orderbook {
12889
13062
  * the order components that can be submitted to `createListing` with a signature.
12890
13063
  */
12891
13064
  async prepareListing({ makerAddress, sell, buy, orderExpiry, }) {
12892
- const orderbookConfig = getOrderbookConfig(this.config.overrides?.chainName);
12893
- const erc721 = new ERC721Factory(sell.contractAddress, orderbookConfig.provider).create();
13065
+ const erc721 = new ERC721Factory(sell.contractAddress, this.orderbookConfig.provider).create();
12894
13066
  const royaltyInfo = await erc721.royaltyInfo(sell.tokenId, buy.amount);
12895
13067
  return this.seaport.prepareSeaportOrder(makerAddress, sell, buy, royaltyInfo,
12896
13068
  // Default order start to now
@@ -24364,9 +24536,8 @@ class ExchangeError extends Error {
24364
24536
  }
24365
24537
  }
24366
24538
  class InvalidConfigurationError extends ExchangeError {
24367
- constructor() {
24368
- const message = 'Invalid configuration';
24369
- super(message, ExchangeErrorCode.INVALID_CONFIGURATION);
24539
+ constructor(message) {
24540
+ super(message || 'Invalid configuration', ExchangeErrorCode.INVALID_CONFIGURATION);
24370
24541
  }
24371
24542
  }
24372
24543
  class ChainNotSupportedError extends ExchangeError {
@@ -26467,20 +26638,84 @@ function getSwap(nativeToken, routeAndQuote, fromAddress, slippage, deadline, pe
26467
26638
  };
26468
26639
  }
26469
26640
 
26641
+ const CONTRACTS_FOR_CHAIN_ID = {
26642
+ [IMMUTABLE_TESTNET_CHAIN_ID]: {
26643
+ multicall: '0xb18c44b211065E69844FbA9AE146DA362104AfBf',
26644
+ coreFactory: '0x12739A8f1A8035F439092D016DAE19A2874F30d2',
26645
+ quoterV2: '0xF674847fBcca5C80315e3AE37043Dce99F6CC529',
26646
+ peripheryRouter: '0x0Afe6F5f4DC34461A801420634239FFaD50A2e44',
26647
+ },
26648
+ };
26649
+ const SUPPORTED_SANDBOX_CHAINS = {
26650
+ [IMMUTABLE_TESTNET_CHAIN_ID]: {
26651
+ chainId: IMMUTABLE_TESTNET_CHAIN_ID,
26652
+ rpcUrl: IMMUTABLE_TESTNET_RPC_URL,
26653
+ contracts: CONTRACTS_FOR_CHAIN_ID[IMMUTABLE_TESTNET_CHAIN_ID],
26654
+ commonRoutingTokens: IMMUTABLE_TESTNET_COMMON_ROUTING_TOKENS,
26655
+ nativeToken: TIMX_IMMUTABLE_TESTNET,
26656
+ },
26657
+ };
26658
+ const SUPPORTED_PRODUCTION_CHAINS = {};
26659
+ const SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT = {
26660
+ [Environment$1.SANDBOX]: SUPPORTED_SANDBOX_CHAINS,
26661
+ [Environment$1.PRODUCTION]: SUPPORTED_PRODUCTION_CHAINS,
26662
+ };
26663
+ function validateOverrides(overrides) {
26664
+ Object.entries(overrides).forEach(([key, value]) => {
26665
+ if (!value) {
26666
+ throw new InvalidConfigurationError(`Missing override: ${key}`);
26667
+ }
26668
+ });
26669
+ Object.entries(overrides.exchangeContracts).forEach(([key, contract]) => {
26670
+ if (!isValidNonZeroAddress(contract)) {
26671
+ throw new InvalidConfigurationError(`Invalid exchange contract address for ${key}`);
26672
+ }
26673
+ });
26674
+ }
26675
+ /**
26676
+ * {@link ExchangeConfiguration} is used to configure the {@link Exchange} class.
26677
+ * @param chainId the ID of the chain to configure. {@link SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT} contains the supported chains for each environment.
26678
+ * @param baseConfig the base {@link ImmutableConfiguration} for the {@link Exchange} class
26679
+ */
26680
+ class ExchangeConfiguration {
26681
+ baseConfig;
26682
+ chain;
26683
+ constructor({ chainId, baseConfig, overrides }) {
26684
+ this.baseConfig = baseConfig;
26685
+ if (overrides) {
26686
+ validateOverrides(overrides);
26687
+ this.chain = {
26688
+ chainId,
26689
+ rpcUrl: overrides.rpcURL,
26690
+ contracts: overrides.exchangeContracts,
26691
+ commonRoutingTokens: overrides.commonRoutingTokens,
26692
+ nativeToken: overrides.nativeToken,
26693
+ };
26694
+ return;
26695
+ }
26696
+ const chain = SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT[baseConfig.environment][chainId];
26697
+ if (!chain) {
26698
+ throw new ChainNotSupportedError(chainId, baseConfig.environment);
26699
+ }
26700
+ this.chain = chain;
26701
+ }
26702
+ }
26703
+
26470
26704
  class Exchange {
26471
26705
  provider;
26472
26706
  router;
26473
26707
  chainId;
26474
26708
  nativeToken;
26475
26709
  constructor(configuration) {
26476
- this.chainId = configuration.chain.chainId;
26477
- this.nativeToken = configuration.chain.nativeToken;
26478
- this.provider = new ethers.providers.JsonRpcProvider(configuration.chain.rpcUrl);
26479
- this.router = new Router(this.provider, configuration.chain.commonRoutingTokens, {
26480
- multicallAddress: configuration.chain.contracts.multicall,
26481
- factoryAddress: configuration.chain.contracts.coreFactory,
26482
- quoterAddress: configuration.chain.contracts.quoterV2,
26483
- peripheryRouterAddress: configuration.chain.contracts.peripheryRouter,
26710
+ const config = new ExchangeConfiguration(configuration);
26711
+ this.chainId = config.chain.chainId;
26712
+ this.nativeToken = config.chain.nativeToken;
26713
+ this.provider = new ethers.providers.JsonRpcProvider(config.chain.rpcUrl);
26714
+ this.router = new Router(this.provider, config.chain.commonRoutingTokens, {
26715
+ multicallAddress: config.chain.contracts.multicall,
26716
+ factoryAddress: config.chain.contracts.coreFactory,
26717
+ quoterAddress: config.chain.contracts.quoterV2,
26718
+ peripheryRouterAddress: config.chain.contracts.peripheryRouter,
26484
26719
  });
26485
26720
  }
26486
26721
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
@@ -26560,67 +26795,6 @@ class Exchange {
26560
26795
  }
26561
26796
  }
26562
26797
 
26563
- const CONTRACTS_FOR_CHAIN_ID = {
26564
- [IMMUTABLE_TESTNET_CHAIN_ID]: {
26565
- multicall: '0xb18c44b211065E69844FbA9AE146DA362104AfBf',
26566
- coreFactory: '0x12739A8f1A8035F439092D016DAE19A2874F30d2',
26567
- quoterV2: '0xF674847fBcca5C80315e3AE37043Dce99F6CC529',
26568
- peripheryRouter: '0x0Afe6F5f4DC34461A801420634239FFaD50A2e44',
26569
- },
26570
- };
26571
- const SUPPORTED_SANDBOX_CHAINS = {
26572
- [IMMUTABLE_TESTNET_CHAIN_ID]: {
26573
- chainId: IMMUTABLE_TESTNET_CHAIN_ID,
26574
- rpcUrl: IMMUTABLE_TESTNET_RPC_URL,
26575
- contracts: CONTRACTS_FOR_CHAIN_ID[IMMUTABLE_TESTNET_CHAIN_ID],
26576
- commonRoutingTokens: IMMUTABLE_TESTNET_COMMON_ROUTING_TOKENS,
26577
- nativeToken: TIMX_IMMUTABLE_TESTNET,
26578
- },
26579
- };
26580
- const SUPPORTED_PRODUCTION_CHAINS = {};
26581
- const SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT = {
26582
- [Environment$1.SANDBOX]: SUPPORTED_SANDBOX_CHAINS,
26583
- [Environment$1.PRODUCTION]: SUPPORTED_PRODUCTION_CHAINS,
26584
- };
26585
- function validateOverrides(overrides) {
26586
- if (!overrides.rpcURL || !overrides.exchangeContracts || !overrides.commonRoutingTokens || !overrides.nativeToken) {
26587
- throw new InvalidConfigurationError();
26588
- }
26589
- Object.values(overrides.exchangeContracts).forEach((contract) => {
26590
- if (!isValidNonZeroAddress(contract)) {
26591
- throw new InvalidConfigurationError();
26592
- }
26593
- });
26594
- }
26595
- /**
26596
- * {@link ExchangeConfiguration} is used to configure the {@link Exchange} class.
26597
- * @param chainId the ID of the chain to configure. {@link SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT} contains the supported chains for each environment.
26598
- * @param baseConfig the base {@link ImmutableConfiguration} for the {@link Exchange} class
26599
- */
26600
- class ExchangeConfiguration {
26601
- baseConfig;
26602
- chain;
26603
- constructor({ chainId, baseConfig, overrides }) {
26604
- this.baseConfig = baseConfig;
26605
- if (overrides) {
26606
- validateOverrides(overrides);
26607
- this.chain = {
26608
- chainId,
26609
- rpcUrl: overrides.rpcURL,
26610
- contracts: overrides.exchangeContracts,
26611
- commonRoutingTokens: overrides.commonRoutingTokens,
26612
- nativeToken: overrides.nativeToken,
26613
- };
26614
- return;
26615
- }
26616
- const chain = SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT[baseConfig.environment][chainId];
26617
- if (!chain) {
26618
- throw new ChainNotSupportedError(chainId, baseConfig.environment);
26619
- }
26620
- this.chain = chain;
26621
- }
26622
- }
26623
-
26624
26798
  /* eslint-disable class-methods-use-this */
26625
26799
 
26626
26800
  const $762782b6c862d954$export$db5daa1b5156ccfe = [
@@ -27373,13 +27547,13 @@ async function $67fc622a2b913d5f$export$989eefe1274a439c(fromChainId, toChainId,
27373
27547
  }
27374
27548
  async function $67fc622a2b913d5f$export$7cf6178417769841(chainId, config) {
27375
27549
  const dexConfig = await config.remote.getConfig("dex");
27376
- return new (Exchange)(new (ExchangeConfiguration)({
27550
+ return new (Exchange)({
27377
27551
  chainId: chainId,
27378
27552
  baseConfig: new (ImmutableConfiguration)({
27379
27553
  environment: config.environment
27380
27554
  }),
27381
27555
  overrides: dexConfig?.overrides
27382
- }));
27556
+ });
27383
27557
  }
27384
27558
 
27385
27559
 
@@ -27743,7 +27917,7 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
27743
27917
  function $parcel$export(e, n, v, s) {
27744
27918
  Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
27745
27919
  }
27746
- const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.1.10-alpha.4";
27920
+ const $d663162fd5a0853f$export$38a083d9fb5551ca = "0.2.1-alpha";
27747
27921
  const $d663162fd5a0853f$export$83bf90b30cdfd29f = ()=>false;
27748
27922
  const $d663162fd5a0853f$export$1169f5475725171b = ()=>$d663162fd5a0853f$export$38a083d9fb5551ca;
27749
27923
 
@@ -1,4 +1,4 @@
1
- import { OrderbookOverrides } from 'config/config';
1
+ import { OrderbookOverrides, OrderbookModuleConfiguration } from 'config/config';
2
2
  import { ListingResult, ListListingsResult } from 'openapi/sdk';
3
3
  import { ListListingsParams, PrepareListingParams, PrepareListingResponse, CreateListingParams, FulfillOrderResponse, CancelOrderResponse } from 'types';
4
4
 
@@ -25,10 +25,10 @@ interface ModuleConfiguration<T> {
25
25
  * @param {OrderbookModuleConfiguration} config - Configuration for Immutable services.
26
26
  */
27
27
  declare class Orderbook {
28
- private config;
29
28
  private apiClient;
30
29
  private seaport;
31
- constructor(config: ModuleConfiguration<OrderbookOverrides>);
30
+ private orderbookConfig;
31
+ constructor(config: ModuleConfiguration<OrderbookOverrides>, localConfig?: OrderbookModuleConfiguration);
32
32
  /**
33
33
  * Get an order by ID
34
34
  * @param {string} listingId - The listingId to find.