diff --git a/packages/checkout/sdk/src/availability/availability.test.ts b/packages/checkout/sdk/src/availability/availability.test.ts index 9f73cf7bc0..5f14f7cf0a 100644 --- a/packages/checkout/sdk/src/availability/availability.test.ts +++ b/packages/checkout/sdk/src/availability/availability.test.ts @@ -14,7 +14,7 @@ describe('availabilityService', () => { it('should return true when status is 2xx', async () => { const mockResponse = {}; mockedAxios.post.mockResolvedValueOnce(mockResponse); - const response = await availabilityService(true, false).checkDexAvailability(); + const response = await availabilityService('testEndpoint').checkDexAvailability(); expect(mockedAxios.post).toHaveBeenCalledTimes(1); expect(response).toEqual(true); @@ -25,7 +25,7 @@ describe('availabilityService', () => { status: 403, }; mockedAxios.post.mockRejectedValueOnce({ response: mockResponse }); - const response = await availabilityService(true, false).checkDexAvailability(); + const response = await availabilityService('testEndpoint').checkDexAvailability(); expect(mockedAxios.post).toHaveBeenCalledTimes(1); expect(response).toEqual(false); @@ -38,7 +38,7 @@ describe('availabilityService', () => { }; mockedAxios.post.mockRejectedValueOnce({ response: mockResponse }); - await expect(availabilityService(true, false).checkDexAvailability()) + await expect(availabilityService('testEndpoint').checkDexAvailability()) .rejects .toThrow( new CheckoutError( diff --git a/packages/checkout/sdk/src/availability/availability.ts b/packages/checkout/sdk/src/availability/availability.ts index 12fcb4098f..449bfd22b0 100644 --- a/packages/checkout/sdk/src/availability/availability.ts +++ b/packages/checkout/sdk/src/availability/availability.ts @@ -1,28 +1,18 @@ -import { Environment } from '@imtbl/config'; import axios from 'axios'; import { CheckoutError, CheckoutErrorType } from '../errors'; -import { ENV_DEVELOPMENT, IMMUTABLE_API_BASE_URL } from '../env'; export type AvailabilityService = { checkDexAvailability: () => Promise }; export const availabilityService = ( - isDevelopment: boolean, - isProduction: boolean, + postEndpoint: string, ) => { - const postEndpoint = () => { - if (isDevelopment) return IMMUTABLE_API_BASE_URL[ENV_DEVELOPMENT]; - if (isProduction) return IMMUTABLE_API_BASE_URL[Environment.PRODUCTION]; - - return IMMUTABLE_API_BASE_URL[Environment.SANDBOX]; - }; - const checkDexAvailability = async (): Promise => { let response; try { - response = await axios.post(`${postEndpoint()}/v1/availability/checkout/swap`); + response = await axios.post(`${postEndpoint}/v1/availability/checkout/swap`); } catch (err: any) { // The request was made and the server responded with a status code // that falls out of the range of 2xx diff --git a/packages/checkout/sdk/src/config/config.test.ts b/packages/checkout/sdk/src/config/config.test.ts index 808d1647fd..f3bbcf6d95 100644 --- a/packages/checkout/sdk/src/config/config.test.ts +++ b/packages/checkout/sdk/src/config/config.test.ts @@ -1,5 +1,5 @@ import { Environment } from '@imtbl/config'; -import { CheckoutConfigurationError, getL1ChainId, getL2ChainId } from './config'; +import { CheckoutConfigurationError } from './config'; import { Checkout } from '../sdk'; import { ChainId, @@ -9,10 +9,6 @@ import { PRODUCTION_CHAIN_ID_NETWORK_MAP, SANDBOX_CHAIN_ID_NETWORK_MAP } from '. describe('config', () => { describe('CheckoutConfiguration class', () => { - beforeEach(() => { - // eslint-disable-next-line @typescript-eslint/naming-convention - process.env = { CHECKOUT_DEV_MODE: undefined }; - }); it('should set the environment in the constructor to SANDBOX or PRODUCTION', () => { const envs = [Environment.SANDBOX, Environment.PRODUCTION]; envs.forEach((env) => { @@ -26,17 +22,6 @@ describe('config', () => { }); }); - it('should set is development', () => { - // eslint-disable-next-line @typescript-eslint/naming-convention - process.env = { CHECKOUT_DEV_MODE: 'true' }; - const testCheckoutConfig = { - baseConfig: { environment: Environment.SANDBOX }, - } as CheckoutModuleConfiguration; - - const checkout = new Checkout(testCheckoutConfig); - expect(checkout.config.isDevelopment).toBeTruthy(); - }); - it('should correctly set the networkMap for sandbox', () => { const sandboxConfig = { baseConfig: { environment: Environment.SANDBOX }, @@ -76,10 +61,6 @@ describe('config', () => { }); describe('get layer chain id', () => { - beforeEach(() => { - // eslint-disable-next-line @typescript-eslint/naming-convention - process.env = { CHECKOUT_DEV_MODE: undefined }; - }); it('should get the L1 chain id for environment', () => { const envs = [ { @@ -97,7 +78,7 @@ describe('config', () => { } as CheckoutModuleConfiguration; const checkout = new Checkout(testCheckoutConfig); - expect(getL1ChainId(checkout.config)).toEqual(chainId); + expect(checkout.config.l1ChainId).toEqual(chainId); }); }); @@ -114,19 +95,18 @@ describe('config', () => { { env: Environment.SANDBOX, chainId: ChainId.IMTBL_ZKEVM_DEVNET, - overrideDev: true, }, ]; - envs.forEach(({ env, chainId, overrideDev }) => { + envs.forEach(({ env, chainId }) => { const testCheckoutConfig = { baseConfig: { environment: env }, + overrides: { + l2ChainId: chainId, + }, } as CheckoutModuleConfiguration; - // eslint-disable-next-line @typescript-eslint/naming-convention - if (overrideDev) process.env = { CHECKOUT_DEV_MODE: 'true' }; - const checkout = new Checkout(testCheckoutConfig); - expect(getL2ChainId(checkout.config)).toEqual(chainId); + expect(checkout.config.l2ChainId).toEqual(chainId); }); }); }); diff --git a/packages/checkout/sdk/src/config/config.ts b/packages/checkout/sdk/src/config/config.ts index 333aa5303c..e563f3bd4c 100644 --- a/packages/checkout/sdk/src/config/config.ts +++ b/packages/checkout/sdk/src/config/config.ts @@ -1,12 +1,16 @@ import { Environment } from '@imtbl/config'; -import { CheckoutModuleConfiguration, ChainId, NetworkMap } from '../types'; +import { BridgeInstance, ETH_MAINNET_TO_ZKEVM_MAINNET, ETH_SEPOLIA_TO_ZKEVM_TESTNET } from '@imtbl/bridge-sdk'; +import { + CheckoutModuleConfiguration, ChainId, NetworkMap, ChainSlug, +} from '../types'; import { RemoteConfigFetcher } from './remoteConfigFetcher'; import { + CHECKOUT_CDN_BASE_URL, DEFAULT_BRIDGE_ENABLED, DEFAULT_ON_RAMP_ENABLED, DEFAULT_SWAP_ENABLED, - DEV_CHAIN_ID_NETWORK_MAP, globalPackageVersion, + IMMUTABLE_API_BASE_URL, PRODUCTION_CHAIN_ID_NETWORK_MAP, SANDBOX_CHAIN_ID_NETWORK_MAP, } from '../env'; @@ -22,41 +26,7 @@ export class CheckoutConfigurationError extends Error { } } -const networkMap = (prod: boolean, dev: boolean) => { - if (dev) return DEV_CHAIN_ID_NETWORK_MAP; - if (prod) return PRODUCTION_CHAIN_ID_NETWORK_MAP; - return SANDBOX_CHAIN_ID_NETWORK_MAP; -}; - -// **************************************************** // -// This is duplicated in the widget-lib project. // -// We are not exposing these functions given that this // -// to keep the Checkout SDK interface as minimal as // -// possible. // -// **************************************************** // -export const getL1ChainId = (config: CheckoutConfiguration): ChainId => { - // DevMode and Sandbox will both use Sepolia. - if (!config.isProduction) return ChainId.SEPOLIA; - return ChainId.ETHEREUM; -}; - -export const getL2ChainId = (config: CheckoutConfiguration): ChainId => { - if (config.isDevelopment) return ChainId.IMTBL_ZKEVM_DEVNET; - if (config.isProduction) return ChainId.IMTBL_ZKEVM_MAINNET; - return ChainId.IMTBL_ZKEVM_TESTNET; -}; -// **************************************************** // -// **************************************************** // - export class CheckoutConfiguration { - // This is a hidden feature that is only available - // when building the project from source code. - // This will be used to get around the lack of - // Environment.DEVELOPMENT - readonly isDevelopment: boolean = process.env.CHECKOUT_DEV_MODE === 'true'; - - readonly isProduction: boolean; - readonly isOnRampEnabled: boolean; readonly isSwapEnabled: boolean; @@ -69,8 +39,6 @@ export class CheckoutConfiguration { readonly environment: Environment; - readonly networkMap: NetworkMap; - readonly publishableKey: string; readonly overrides: CheckoutModuleConfiguration['overrides']; @@ -83,25 +51,14 @@ export class CheckoutConfiguration { } this.environment = config.baseConfig.environment; - - // Developer mode will super set any environment configuration - this.isProduction = !this.isDevelopment && this.environment === Environment.PRODUCTION; this.isOnRampEnabled = config.onRamp?.enable ?? DEFAULT_ON_RAMP_ENABLED; this.isSwapEnabled = config.swap?.enable ?? DEFAULT_SWAP_ENABLED; this.isBridgeEnabled = config.bridge?.enable ?? DEFAULT_BRIDGE_ENABLED; this.publishableKey = config.publishableKey ?? ''; - this.networkMap = networkMap(this.isProduction, this.isDevelopment); + this.remote = new RemoteConfigFetcher(httpClient, this.remoteEndpoint); - this.remote = new RemoteConfigFetcher(httpClient, { - isDevelopment: this.isDevelopment, - isProduction: this.isProduction, - }); - - this.tokens = new TokensFetcher(httpClient, this.remote, { - isDevelopment: this.isDevelopment, - isProduction: this.isProduction, - }); + this.tokens = new TokensFetcher(httpClient, this.remote, this.baseUrl, this.chainSlug); this.overrides = config.overrides ?? {}; } @@ -110,4 +67,42 @@ export class CheckoutConfiguration { get sdkVersion(): string { return globalPackageVersion(); } + + get remoteEndpoint(): string { + return this.overrides?.remoteEndpoint ?? CHECKOUT_CDN_BASE_URL[this.environment]; + } + + get baseUrl(): string { + return this.overrides?.baseUrl ?? IMMUTABLE_API_BASE_URL[this.environment]; + } + + get chainSlug(): ChainSlug { + if (this.overrides?.chainSlug) return this.overrides.chainSlug; + if (this.environment === Environment.PRODUCTION) return ChainSlug.IMTBL_ZKEVM_MAINNET; + return ChainSlug.IMTBL_ZKEVM_TESTNET; + } + + get bridgeInstance(): BridgeInstance { + if (this.overrides?.bridgeInstance) return this.overrides.bridgeInstance; + if (this.environment === Environment.PRODUCTION) return ETH_MAINNET_TO_ZKEVM_MAINNET; + return ETH_SEPOLIA_TO_ZKEVM_TESTNET; + } + + get l1ChainId(): ChainId { + if (this.overrides?.l1ChainId) return this.overrides.l1ChainId; + if (this.environment === Environment.PRODUCTION) return ChainId.ETHEREUM; + return ChainId.SEPOLIA; + } + + get l2ChainId(): ChainId { + if (this.overrides?.l2ChainId) return this.overrides.l2ChainId; + if (this.environment === Environment.PRODUCTION) return ChainId.IMTBL_ZKEVM_MAINNET; + return ChainId.IMTBL_ZKEVM_TESTNET; + } + + get networkMap(): NetworkMap { + if (this.overrides?.networkMap) return this.overrides.networkMap; + if (this.environment === Environment.PRODUCTION) return PRODUCTION_CHAIN_ID_NETWORK_MAP; + return SANDBOX_CHAIN_ID_NETWORK_MAP; + } } diff --git a/packages/checkout/sdk/src/config/remoteConfigFetcher.test.ts b/packages/checkout/sdk/src/config/remoteConfigFetcher.test.ts index 53b5be9f69..64e3866455 100644 --- a/packages/checkout/sdk/src/config/remoteConfigFetcher.test.ts +++ b/packages/checkout/sdk/src/config/remoteConfigFetcher.test.ts @@ -1,11 +1,6 @@ -import { Environment } from '@imtbl/config'; import { AxiosResponse } from 'axios'; import { ChainId } from '../types'; import { RemoteConfigFetcher } from './remoteConfigFetcher'; -import { - CHECKOUT_CDN_BASE_URL, - ENV_DEVELOPMENT, -} from '../env'; import { HttpClient } from '../api/http'; jest.mock('../api/http'); @@ -22,31 +17,49 @@ describe('RemoteConfig', () => { mockedHttpClient = new HttpClient() as jest.Mocked; }); - [Environment.PRODUCTION, Environment.SANDBOX, ENV_DEVELOPMENT].forEach((env) => { - describe('config', () => { - it(`should fetch configs and cache them [${env}]`, async () => { - const mockResponse = { - status: 200, - data: { - connect: { - walletConnect: false, - }, - dex: { - overrides: { - rpcURL: 'https://test.com', - }, + describe('config', () => { + it('should fetch configs and cache them', async () => { + const mockResponse = { + status: 200, + data: { + connect: { + walletConnect: false, + }, + dex: { + overrides: { + rpcURL: 'https://test.com', }, - allowedNetworks: [ChainId.SEPOLIA], }, - } as AxiosResponse; - mockedHttpClient.get.mockResolvedValueOnce(mockResponse); + allowedNetworks: [ChainId.SEPOLIA], + }, + } as AxiosResponse; + mockedHttpClient.get.mockResolvedValueOnce(mockResponse); + + const fetcher = new RemoteConfigFetcher(mockedHttpClient, 'testEndpoint'); + + expect(await fetcher.getConfig()).toEqual({ + connect: { + walletConnect: false, + }, + dex: { + overrides: { + rpcURL: 'https://test.com', + }, + }, + allowedNetworks: [ChainId.SEPOLIA], + }); - const fetcher = new RemoteConfigFetcher(mockedHttpClient, { - isDevelopment: env === ENV_DEVELOPMENT, - isProduction: env !== ENV_DEVELOPMENT && env === Environment.PRODUCTION, - }); + expect(mockedHttpClient.get).toHaveBeenCalledTimes(1); + expect(mockedHttpClient.get).toHaveBeenNthCalledWith( + 1, + `testEndpoint/${version}/config`, + ); + }); - expect(await fetcher.getConfig()).toEqual({ + it('should fetch config for key', async () => { + const mockResponse = { + status: 200, + data: { connect: { walletConnect: false, }, @@ -56,70 +69,38 @@ describe('RemoteConfig', () => { }, }, allowedNetworks: [ChainId.SEPOLIA], - }); + }, + } as AxiosResponse; + mockedHttpClient.get.mockResolvedValueOnce(mockResponse); - expect(mockedHttpClient.get).toHaveBeenCalledTimes(1); - expect(mockedHttpClient.get).toHaveBeenNthCalledWith( - 1, - `${CHECKOUT_CDN_BASE_URL[env]}/${version}/config`, - ); - }); + const fetcher = new RemoteConfigFetcher(mockedHttpClient, 'testEndpoint'); - it(`should fetch config for key [${env}]`, async () => { - const mockResponse = { - status: 200, - data: { - connect: { - walletConnect: false, - }, - dex: { - overrides: { - rpcURL: 'https://test.com', - }, - }, - allowedNetworks: [ChainId.SEPOLIA], - }, - } as AxiosResponse; - mockedHttpClient.get.mockResolvedValueOnce(mockResponse); + expect(await fetcher.getConfig('allowedNetworks')).toEqual([ChainId.SEPOLIA]); + }); - const fetcher = new RemoteConfigFetcher(mockedHttpClient, { - isDevelopment: env === ENV_DEVELOPMENT, - isProduction: env !== ENV_DEVELOPMENT && env === Environment.PRODUCTION, - }); + it('should return undefined if missing config', async () => { + const mockResponse = { + status: 200, + } as AxiosResponse; + mockedHttpClient.get.mockResolvedValueOnce(mockResponse); - expect(await fetcher.getConfig('allowedNetworks')).toEqual([ChainId.SEPOLIA]); - }); + const fetcher = new RemoteConfigFetcher(mockedHttpClient, 'testEndpoint'); - it(`should return undefined if missing config [${env}]`, async () => { - const mockResponse = { - status: 200, - } as AxiosResponse; - mockedHttpClient.get.mockResolvedValueOnce(mockResponse); + expect(await fetcher.getConfig()).toBeUndefined(); + }); - const fetcher = new RemoteConfigFetcher(mockedHttpClient, { - isDevelopment: env === ENV_DEVELOPMENT, - isProduction: env !== ENV_DEVELOPMENT && env === Environment.PRODUCTION, - }); + it('should throw error when configuration is invalid JSON', async () => { + const mockInvalidJSONResponse = { + status: 200, + data: 'invalid json', + } as AxiosResponse; + mockedHttpClient.get.mockResolvedValue(mockInvalidJSONResponse); - expect(await fetcher.getConfig()).toBeUndefined(); - }); + const fetcher = new RemoteConfigFetcher(mockedHttpClient, 'testEndpoint'); - it('should throw error when configuration is invalid JSON', async () => { - const mockInvalidJSONResponse = { - status: 200, - data: 'invalid json', - } as AxiosResponse; - mockedHttpClient.get.mockResolvedValue(mockInvalidJSONResponse); - - const fetcher = new RemoteConfigFetcher(mockedHttpClient, { - isDevelopment: env === ENV_DEVELOPMENT, - isProduction: env !== ENV_DEVELOPMENT && env === Environment.PRODUCTION, - }); - - await expect(fetcher.getConfig()).rejects.toThrowError( - new Error('Invalid configuration'), - ); - }); + await expect(fetcher.getConfig()).rejects.toThrowError( + new Error('Invalid configuration'), + ); }); }); }); diff --git a/packages/checkout/sdk/src/config/remoteConfigFetcher.ts b/packages/checkout/sdk/src/config/remoteConfigFetcher.ts index 3acf7be998..d909860fab 100644 --- a/packages/checkout/sdk/src/config/remoteConfigFetcher.ts +++ b/packages/checkout/sdk/src/config/remoteConfigFetcher.ts @@ -1,38 +1,22 @@ -import { Environment } from '@imtbl/config'; import { AxiosResponse } from 'axios'; import { RemoteConfiguration } from '../types'; -import { CHECKOUT_CDN_BASE_URL, ENV_DEVELOPMENT } from '../env'; import { HttpClient } from '../api/http'; import { CheckoutError, CheckoutErrorType } from '../errors'; -export type RemoteConfigParams = { - isDevelopment: boolean; - isProduction: boolean; -}; - export class RemoteConfigFetcher { private httpClient: HttpClient; - private isDevelopment: boolean; - - private isProduction: boolean; + private endpoint: string; private configCache: RemoteConfiguration | undefined; private version: string = 'v1'; - constructor(httpClient: HttpClient, params: RemoteConfigParams) { - this.isDevelopment = params.isDevelopment; - this.isProduction = params.isProduction; + constructor(httpClient: HttpClient, endpoint: string) { this.httpClient = httpClient; + this.endpoint = endpoint; } - private getEndpoint = () => { - if (this.isDevelopment) return CHECKOUT_CDN_BASE_URL[ENV_DEVELOPMENT]; - if (this.isProduction) return CHECKOUT_CDN_BASE_URL[Environment.PRODUCTION]; - return CHECKOUT_CDN_BASE_URL[Environment.SANDBOX]; - }; - // eslint-disable-next-line class-methods-use-this private parseResponse(response: AxiosResponse): T { let responseData: T = response.data; @@ -56,7 +40,7 @@ export class RemoteConfigFetcher { let response: AxiosResponse; try { response = await this.httpClient.get( - `${this.getEndpoint()}/${this.version}/config`, + `${this.endpoint}/${this.version}/config`, ); } catch (err: any) { throw new CheckoutError( diff --git a/packages/checkout/sdk/src/config/tokensFetcher.test.ts b/packages/checkout/sdk/src/config/tokensFetcher.test.ts index d55c6ad9cf..7db4e90ef9 100644 --- a/packages/checkout/sdk/src/config/tokensFetcher.test.ts +++ b/packages/checkout/sdk/src/config/tokensFetcher.test.ts @@ -1,6 +1,6 @@ import { Environment } from '@imtbl/config'; import { AxiosResponse } from 'axios'; -import { ChainId, RemoteConfiguration } from '../types'; +import { ChainId, ChainSlug, RemoteConfiguration } from '../types'; import { RemoteConfigFetcher } from './remoteConfigFetcher'; import { ENV_DEVELOPMENT } from '../env'; import { HttpClient } from '../api/http'; @@ -19,10 +19,7 @@ describe('TokensFetcher', () => { beforeEach(() => { mockedHttpClient = new HttpClient() as jest.Mocked; - mockedConfigClient = new RemoteConfigFetcher(mockedHttpClient, { - isDevelopment: true, - isProduction: false, - }) as jest.Mocked; + mockedConfigClient = new RemoteConfigFetcher(mockedHttpClient, 'testEndpoint') as jest.Mocked; mockedConfigClient.getConfig.mockResolvedValue({ [ChainId.IMTBL_ZKEVM_TESTNET]: 'native', @@ -109,11 +106,11 @@ describe('TokensFetcher', () => { const fetcher = new TokensFetcher( mockedHttpClient, mockedConfigClient, - { - isDevelopment: env === ENV_DEVELOPMENT, - isProduction: - env !== ENV_DEVELOPMENT && env === Environment.PRODUCTION, - }, + 'baseUrl', + // eslint-disable-next-line no-nested-ternary + env === ENV_DEVELOPMENT ? ChainSlug.IMTBL_ZKEVM_DEVNET + : env === Environment.SANDBOX ? ChainSlug.IMTBL_ZKEVM_TESTNET + : ChainSlug.IMTBL_ZKEVM_MAINNET, ); const chainsTokenConfig = await fetcher.getChainTokensConfig(); @@ -193,11 +190,11 @@ describe('TokensFetcher', () => { const fetcher = new TokensFetcher( mockedHttpClient, mockedConfigClient, - { - isDevelopment: env === ENV_DEVELOPMENT, - isProduction: - env !== ENV_DEVELOPMENT && env === Environment.PRODUCTION, - }, + 'baseUrl', + // eslint-disable-next-line no-nested-ternary + env === ENV_DEVELOPMENT ? ChainSlug.IMTBL_ZKEVM_DEVNET + : env === Environment.SANDBOX ? ChainSlug.IMTBL_ZKEVM_TESTNET + : ChainSlug.IMTBL_ZKEVM_MAINNET, ); expect(await fetcher.getChainTokensConfig()).toEqual({}); diff --git a/packages/checkout/sdk/src/config/tokensFetcher.ts b/packages/checkout/sdk/src/config/tokensFetcher.ts index a4e4188a4c..4cb871b015 100644 --- a/packages/checkout/sdk/src/config/tokensFetcher.ts +++ b/packages/checkout/sdk/src/config/tokensFetcher.ts @@ -1,4 +1,3 @@ -import { Environment } from '@imtbl/config'; import { AxiosResponse } from 'axios'; import { ChainId, @@ -7,7 +6,6 @@ import { ImxAddressConfig, TokenBridgeInfo, } from '../types'; -import { ENV_DEVELOPMENT, IMMUTABLE_API_BASE_URL } from '../env'; import { HttpClient } from '../api/http'; import { CheckoutError, CheckoutErrorType } from '../errors'; import { RemoteConfigFetcher } from './remoteConfigFetcher'; @@ -34,45 +32,30 @@ type TokensEndpointResponse = { result: TokensEndpointResult[]; }; -export type RemoteConfigParams = { - isDevelopment: boolean; - isProduction: boolean; -}; - export class TokensFetcher { private httpClient: HttpClient; private remoteConfig: RemoteConfigFetcher; - private readonly isDevelopment: boolean; + private tokensCache: ChainTokensConfig | undefined; - private readonly isProduction: boolean; + private baseUrl: string; - private tokensCache: ChainTokensConfig | undefined; + private chainSlug: ChainSlug; constructor( httpClient: HttpClient, remoteConfig: RemoteConfigFetcher, - params: RemoteConfigParams, + baseUrl: string, + chainSlug: ChainSlug, ) { - this.isDevelopment = params.isDevelopment; - this.isProduction = params.isProduction; + console.log({ baseUrl, chainSlug }); this.httpClient = httpClient; this.remoteConfig = remoteConfig; + this.baseUrl = baseUrl; + this.chainSlug = chainSlug; } - private getBaseUrl = () => { - if (this.isDevelopment) return IMMUTABLE_API_BASE_URL[ENV_DEVELOPMENT]; - if (this.isProduction) return IMMUTABLE_API_BASE_URL[Environment.PRODUCTION]; - return IMMUTABLE_API_BASE_URL[Environment.SANDBOX]; - }; - - private getChainSlug = () => { - if (this.isDevelopment) return ChainSlug.IMTBL_ZKEVM_DEVNET; - if (this.isProduction) return ChainSlug.IMTBL_ZKEVM_MAINNET; - return ChainSlug.IMTBL_ZKEVM_TESTNET; - }; - private async loadTokens(): Promise { if (this.tokensCache) { return this.tokensCache; @@ -81,7 +64,7 @@ export class TokensFetcher { let response: AxiosResponse; try { response = await this.httpClient.get( - `${this.getBaseUrl()}/v1/chains/${this.getChainSlug()}/tokens?verification_status=verified&is_canonical=true`, + `${this.baseUrl}/v1/chains/${this.chainSlug}/tokens?verification_status=verified&is_canonical=true`, ); } catch (err: any) { throw new CheckoutError( diff --git a/packages/checkout/sdk/src/gasEstimate/bridgeGasEstimate.ts b/packages/checkout/sdk/src/gasEstimate/bridgeGasEstimate.ts index 823e2ec088..3d89bbaf55 100644 --- a/packages/checkout/sdk/src/gasEstimate/bridgeGasEstimate.ts +++ b/packages/checkout/sdk/src/gasEstimate/bridgeGasEstimate.ts @@ -3,7 +3,7 @@ import { BridgeFeeResponse, TokenBridge, } from '@imtbl/bridge-sdk'; -import { CheckoutConfiguration, getL1ChainId } from '../config'; +import { CheckoutConfiguration } from '../config'; import { ChainId } from '../types'; import { NATIVE } from '../env/constants'; @@ -13,7 +13,7 @@ export async function getBridgeFeeEstimate( toChainId: ChainId, config: CheckoutConfiguration, ): Promise { - const bridgeFeeAction = fromChainId === getL1ChainId(config) + const bridgeFeeAction = fromChainId === config.l1ChainId ? BridgeFeeActions.DEPOSIT : BridgeFeeActions.WITHDRAW; diff --git a/packages/checkout/sdk/src/gasEstimate/gasEstimator.ts b/packages/checkout/sdk/src/gasEstimate/gasEstimator.ts index dacee0de7b..431d4a2c10 100644 --- a/packages/checkout/sdk/src/gasEstimate/gasEstimator.ts +++ b/packages/checkout/sdk/src/gasEstimate/gasEstimator.ts @@ -13,7 +13,7 @@ import { getBridgeFeeEstimate, } from './bridgeGasEstimate'; import * as instance from '../instance'; -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../config'; +import { CheckoutConfiguration } from '../config'; const DUMMY_WALLET_ADDRESS = '0x0000000000000000000000000000000000000001'; const DEFAULT_TOKEN_DECIMALS = 18; @@ -22,8 +22,8 @@ async function bridgeToL2GasEstimator( readOnlyProviders: Map, config: CheckoutConfiguration, ): Promise { - const fromChainId = getL1ChainId(config); - const toChainId = getL2ChainId(config); + const fromChainId = config.l1ChainId; + const toChainId = config.l2ChainId; const provider = readOnlyProviders.get(fromChainId); if (!provider) throw new Error(`Missing JsonRpcProvider for chain id: ${fromChainId}`); @@ -68,7 +68,7 @@ async function bridgeToL2GasEstimator( async function swapGasEstimator( config: CheckoutConfiguration, ): Promise { - const chainId = getL2ChainId(config); + const chainId = config.l2ChainId; const gasEstimateTokensConfig = (await config.remote.getConfig( 'gasEstimateTokens', diff --git a/packages/checkout/sdk/src/instance/instance.ts b/packages/checkout/sdk/src/instance/instance.ts index c551d74dab..fc11ce5cd6 100644 --- a/packages/checkout/sdk/src/instance/instance.ts +++ b/packages/checkout/sdk/src/instance/instance.ts @@ -1,8 +1,5 @@ import { BridgeConfiguration, - ETH_MAINNET_TO_ZKEVM_MAINNET, - ETH_SEPOLIA_TO_ZKEVM_DEVNET, - ETH_SEPOLIA_TO_ZKEVM_TESTNET, TokenBridge, } from '@imtbl/bridge-sdk'; import { ImmutableConfiguration } from '@imtbl/config'; @@ -36,13 +33,9 @@ export function createBridgeInstance( ); } - let bridgeInstance = ETH_SEPOLIA_TO_ZKEVM_TESTNET; - if (config.isDevelopment) bridgeInstance = ETH_SEPOLIA_TO_ZKEVM_DEVNET; - if (config.isProduction) bridgeInstance = ETH_MAINNET_TO_ZKEVM_MAINNET; - const bridgeConfig = new BridgeConfiguration({ baseConfig: new ImmutableConfiguration({ environment: config.environment }), - bridgeInstance, + bridgeInstance: config.bridgeInstance, rootProvider: rootChainProvider, childProvider: childChainProvider, }); diff --git a/packages/checkout/sdk/src/logger/debugLogger.test.ts b/packages/checkout/sdk/src/logger/debugLogger.test.ts index fdb7844a53..9836bb192f 100644 --- a/packages/checkout/sdk/src/logger/debugLogger.test.ts +++ b/packages/checkout/sdk/src/logger/debugLogger.test.ts @@ -1,4 +1,4 @@ -/* eslint-disable import/no-cycle */ +import { Environment } from '@imtbl/config'; import { CheckoutConfiguration } from '../config'; import { debugLogger, measureAsyncExecution } from './debugLogger'; @@ -8,7 +8,7 @@ describe('debugLogger', () => { }); it('should call underlying function and return result of the promise', async () => { - const testCheckoutConfig = { isProduction: false } as CheckoutConfiguration; + const testCheckoutConfig = { environment: Environment.SANDBOX } as CheckoutConfiguration; const debugString = 'Test Debug String'; const mockResult = 'Mock Result'; const mockPromise = new Promise((resolve) => { @@ -19,7 +19,7 @@ describe('debugLogger', () => { }); it('should call console if production false', () => { - const testCheckoutConfig = { isProduction: false } as CheckoutConfiguration; + const testCheckoutConfig = { environment: Environment.SANDBOX } as CheckoutConfiguration; const consoleDebugSpy = jest.spyOn(console, 'info').mockImplementation(); const debugString = 'Test Debug String'; debugLogger(testCheckoutConfig, debugString, 1); @@ -28,7 +28,7 @@ describe('debugLogger', () => { }); it('should not call console if production', () => { - const testCheckoutConfig = { isProduction: true } as CheckoutConfiguration; + const testCheckoutConfig = { environment: Environment.PRODUCTION } as CheckoutConfiguration; const consoleDebugSpy = jest.spyOn(console, 'info').mockImplementation(); const debugString = 'Test Debug String'; debugLogger(testCheckoutConfig, debugString, 1); diff --git a/packages/checkout/sdk/src/logger/debugLogger.ts b/packages/checkout/sdk/src/logger/debugLogger.ts index c6570c469f..d400441fac 100644 --- a/packages/checkout/sdk/src/logger/debugLogger.ts +++ b/packages/checkout/sdk/src/logger/debugLogger.ts @@ -1,9 +1,10 @@ /* eslint-disable import/no-cycle */ +import { Environment } from '@imtbl/config'; import { CheckoutConfiguration } from '../config'; export const debugLogger = (config: CheckoutConfiguration, debugString: string, seconds: number) => { // eslint-disable-next-line no-console - if (!config.isProduction) console.info(debugString, seconds); + if (config.environment !== Environment.PRODUCTION) console.info(debugString, seconds); }; export const measureAsyncExecution = async ( diff --git a/packages/checkout/sdk/src/readOnlyProviders/readOnlyProvider.ts b/packages/checkout/sdk/src/readOnlyProviders/readOnlyProvider.ts index 19b74f9741..23d64c1fca 100644 --- a/packages/checkout/sdk/src/readOnlyProviders/readOnlyProvider.ts +++ b/packages/checkout/sdk/src/readOnlyProviders/readOnlyProvider.ts @@ -1,4 +1,5 @@ import { JsonRpcProvider } from 'ethers'; +import { Environment } from '@imtbl/config'; import * as network from '../network'; import { ChainId, NetworkFilterTypes } from '../types'; import { CheckoutConfiguration } from '../config'; @@ -7,7 +8,11 @@ export async function createReadOnlyProviders( config: CheckoutConfiguration, existingReadOnlyProviders?: Map, ): Promise> { - if (config.isProduction && existingReadOnlyProviders?.has(ChainId.ETHEREUM)) return existingReadOnlyProviders; + if ( + config.environment === Environment.PRODUCTION + && existingReadOnlyProviders?.has(ChainId.ETHEREUM) + ) return existingReadOnlyProviders; + if (existingReadOnlyProviders?.has(ChainId.SEPOLIA)) return existingReadOnlyProviders; const readOnlyProviders = new Map(); diff --git a/packages/checkout/sdk/src/sdk.test.ts b/packages/checkout/sdk/src/sdk.test.ts index eab2c3a066..eb9a62a1d2 100644 --- a/packages/checkout/sdk/src/sdk.test.ts +++ b/packages/checkout/sdk/src/sdk.test.ts @@ -568,6 +568,7 @@ describe('Connect', () => { expect(buy).toBeCalledWith( checkout.config, provider, + checkout.availability, [{ id: '1', takerFees: [] }], undefined, ); @@ -613,7 +614,7 @@ describe('Connect', () => { }); expect(sell).toBeCalledTimes(1); - expect(sell).toBeCalledWith(checkout.config, provider, orders); + expect(sell).toBeCalledWith(checkout.config, provider, checkout.availability, orders); }); it('should call cancel function', async () => { @@ -675,6 +676,7 @@ describe('Connect', () => { expect(smartCheckout).toBeCalledWith( checkout.config, params.provider, + checkout.availability, params.itemRequirements, params.transactionOrGasAmount, undefined, diff --git a/packages/checkout/sdk/src/sdk.ts b/packages/checkout/sdk/src/sdk.ts index e290c037aa..9dc62f26c7 100644 --- a/packages/checkout/sdk/src/sdk.ts +++ b/packages/checkout/sdk/src/sdk.ts @@ -104,14 +104,8 @@ export class Checkout { this.httpClient = new HttpClient(config); this.config = new CheckoutConfiguration(config, this.httpClient); this.fiatRampService = new FiatRampService(this.config); - this.readOnlyProviders = new Map< - ChainId, - JsonRpcProvider - >(); - this.availability = availabilityService( - this.config.isDevelopment, - this.config.isProduction, - ); + this.readOnlyProviders = new Map(); + this.availability = availabilityService(this.config.baseUrl); this.passport = config.passport; // Initialise injected providers via EIP-6963 @@ -495,6 +489,7 @@ export class Checkout { return await buy.buy( this.config, browserProvider, + this.availability, params.orders, params.overrides, ); @@ -522,7 +517,7 @@ export class Checkout { params.provider, ); - return await sell.sell(this.config, browserProvider, params.orders); + return await sell.sell(this.config, browserProvider, this.availability, params.orders); } /** @@ -587,6 +582,7 @@ export class Checkout { return await smartCheckout.smartCheckout( this.config, browserProvider, + this.availability, itemRequirements, params.transactionOrGasAmount, params.routingOptions, diff --git a/packages/checkout/sdk/src/smartCheckout/allowList/allowListCheck.ts b/packages/checkout/sdk/src/smartCheckout/allowList/allowListCheck.ts index 601d3feed9..6fd3f6c242 100644 --- a/packages/checkout/sdk/src/smartCheckout/allowList/allowListCheck.ts +++ b/packages/checkout/sdk/src/smartCheckout/allowList/allowListCheck.ts @@ -1,4 +1,4 @@ -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../config'; +import { CheckoutConfiguration } from '../../config'; import { getTokenAllowList } from '../../tokens'; import { AvailableRoutingOptions, @@ -43,7 +43,7 @@ export const allowListCheckForBridge = async ( availableRoutingOptions: AvailableRoutingOptions, ) : Promise => { if (availableRoutingOptions.bridge) { - const chainId = getL1ChainId(config); + const chainId = config.l1ChainId; const allowedTokens = (await getTokenAllowList(config, { type: TokenFilterTypes.BRIDGE, chainId })).tokens; const balances = tokenBalances.get(chainId); return filterTokens(allowedTokens, balances); @@ -59,7 +59,7 @@ export const allowListCheckForSwap = async ( ) : Promise => { if (availableRoutingOptions.swap) { const allowedTokens = (await getTokenAllowList(config, { type: TokenFilterTypes.SWAP })).tokens; - const balances = tokenBalances.get(getL2ChainId(config)); + const balances = tokenBalances.get(config.l2ChainId); return filterTokens(allowedTokens, balances); } diff --git a/packages/checkout/sdk/src/smartCheckout/balanceCheck/balanceCheck.ts b/packages/checkout/sdk/src/smartCheckout/balanceCheck/balanceCheck.ts index 991a9eaef6..11a1f9573d 100644 --- a/packages/checkout/sdk/src/smartCheckout/balanceCheck/balanceCheck.ts +++ b/packages/checkout/sdk/src/smartCheckout/balanceCheck/balanceCheck.ts @@ -12,7 +12,7 @@ import { TokenInfo, } from '../../types'; import { getAllBalances } from '../../balances'; -import { CheckoutConfiguration, getL2ChainId } from '../../config'; +import { CheckoutConfiguration } from '../../config'; import { BalanceCheckResult, BalanceRequirement } from './types'; import { CheckoutError, CheckoutErrorType } from '../../errors'; import { balanceAggregator } from '../aggregators/balanceAggregator'; @@ -43,7 +43,7 @@ const getTokenBalances = async ( tokenMap.set(item.address.toLocaleLowerCase(), item); }, ); - const { balances } = await getAllBalances(config, provider, ownerAddress, getL2ChainId(config), forceFetch); + const { balances } = await getAllBalances(config, provider, ownerAddress, config.l2ChainId, forceFetch); return balances.filter( (balance) => tokenMap.get((balance.token.address || NATIVE).toLocaleLowerCase()), ) as TokenBalance[]; diff --git a/packages/checkout/sdk/src/smartCheckout/buy/buy.test.ts b/packages/checkout/sdk/src/smartCheckout/buy/buy.test.ts index ad809e722e..bac66ac8fd 100644 --- a/packages/checkout/sdk/src/smartCheckout/buy/buy.test.ts +++ b/packages/checkout/sdk/src/smartCheckout/buy/buy.test.ts @@ -26,6 +26,7 @@ import { SignTransactionStatusType } from '../actions/types'; import { INDEXER_ETH_ROOT_CONTRACT_ADDRESS } from '../routing/indexer/fetchL1Representation'; import { HttpClient } from '../../api/http'; import { sendTransaction } from '../../transaction'; +import { AvailabilityService } from '../../availability'; jest.mock('../../instance'); jest.mock('../smartCheckout'); @@ -45,6 +46,7 @@ describe('buy', () => { describe('buy', () => { let config: CheckoutConfiguration; let mockProvider: WrappedBrowserProvider; + let availabilityService: AvailabilityService; beforeEach(() => { mockProvider = { @@ -53,6 +55,10 @@ describe('buy', () => { }), } as unknown as WrappedBrowserProvider; + availabilityService = { + checkDexAvailability: jest.fn().mockResolvedValue(true), + } as unknown as AvailabilityService; + config = new CheckoutConfiguration({ baseConfig: { environment: Environment.SANDBOX }, }, mockedHttpClient); @@ -160,10 +166,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, [order]); + const buyResult = await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); @@ -340,10 +347,11 @@ describe('buy', () => { }, }; - const buyResult = await buy(config, mockProvider, [order]); + const buyResult = await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, gasTransaction, ); @@ -471,10 +479,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, [order]); + const buyResult = await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); @@ -604,10 +613,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, [order]); + const buyResult = await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); @@ -786,12 +796,14 @@ describe('buy', () => { const buyResult = await buy( config, mockProvider, + availabilityService, [order], { waitFulfillmentSettlements: false }, ); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, gasTransaction, ); @@ -970,7 +982,7 @@ describe('buy', () => { let errorType; let errorData; try { - await buy(config, mockProvider, [order]); + await buy(config, mockProvider, availabilityService, [order]); } catch (err: any) { errorType = err.type; errorData = err.data; @@ -982,6 +994,7 @@ describe('buy', () => { expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, gasTransaction, ); @@ -1047,10 +1060,11 @@ describe('buy', () => { }, }; - await buy(config, mockProvider, [order]); + await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, gasAmount, ); @@ -1156,10 +1170,11 @@ describe('buy', () => { }, }; - await buy(config, mockProvider, [order]); + await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, gasAmount, ); @@ -1262,10 +1277,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, [order]); + const buyResult = await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); @@ -1381,10 +1397,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, [order]); + const buyResult = await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); @@ -1505,10 +1522,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, [order]); + const buyResult = await buy(config, mockProvider, availabilityService, [order]); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); @@ -1564,7 +1582,7 @@ describe('buy', () => { let type; let data; try { - await buy(config, mockProvider, [order]); + await buy(config, mockProvider, availabilityService, [order]); } catch (err: any) { message = err.message; type = err.type; @@ -1615,7 +1633,7 @@ describe('buy', () => { let type; let data; try { - await buy(config, mockProvider, [order]); + await buy(config, mockProvider, availabilityService, [order]); } catch (err: any) { message = err.message; type = err.type; @@ -1668,7 +1686,7 @@ describe('buy', () => { let data; try { - await buy(config, mockProvider, [order]); + await buy(config, mockProvider, availabilityService, [order]); } catch (err: any) { message = err.message; type = err.type; @@ -1723,7 +1741,7 @@ describe('buy', () => { let data; try { - await buy(config, mockProvider, [order]); + await buy(config, mockProvider, availabilityService, [order]); } catch (err: any) { message = err.message; type = err.type; @@ -1740,6 +1758,7 @@ describe('buy', () => { describe('taker fees', () => { let config: CheckoutConfiguration; let mockProvider: WrappedBrowserProvider; + let availabilityService: AvailabilityService; beforeEach(() => { mockProvider = { @@ -1748,6 +1767,10 @@ describe('buy', () => { }), } as unknown as WrappedBrowserProvider; + availabilityService = { + checkDexAvailability: jest.fn().mockResolvedValue(true), + } as unknown as AvailabilityService; + config = new CheckoutConfiguration({ baseConfig: { environment: Environment.SANDBOX }, }, mockedHttpClient); @@ -1932,10 +1955,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, testCase.orders); + const buyResult = await buy(config, mockProvider, availabilityService, testCase.orders); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); @@ -2151,10 +2175,11 @@ describe('buy', () => { transaction: { from: '0xTRANSACTION' }, }; - const buyResult = await buy(config, mockProvider, testCase.orders); + const buyResult = await buy(config, mockProvider, availabilityService, testCase.orders); expect(smartCheckout).toBeCalledWith( config, mockProvider, + availabilityService, itemRequirements, fulfillmentTransaction, ); diff --git a/packages/checkout/sdk/src/smartCheckout/buy/buy.ts b/packages/checkout/sdk/src/smartCheckout/buy/buy.ts index 1cf1bb446f..7711975a86 100644 --- a/packages/checkout/sdk/src/smartCheckout/buy/buy.ts +++ b/packages/checkout/sdk/src/smartCheckout/buy/buy.ts @@ -12,7 +12,7 @@ import { mr } from '@imtbl/generated-clients'; import { track } from '@imtbl/metrics'; import { TransactionRequest, TransactionResponse } from 'ethers'; import * as instance from '../../instance'; -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../config'; +import { CheckoutConfiguration } from '../../config'; import { CheckoutError, CheckoutErrorType } from '../../errors'; import { ItemType, @@ -39,6 +39,7 @@ import { getAllBalances, resetBlockscoutClientMap } from '../../balances'; import { debugLogger, measureAsyncExecution } from '../../logger/debugLogger'; import { sendTransaction } from '../../transaction'; import { WrappedBrowserProvider } from '../../types'; +import { AvailabilityService } from '../../availability'; export const getItemRequirement = ( type: ItemType, @@ -89,6 +90,7 @@ export const getTransactionOrGas = ( export const buy = async ( config: CheckoutConfiguration, provider: WrappedBrowserProvider, + availability: AvailabilityService, orders: Array, overrides: BuyOverrides = { waitFulfillmentSettlements: true, @@ -119,8 +121,8 @@ export const buy = async ( // Prefetch balances and store them in memory resetBlockscoutClientMap(); - getAllBalances(config, provider, fulfillerAddress, getL1ChainId(config)); - getAllBalances(config, provider, fulfillerAddress, getL2ChainId(config)); + getAllBalances(config, provider, fulfillerAddress, config.l1ChainId); + getAllBalances(config, provider, fulfillerAddress, config.l2ChainId); const { id, takerFees, fillAmount } = orders[0]; @@ -277,6 +279,7 @@ export const buy = async ( smartCheckout( config, provider, + availability, itemRequirements, getTransactionOrGas( gasLimit, diff --git a/packages/checkout/sdk/src/smartCheckout/routing/bridge/bridgeRoute.ts b/packages/checkout/sdk/src/smartCheckout/routing/bridge/bridgeRoute.ts index f51f57340e..25628e1870 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/bridge/bridgeRoute.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/bridge/bridgeRoute.ts @@ -10,7 +10,7 @@ import { TokenInfo, FeeType, } from '../../../types'; -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../../config'; +import { CheckoutConfiguration } from '../../../config'; import { TokenBalanceResult, } from '../types'; @@ -121,16 +121,14 @@ export const bridgeRoute = async ( tokenBalanceResults: Map, ): Promise => { if (!availableRoutingOptions.bridge) return undefined; - const l1ChainId = getL1ChainId(config); - const l2ChainId = getL2ChainId(config); - const nativeToken = config.networkMap.get(l1ChainId)?.nativeCurrency; - const tokenBalanceResult = tokenBalanceResults.get(l1ChainId); - const l1provider = readOnlyProviders.get(l1ChainId); + const nativeToken = config.networkMap.get(config.l1ChainId)?.nativeCurrency; + const tokenBalanceResult = tokenBalanceResults.get(config.l1ChainId); + const l1provider = readOnlyProviders.get(config.l1ChainId); if (!l1provider) { throw new CheckoutError( 'No L1 provider available', CheckoutErrorType.PROVIDER_ERROR, - { chainId: l1ChainId.toString() }, + { chainId: config.l1ChainId.toString() }, ); } @@ -155,8 +153,8 @@ export const bridgeRoute = async ( const feesFromBridge = await getBridgeFeeEstimate( config, readOnlyProviders, - l1ChainId, - l2ChainId, + config.l1ChainId, + config.l2ChainId, ); const { @@ -185,7 +183,13 @@ export const bridgeRoute = async ( approvalGas, nativeToken, ); - return constructBridgeFundingRoute(l1ChainId, nativeETHBalance, bridgeRequirement, ItemType.NATIVE, bridgeFees); + return constructBridgeFundingRoute( + config.l1ChainId, + nativeETHBalance, + bridgeRequirement, + ItemType.NATIVE, + bridgeFees, + ); } return undefined; @@ -204,7 +208,7 @@ export const bridgeRoute = async ( approvalGas, nativeToken, ); - return constructBridgeFundingRoute(l1ChainId, erc20balance, bridgeRequirement, ItemType.ERC20, bridgeFees); + return constructBridgeFundingRoute(config.l1ChainId, erc20balance, bridgeRequirement, ItemType.ERC20, bridgeFees); } return undefined; diff --git a/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/bridgeAndSwapRoute.ts b/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/bridgeAndSwapRoute.ts index 4ec4717b53..4e135826c0 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/bridgeAndSwapRoute.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/bridgeAndSwapRoute.ts @@ -1,5 +1,5 @@ import { formatUnits, JsonRpcProvider } from 'ethers'; -import { CheckoutConfiguration, getL2ChainId } from '../../../config'; +import { CheckoutConfiguration } from '../../../config'; import { AvailableRoutingOptions, BridgeFundingStep, @@ -120,7 +120,7 @@ const modifyTokenBalancesWithBridgedAmount = ( const updatedBalances = Array.from(balanceMap.values()); modifiedTokenBalances.set( - getL2ChainId(config), + config.l2ChainId, { success: true, balances: updatedBalances, diff --git a/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getBalancesByChain.ts b/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getBalancesByChain.ts index 4495b503a7..73b68dea39 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getBalancesByChain.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getBalancesByChain.ts @@ -1,4 +1,4 @@ -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../../config'; +import { CheckoutConfiguration } from '../../../config'; import { ChainId, GetBalanceResult } from '../../../types'; import { TokenBalanceResult } from '../types'; @@ -11,8 +11,8 @@ export const getBalancesByChain = ( } => { const balances = { l1balances: [], l2balances: [] }; - const l1balancesResult = tokenBalances.get(getL1ChainId(config)); - const l2balancesResult = tokenBalances.get(getL2ChainId(config)); + const l1balancesResult = tokenBalances.get(config.l1ChainId); + const l2balancesResult = tokenBalances.get(config.l2ChainId); // If there are no l1 balance then cannot bridge if (!l1balancesResult) return balances; diff --git a/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getDexQuotes.ts b/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getDexQuotes.ts index 6f4d6e1427..809bc4cac6 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getDexQuotes.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/bridgeAndSwap/getDexQuotes.ts @@ -1,4 +1,4 @@ -import { CheckoutConfiguration, getL2ChainId } from '../../../config'; +import { CheckoutConfiguration } from '../../../config'; import { DexQuotes } from '../types'; import { BalanceNativeRequirement, BalanceERC20Requirement } from '../../balanceCheck/types'; import { TokenInfo } from '../../../types'; @@ -20,7 +20,7 @@ export const getDexQuotes = async ( const dexQuotes = await quoteFetcher( config, - getL2ChainId(config), + config.l2ChainId, ownerAddress, { address: requiredTokenAddress as string, diff --git a/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.test.ts b/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.test.ts index 727d9375f1..5a9a6f6ff3 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.test.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.test.ts @@ -1,45 +1,35 @@ -import { Environment } from '@imtbl/config'; -import { CheckoutConfiguration } from '../../config'; import { isSwapAvailable } from './geoBlocking'; -import { availabilityService } from '../../availability'; -import { HttpClient } from '../../api/http'; +import { AvailabilityService } from '../../availability'; jest.mock('../../availability'); describe('geoBlocking', () => { - let config: CheckoutConfiguration; - - beforeEach(() => { - const mockedHttpClient = new HttpClient() as jest.Mocked; - config = new CheckoutConfiguration({ - baseConfig: { environment: Environment.PRODUCTION }, - }, mockedHttpClient); - }); + let availabilityService: AvailabilityService; describe('isSwapAvailable', () => { it('should return true if checkDexAvailability returns true', async () => { - (availabilityService as jest.Mock).mockReturnValue({ + availabilityService = { checkDexAvailability: jest.fn().mockResolvedValue(true), - }); - const response = await isSwapAvailable(config); + } as unknown as AvailabilityService; + const response = await isSwapAvailable(availabilityService); expect(response).toEqual(true); }); it('should return false if checkDexAvailability returns false', async () => { - (availabilityService as jest.Mock).mockReturnValue({ + availabilityService = { checkDexAvailability: jest.fn().mockResolvedValue(false), - }); - const response = await isSwapAvailable(config); + } as unknown as AvailabilityService; + const response = await isSwapAvailable(availabilityService); expect(response).toEqual(false); }); it('should return false by default', async () => { - (availabilityService as jest.Mock).mockReturnValue({ + availabilityService = { checkDexAvailability: jest.fn().mockRejectedValue(new Error()), - }); - const response = await isSwapAvailable(config); + } as unknown as AvailabilityService; + const response = await isSwapAvailable(availabilityService); expect(response).toEqual(false); }); diff --git a/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.ts b/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.ts index e7f07d228a..0c5e2fc9ef 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/geoBlocking.ts @@ -1,13 +1,10 @@ -import { availabilityService } from '../../availability'; -import { CheckoutConfiguration } from '../../config'; +import { AvailabilityService } from '../../availability'; export const isOnRampAvailable = async (): Promise => true; export const isSwapAvailable = async ( - config: CheckoutConfiguration, + availability: AvailabilityService, ): Promise => { - const availability = availabilityService(config.isDevelopment, config.isProduction); - try { return await availability.checkDexAvailability(); } catch { diff --git a/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.test.ts b/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.test.ts index bb3607aef0..e966f4e1d1 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.test.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.test.ts @@ -41,6 +41,7 @@ describe('fetchL1Representation', () => { const result = await fetchL1Representation( { + l1ChainId: ChainId.SEPOLIA, remote: { getConfig: jest.fn().mockResolvedValue({ [ChainId.SEPOLIA]: '0x2Fa06C6672dDCc066Ab04631192738799231dE4a', @@ -82,6 +83,7 @@ describe('fetchL1Representation', () => { const requiredL2Address = ''; const result = await fetchL1Representation( { + l1ChainId: ChainId.SEPOLIA, remote: { getConfig: jest.fn().mockResolvedValue({ [ChainId.SEPOLIA]: '0xIMX_ADDRESS', diff --git a/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.ts b/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.ts index a5c990b535..7ac1fa82d0 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/indexer/fetchL1Representation.ts @@ -1,20 +1,13 @@ -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../../config'; +import { CheckoutConfiguration } from '../../../config'; import { createBlockchainDataInstance } from '../../../instance'; import { NATIVE } from '../../../env'; -import { ChainId, ChainSlug, ImxAddressConfig } from '../../../types'; +import { ChainId, ImxAddressConfig } from '../../../types'; import { isNativeToken } from '../../../tokens'; import { isMatchingAddress } from '../../../utils/utils'; // If the root address evaluates to this then its ETH export const INDEXER_ETH_ROOT_CONTRACT_ADDRESS = '0x0000000000000000000000000000000000000eee'; -const getIndexerChainName = (chainId: ChainId): string => { - if (chainId === ChainId.IMTBL_ZKEVM_MAINNET) return ChainSlug.IMTBL_ZKEVM_MAINNET; - if (chainId === ChainId.IMTBL_ZKEVM_TESTNET) return ChainSlug.IMTBL_ZKEVM_TESTNET; - if (chainId === ChainId.IMTBL_ZKEVM_DEVNET) return ChainSlug.IMTBL_ZKEVM_DEVNET; - return ''; -}; - // Indexer ERC20 call does not support IMX so cannot get root chain mapping from this endpoint. // Use the remote config instead to find IMX address mapping. export const getImxL1Representation = async (chainId: ChainId, config: CheckoutConfiguration): Promise => { @@ -35,15 +28,14 @@ export const fetchL1Representation = async ( ): Promise => { if (isNativeToken(l2address)) { return { - l1address: await getImxL1Representation(getL1ChainId(config), config), + l1address: await getImxL1Representation(config.l1ChainId, config), l2address: NATIVE, }; } - const chainName = getIndexerChainName(getL2ChainId(config)); const blockchainData = createBlockchainDataInstance(config); const tokenData = await blockchainData.getToken({ - chainName, + chainName: config.chainSlug, contractAddress: l2address, }); diff --git a/packages/checkout/sdk/src/smartCheckout/routing/onRamp/onRampRoute.ts b/packages/checkout/sdk/src/smartCheckout/routing/onRamp/onRampRoute.ts index edaae2c361..ef0f22071a 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/onRamp/onRampRoute.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/onRamp/onRampRoute.ts @@ -1,4 +1,4 @@ -import { CheckoutConfiguration, getL2ChainId } from '../../../config'; +import { CheckoutConfiguration } from '../../../config'; import { AvailableRoutingOptions, FundingStepType, @@ -37,7 +37,7 @@ export const onRampRoute = async ( return { type: FundingStepType.ONRAMP, - chainId: getL2ChainId(config), + chainId: config.l2ChainId, fundingItem: { type: isNativeToken(required.token.address) ? ItemType.NATIVE : ItemType.ERC20, fundsRequired: { diff --git a/packages/checkout/sdk/src/smartCheckout/routing/routingCalculator.ts b/packages/checkout/sdk/src/smartCheckout/routing/routingCalculator.ts index 8ec369cf55..77fa8faf68 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/routingCalculator.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/routingCalculator.ts @@ -17,8 +17,6 @@ import { TokenBalanceResult } from './types'; import { getAllTokenBalances } from './tokenBalances'; import { CheckoutConfiguration, - getL1ChainId, - getL2ChainId, } from '../../config'; import { createReadOnlyProviders } from '../../readOnlyProviders/readOnlyProvider'; import { CheckoutError, CheckoutErrorType } from '../../errors'; @@ -105,7 +103,7 @@ export const getSwapFundingSteps = async ( if (insufficientRequirement === undefined) return fundingSteps; if (swapTokenAllowList === undefined) return fundingSteps; - const tokenBalanceResult = tokenBalances.get(getL2ChainId(config)); + const tokenBalanceResult = tokenBalances.get(config.l2ChainId); if (!tokenBalanceResult) return fundingSteps; if (tokenBalanceResult.error !== undefined || !tokenBalanceResult.success) return fundingSteps; @@ -139,8 +137,8 @@ export const getBridgeAndSwapFundingSteps = async ( ): Promise => { if (!insufficientRequirement) return []; - const l1balancesResult = tokenBalances.get(getL1ChainId(config)); - const l2balancesResult = tokenBalances.get(getL2ChainId(config)); + const l1balancesResult = tokenBalances.get(config.l1ChainId); + const l2balancesResult = tokenBalances.get(config.l2ChainId); // If there are no l1 balance then cannot bridge if (!l1balancesResult) return []; diff --git a/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.test.ts b/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.test.ts index 7b81607432..00f15da951 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.test.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.test.ts @@ -5,11 +5,13 @@ import * as geoBlocking from './geoBlocking'; import { DEFAULT_BRIDGE_ENABLED, DEFAULT_ON_RAMP_ENABLED, DEFAULT_SWAP_ENABLED } from '../../env'; import { HttpClient } from '../../api/http'; import { WrappedBrowserProvider } from '../../types'; +import { AvailabilityService } from '../../availability'; jest.mock('./geoBlocking'); describe('getAvailableRoutingOptions', () => { let mockProvider: WrappedBrowserProvider; + let availabilityService: AvailabilityService; let config: CheckoutConfiguration; let mockedHttpClient: jest.Mocked; @@ -20,6 +22,10 @@ describe('getAvailableRoutingOptions', () => { }), } as unknown as WrappedBrowserProvider; + availabilityService = { + checkDexAvailability: jest.fn().mockResolvedValue(true), + } as unknown as AvailabilityService; + mockedHttpClient = new HttpClient() as jest.Mocked; config = new CheckoutConfiguration({ baseConfig: { environment: Environment.SANDBOX }, @@ -34,7 +40,7 @@ describe('getAvailableRoutingOptions', () => { (geoBlocking.isOnRampAvailable as jest.Mock).mockResolvedValue(true); (geoBlocking.isSwapAvailable as jest.Mock).mockResolvedValue(true); - const routingOptions = await getAvailableRoutingOptions(config, mockProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockProvider, availabilityService); expect(routingOptions).toEqual({ onRamp: DEFAULT_ON_RAMP_ENABLED, swap: DEFAULT_SWAP_ENABLED, @@ -50,7 +56,7 @@ describe('getAvailableRoutingOptions', () => { swap: { enable: false }, }, mockedHttpClient); - const routingOptions = await getAvailableRoutingOptions(configWithOptions, mockProvider); + const routingOptions = await getAvailableRoutingOptions(configWithOptions, mockProvider, availabilityService); expect(routingOptions).toEqual({ onRamp: false, swap: false, @@ -61,28 +67,28 @@ describe('getAvailableRoutingOptions', () => { it('should disable onRamp options if OnRamp is geo-blocked', async () => { (geoBlocking.isOnRampAvailable as jest.Mock).mockResolvedValue(false); - const routingOptions = await getAvailableRoutingOptions(config, mockProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockProvider, availabilityService); expect(routingOptions.onRamp).toEqual(false); }); it('should disable OnRamp options if OnRamp geo-blocked checks are rejected', async () => { (geoBlocking.isOnRampAvailable as jest.Mock).mockRejectedValue({ error: '404' }); - const routingOptions = await getAvailableRoutingOptions(config, mockProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockProvider, availabilityService); expect(routingOptions.onRamp).toEqual(false); }); it('should disable Swap options if Swap is geo-blocked', async () => { (geoBlocking.isSwapAvailable as jest.Mock).mockResolvedValue(false); - const routingOptions = await getAvailableRoutingOptions(config, mockProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockProvider, availabilityService); expect(routingOptions.swap).toEqual(false); }); it('should disable Swap options if Swap geo-blocked checks are rejected', async () => { (geoBlocking.isSwapAvailable as jest.Mock).mockRejectedValue({ error: '404' }); - const routingOptions = await getAvailableRoutingOptions(config, mockProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockProvider, availabilityService); expect(routingOptions.swap).toEqual(false); }); @@ -90,7 +96,7 @@ describe('getAvailableRoutingOptions', () => { (geoBlocking.isOnRampAvailable as jest.Mock).mockResolvedValue(false); (geoBlocking.isSwapAvailable as jest.Mock).mockResolvedValue(false); - const routingOptions = await getAvailableRoutingOptions(config, mockProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockProvider, availabilityService); expect(routingOptions.onRamp).toEqual(false); expect(routingOptions.swap).toEqual(false); }); @@ -99,7 +105,7 @@ describe('getAvailableRoutingOptions', () => { (geoBlocking.isOnRampAvailable as jest.Mock).mockRejectedValue({ error: '404' }); (geoBlocking.isSwapAvailable as jest.Mock).mockRejectedValue({ error: '404' }); - const routingOptions = await getAvailableRoutingOptions(config, mockProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockProvider, availabilityService); expect(routingOptions.onRamp).toEqual(false); expect(routingOptions.swap).toEqual(false); }); @@ -111,7 +117,7 @@ describe('getAvailableRoutingOptions', () => { }, } as unknown as WrappedBrowserProvider; - const routingOptions = await getAvailableRoutingOptions(config, mockPassportProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockPassportProvider, availabilityService); expect(routingOptions.bridge).toEqual(false); }); @@ -120,7 +126,7 @@ describe('getAvailableRoutingOptions', () => { provider: {}, } as unknown as WrappedBrowserProvider; - const routingOptions = await getAvailableRoutingOptions(config, mockPassportProvider); + const routingOptions = await getAvailableRoutingOptions(config, mockPassportProvider, availabilityService); expect(routingOptions.bridge).toEqual(true); }); }); diff --git a/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.ts b/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.ts index d985db35e9..08ea055ff1 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/routingOptions.ts @@ -1,6 +1,7 @@ import { CheckoutConfiguration } from '../../config'; import { isOnRampAvailable, isSwapAvailable } from './geoBlocking'; import { AvailableRoutingOptions, WrappedBrowserProvider } from '../../types'; +import { AvailabilityService } from '../../availability'; export function isPassportProvider(provider?: WrappedBrowserProvider | null) { return provider?.ethereumProvider?.isPassport === true; @@ -17,6 +18,7 @@ type GeoBlockingCheck = { export const getAvailableRoutingOptions = async ( config: CheckoutConfiguration, provider: WrappedBrowserProvider, + availability: AvailabilityService, ) : Promise => { const availableRoutingOptions = { onRamp: config.isOnRampEnabled, @@ -30,7 +32,7 @@ export const getAvailableRoutingOptions = async ( geoBlockingChecks.push({ id: 'onRamp', promise: isOnRampAvailable() }); } if (availableRoutingOptions.swap) { - geoBlockingChecks.push({ id: 'swap', promise: isSwapAvailable(config) }); + geoBlockingChecks.push({ id: 'swap', promise: isSwapAvailable(availability) }); } if (geoBlockingChecks.length > 0) { diff --git a/packages/checkout/sdk/src/smartCheckout/routing/swap/swapRoute.ts b/packages/checkout/sdk/src/smartCheckout/routing/swap/swapRoute.ts index 6a7951845e..6ff6e187b7 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/swap/swapRoute.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/swap/swapRoute.ts @@ -1,6 +1,6 @@ import { Amount, Fee } from '@imtbl/dex-sdk'; import { formatUnits } from 'ethers'; -import { CheckoutConfiguration, getL2ChainId } from '../../../config'; +import { CheckoutConfiguration } from '../../../config'; import { AvailableRoutingOptions, ChainId, @@ -327,7 +327,7 @@ export const swapRoute = async ( const requiredToken = getRequiredToken(balanceRequirement); - const chainId = getL2ChainId(config); + const chainId = config.l2ChainId; const l2TokenBalanceResult = tokenBalanceResults.get(chainId); if (!l2TokenBalanceResult) return fundingSteps; const l2Balances = l2TokenBalanceResult.balances; @@ -335,7 +335,7 @@ export const swapRoute = async ( const quotes = await quoteFetcher( config, - getL2ChainId(config), + config.l2ChainId, walletAddress, requiredToken, swappableTokens, diff --git a/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.test.ts b/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.test.ts index c861874600..d5f8865138 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.test.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.test.ts @@ -1,7 +1,7 @@ import { Environment } from '@imtbl/config'; import { JsonRpcProvider } from 'ethers'; import { getAllTokenBalances } from './tokenBalances'; -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../config'; +import { CheckoutConfiguration } from '../../config'; import { ChainId } from '../../types'; import { getAllBalances } from '../../balances'; import { CheckoutErrorType } from '../../errors'; @@ -9,7 +9,6 @@ import { TokenBalanceResult } from './types'; import { HttpClient } from '../../api/http'; jest.mock('../../balances'); -jest.mock('../../config'); describe('tokenBalances', () => { let mockConfig: CheckoutConfiguration; @@ -18,8 +17,6 @@ describe('tokenBalances', () => { beforeEach(() => { jest.resetAllMocks(); - (getL1ChainId as jest.Mock).mockReturnValue(ChainId.SEPOLIA); - (getL2ChainId as jest.Mock).mockReturnValue(ChainId.IMTBL_ZKEVM_TESTNET); const mockedHttpClient = new HttpClient() as jest.Mocked; mockConfig = new CheckoutConfiguration({ baseConfig: { environment: Environment.SANDBOX }, diff --git a/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.ts b/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.ts index f88e53dfdf..fe1126a927 100644 --- a/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.ts +++ b/packages/checkout/sdk/src/smartCheckout/routing/tokenBalances.ts @@ -1,5 +1,5 @@ import { JsonRpcProvider } from 'ethers'; -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../config'; +import { CheckoutConfiguration } from '../../config'; import { ChainId, GetAllBalancesResult, AvailableRoutingOptions, } from '../../types'; @@ -22,14 +22,14 @@ export const getAllTokenBalances = async ( error: new CheckoutError('No L1 or L2 provider available', CheckoutErrorType.PROVIDER_ERROR), balances: [], }; - chainBalances.set(getL1ChainId(config), noProviderResult); - chainBalances.set(getL2ChainId(config), noProviderResult); + chainBalances.set(config.l1ChainId, noProviderResult); + chainBalances.set(config.l2ChainId, noProviderResult); return chainBalances; } // Only get L1 Balances if we can bridge if (availableRoutingOptions.bridge) { - const chainId = getL1ChainId(config); + const chainId = config.l1ChainId; if (readOnlyProviders.has(chainId)) { chainBalancePromises.set(chainId, getAllBalances( config, @@ -38,7 +38,7 @@ export const getAllTokenBalances = async ( chainId, )); } else { - chainBalances.set(getL1ChainId(config), { + chainBalances.set(config.l1ChainId, { success: false, error: new CheckoutError(`No L1 provider available for ${chainId}`, CheckoutErrorType.PROVIDER_ERROR), balances: [], @@ -46,7 +46,7 @@ export const getAllTokenBalances = async ( } } - const chainId = getL2ChainId(config); + const chainId = config.l2ChainId; if (readOnlyProviders.has(chainId)) { chainBalancePromises.set(chainId, getAllBalances( config, @@ -55,7 +55,7 @@ export const getAllTokenBalances = async ( chainId, )); } else { - chainBalances.set(getL2ChainId(config), { + chainBalances.set(config.l2ChainId, { success: false, error: new CheckoutError(`No L2 provider available for ${chainId}`, CheckoutErrorType.PROVIDER_ERROR), balances: [], diff --git a/packages/checkout/sdk/src/smartCheckout/sell/sell.test.ts b/packages/checkout/sdk/src/smartCheckout/sell/sell.test.ts index d2a4668e6c..cda0137fa1 100644 --- a/packages/checkout/sdk/src/smartCheckout/sell/sell.test.ts +++ b/packages/checkout/sdk/src/smartCheckout/sell/sell.test.ts @@ -26,6 +26,7 @@ import { } from '../actions'; import { SignTransactionStatusType } from '../actions/types'; import { HttpClient } from '../../api/http'; +import { AvailabilityService } from '../../availability'; jest.mock('../../instance'); jest.mock('../smartCheckout'); @@ -36,6 +37,7 @@ describe('sell', () => { const walletAddress = '0xADDRESS'; let config: CheckoutConfiguration; let mockProvider: WrappedBrowserProvider; + let availabilityService: AvailabilityService; beforeEach(() => { mockProvider = { @@ -44,6 +46,10 @@ describe('sell', () => { }), } as unknown as WrappedBrowserProvider; + availabilityService = { + checkDexAvailability: jest.fn().mockResolvedValue(true), + } as unknown as AvailabilityService; + const mockedHttpClient = new HttpClient() as jest.Mocked; config = new CheckoutConfiguration({ baseConfig: { environment: Environment.SANDBOX }, @@ -165,6 +171,7 @@ describe('sell', () => { const result = await sell( config, mockProvider, + availabilityService, [order], ); @@ -344,6 +351,7 @@ describe('sell', () => { const result = await sell( config, mockProvider, + availabilityService, [order], ); @@ -526,6 +534,7 @@ describe('sell', () => { const result = await sell( config, mockProvider, + availabilityService, [order], ); @@ -693,6 +702,7 @@ describe('sell', () => { const result = await sell( config, mockProvider, + availabilityService, orders, ); @@ -820,6 +830,7 @@ describe('sell', () => { const result = await sell( config, mockProvider, + availabilityService, orders, ); @@ -888,6 +899,7 @@ describe('sell', () => { await sell( config, mockProvider, + availabilityService, orders, ); } catch (err: any) { @@ -958,6 +970,7 @@ describe('sell', () => { await sell( config, rejectedProvider, + availabilityService, orders, ); } catch (err: any) { @@ -1066,6 +1079,7 @@ describe('sell', () => { sell( config, mockProvider, + availabilityService, orders, ), ).rejects.toThrowError('error from sign message'); @@ -1159,6 +1173,7 @@ describe('sell', () => { sell( config, mockProvider, + availabilityService, orders, ), ).rejects.toThrowError('error from get unsigned transactions'); @@ -1250,6 +1265,7 @@ describe('sell', () => { sell( config, mockProvider, + availabilityService, orders, ), ).rejects.toThrowError('error from sign approval transactions'); @@ -1335,6 +1351,7 @@ describe('sell', () => { await sell( config, mockProvider, + availabilityService, orders, ); } catch (err: any) { @@ -1454,6 +1471,7 @@ describe('sell', () => { await sell( config, mockProvider, + availabilityService, orders, ); } catch (err: any) { diff --git a/packages/checkout/sdk/src/smartCheckout/sell/sell.ts b/packages/checkout/sdk/src/smartCheckout/sell/sell.ts index e8dbef2cb8..d4b7fd7ac4 100644 --- a/packages/checkout/sdk/src/smartCheckout/sell/sell.ts +++ b/packages/checkout/sdk/src/smartCheckout/sell/sell.ts @@ -39,6 +39,7 @@ import { calculateFees } from '../fees/fees'; import { ERC20ABI } from '../../env'; import { measureAsyncExecution } from '../../logger/debugLogger'; import { isPassportProvider } from '../routing'; +import { AvailabilityService } from '../../availability'; export const getERC721Requirement = ( id: string, @@ -87,6 +88,7 @@ export const getBuyToken = ( export const sell = async ( config: CheckoutConfiguration, provider: WrappedBrowserProvider, + availability: AvailabilityService, orders: Array, ): Promise => { let orderbook: Orderbook; @@ -195,6 +197,7 @@ export const sell = async ( smartCheckout( config, provider, + availability, itemRequirements, { type: TransactionOrGasType.GAS, diff --git a/packages/checkout/sdk/src/smartCheckout/smartCheckout.test.ts b/packages/checkout/sdk/src/smartCheckout/smartCheckout.test.ts index 6245b58b65..18a877f565 100644 --- a/packages/checkout/sdk/src/smartCheckout/smartCheckout.test.ts +++ b/packages/checkout/sdk/src/smartCheckout/smartCheckout.test.ts @@ -15,6 +15,7 @@ import { balanceCheck } from './balanceCheck'; import { routingCalculator } from './routing/routingCalculator'; import { getAvailableRoutingOptions } from './routing'; import { BalanceCheckResult } from './balanceCheck/types'; +import { AvailabilityService } from '../availability'; jest.mock('./routing'); jest.mock('./allowance'); @@ -24,6 +25,7 @@ jest.mock('./routing/routingCalculator'); describe('smartCheckout', () => { let mockProvider: WrappedBrowserProvider; + let availabilityService: AvailabilityService; beforeEach(() => { jest.resetAllMocks(); @@ -34,6 +36,10 @@ describe('smartCheckout', () => { }), } as unknown as WrappedBrowserProvider; + availabilityService = { + checkDexAvailability: jest.fn().mockResolvedValue(true), + } as unknown as AvailabilityService; + (routingCalculator as jest.Mock).mockResolvedValue({ type: RoutingOutcomeType.NO_ROUTES_FOUND, message: 'No routes found', @@ -171,6 +177,7 @@ describe('smartCheckout', () => { const result = await smartCheckout( {} as CheckoutConfiguration, mockProvider, + availabilityService, itemRequirements, transactionOrGasAmount, ); @@ -376,6 +383,7 @@ describe('smartCheckout', () => { const result = await smartCheckout( {} as CheckoutConfiguration, mockProvider, + availabilityService, itemRequirements, transactionOrGasAmount, ); @@ -664,6 +672,7 @@ describe('smartCheckout', () => { smartCheckout( {} as CheckoutConfiguration, mockProvider, + availabilityService, itemRequirements, transactionOrGasAmount, undefined, @@ -793,6 +802,7 @@ describe('smartCheckout', () => { const result = await smartCheckout( {} as CheckoutConfiguration, mockProvider, + availabilityService, itemRequirements, transactionOrGasAmount, ); @@ -1019,6 +1029,7 @@ describe('smartCheckout', () => { const result = await smartCheckout( {} as CheckoutConfiguration, passportMockProvider, + availabilityService, itemRequirements, transactionOrGasAmount, ); @@ -1180,6 +1191,7 @@ describe('smartCheckout', () => { const result = await smartCheckout( {} as CheckoutConfiguration, mockProvider, + availabilityService, itemRequirements, undefined, ); @@ -1301,6 +1313,7 @@ describe('smartCheckout', () => { const result = await smartCheckout( {} as CheckoutConfiguration, mockProvider, + availabilityService, itemRequirements, undefined, { @@ -1496,6 +1509,7 @@ describe('smartCheckout', () => { smartCheckout( {} as CheckoutConfiguration, mockProvider, + availabilityService, itemRequirements, undefined, undefined, diff --git a/packages/checkout/sdk/src/smartCheckout/smartCheckout.ts b/packages/checkout/sdk/src/smartCheckout/smartCheckout.ts index 8a0e189485..fb6e8a98bf 100644 --- a/packages/checkout/sdk/src/smartCheckout/smartCheckout.ts +++ b/packages/checkout/sdk/src/smartCheckout/smartCheckout.ts @@ -20,6 +20,7 @@ import { Allowance } from './allowance/types'; import { BalanceCheckResult, BalanceRequirement } from './balanceCheck/types'; import { measureAsyncExecution } from '../logger/debugLogger'; import { WrappedBrowserProvider } from '../types'; +import { AvailabilityService } from '../availability'; export const overrideBalanceCheckResult = ( balanceCheckResult: BalanceCheckResult, @@ -88,6 +89,7 @@ const processRoutes = async ( export const smartCheckout = async ( config: CheckoutConfiguration, provider: WrappedBrowserProvider, + availability: AvailabilityService, itemRequirements: ItemRequirement[], transactionOrGasAmount?: FulfillmentTransaction | GasAmount, routingOptions?: AvailableRoutingOptions, @@ -155,7 +157,7 @@ export const smartCheckout = async ( const availableRoutingOptions = await measureAsyncExecution( config, 'Time to fetch available routing options', - getAvailableRoutingOptions(config, provider), + getAvailableRoutingOptions(config, provider, availability), ); if (routingOptions?.onRamp === false) availableRoutingOptions.onRamp = false; if (routingOptions?.swap === false) availableRoutingOptions.swap = false; diff --git a/packages/checkout/sdk/src/swap/swap.test.ts b/packages/checkout/sdk/src/swap/swap.test.ts index fb4e6414ce..e2ae138d2a 100644 --- a/packages/checkout/sdk/src/swap/swap.test.ts +++ b/packages/checkout/sdk/src/swap/swap.test.ts @@ -10,7 +10,7 @@ jest.mock('../instance', () => ({ describe('swapQuote', () => { const mockChainId = 13473; - const mockConfig = {} as unknown as CheckoutConfiguration; + const mockConfig = { l2ChainId: mockChainId } as unknown as CheckoutConfiguration; const mockProvider = { getSigner: jest.fn().mockReturnValue({ getAddress: jest.fn().mockResolvedValue('0xmockaddress'), @@ -112,7 +112,7 @@ describe('swapQuote', () => { describe('swap', () => { const mockChainId = 13473; - const mockConfig = {} as unknown as CheckoutConfiguration; + const mockConfig = { l2ChainId: mockChainId } as unknown as CheckoutConfiguration; const mockSigner = { getAddress: jest.fn().mockResolvedValue('0xmockaddress'), sendTransaction: jest.fn().mockResolvedValue({ hash: '0xtxhash' }), diff --git a/packages/checkout/sdk/src/swap/swap.ts b/packages/checkout/sdk/src/swap/swap.ts index 404a693ecf..4bbfdd517d 100644 --- a/packages/checkout/sdk/src/swap/swap.ts +++ b/packages/checkout/sdk/src/swap/swap.ts @@ -2,7 +2,7 @@ import { BrowserProvider, parseUnits } from 'ethers'; import { CheckoutError, CheckoutErrorType } from '../errors'; import { WrappedBrowserProvider, TokenInfo } from '../types'; import { createExchangeInstance } from '../instance'; -import { CheckoutConfiguration, getL2ChainId } from '../config'; +import { CheckoutConfiguration } from '../config'; import { SwapQuoteResult, SwapResult } from '../types/swap'; import { sendTransaction } from '../transaction/transaction'; @@ -41,7 +41,7 @@ const swapQuote = async ( CheckoutErrorType.MISSING_PARAMS, ); } - const chainId = getL2ChainId(config); + const chainId = config.l2ChainId; const exchange = await createExchangeInstance(chainId, config); const address = await (await provider.getSigner()).getAddress(); diff --git a/packages/checkout/sdk/src/tokens/tokens.ts b/packages/checkout/sdk/src/tokens/tokens.ts index 9f5ef1d260..e06d0732b6 100644 --- a/packages/checkout/sdk/src/tokens/tokens.ts +++ b/packages/checkout/sdk/src/tokens/tokens.ts @@ -8,7 +8,7 @@ import { TokenFilterTypes, TokenInfo, } from '../types'; -import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../config'; +import { CheckoutConfiguration } from '../config'; import { ERC20ABI, NATIVE } from '../env'; import { CheckoutErrorType, withCheckoutError } from '../errors'; import { isMatchingAddress } from '../utils/utils'; @@ -33,8 +33,8 @@ export const getTokenAllowList = async ( let onRampConfig: OnRampConfig; let blockedTokens: string[]; - const targetChainId = chainId ?? getL1ChainId(config); - const dexChainId = getL2ChainId(config); + const targetChainId = chainId ?? config.l1ChainId; + const dexChainId = config.l2ChainId; switch (type) { case TokenFilterTypes.SWAP: diff --git a/packages/checkout/sdk/src/types/config.ts b/packages/checkout/sdk/src/types/config.ts index a94d33673f..5d7094a3bd 100644 --- a/packages/checkout/sdk/src/types/config.ts +++ b/packages/checkout/sdk/src/types/config.ts @@ -1,14 +1,20 @@ import { Environment, ModuleConfiguration } from '@imtbl/config'; import { ExchangeOverrides, SecondaryFee } from '@imtbl/dex-sdk'; import { Passport } from '@imtbl/passport'; +import { BridgeInstance } from '@imtbl/bridge-sdk'; import { TokenBridgeInfo, TokenInfo } from './tokenInfo'; -import { ChainId } from './chains'; +import { ChainId, ChainSlug } from './chains'; +import { NetworkMap } from './network'; export interface CheckoutOverrides { - environment?: Environment; - [key: string]: unknown; + remoteEndpoint?: string; + baseUrl?: string; + chainSlug?: ChainSlug; + bridgeInstance?: BridgeInstance; + l1ChainId?: ChainId; + l2ChainId?: ChainId; + networkMap?: NetworkMap; } - interface CheckoutFeatureConfiguration { enable: boolean; } diff --git a/packages/checkout/widgets-lib/src/components/NetworkSwitchDrawer/NetworkSwitchDrawer.tsx b/packages/checkout/widgets-lib/src/components/NetworkSwitchDrawer/NetworkSwitchDrawer.tsx index 696eb7dd0d..e4ef9b4709 100644 --- a/packages/checkout/widgets-lib/src/components/NetworkSwitchDrawer/NetworkSwitchDrawer.tsx +++ b/packages/checkout/widgets-lib/src/components/NetworkSwitchDrawer/NetworkSwitchDrawer.tsx @@ -14,7 +14,6 @@ import { useTranslation } from 'react-i18next'; import { ChainId, Checkout, WrappedBrowserProvider } from '@imtbl/checkout-sdk'; import { Environment } from '@imtbl/config'; import { FooterLogo } from '../Footer/FooterLogo'; -import { getL1ChainId } from '../../lib'; import { getChainNameById } from '../../lib/chains'; import { isMetaMaskProvider, @@ -51,7 +50,7 @@ export function NetworkSwitchDrawer({ ); const targetChainName = getChainNameById(targetChainId); - const showEthImage = targetChainId === getL1ChainId(checkout.config); + const showEthImage = targetChainId === checkout.config.l1ChainId; const handleSwitchNetwork = useCallback(async () => { if (!checkout) return; diff --git a/packages/checkout/widgets-lib/src/components/Transactions/Transactions.tsx b/packages/checkout/widgets-lib/src/components/Transactions/Transactions.tsx index 16422a0abc..3d33ba4557 100644 --- a/packages/checkout/widgets-lib/src/components/Transactions/Transactions.tsx +++ b/packages/checkout/widgets-lib/src/components/Transactions/Transactions.tsx @@ -22,8 +22,6 @@ import { } from '../../lib/provider'; import { DEFAULT_TRANSACTIONS_RETRY_POLICY, - getL1ChainId, - getL2ChainId, } from '../../lib'; import { CheckoutApi, Transaction, TransactionType } from '../../lib/clients'; import { retry } from '../../lib/retry'; @@ -94,7 +92,7 @@ export function Transactions({ const rootChainTokensHashmap = useCallback(async () => { if (!checkout) return {}; - const rootChainId = getL1ChainId(checkout.config); + const rootChainId = checkout.config.l1ChainId; try { const tokens = ( await checkout.getTokenAllowList({ @@ -123,7 +121,7 @@ export function Transactions({ if (!from?.walletAddress) return {}; - const childChainId = getL2ChainId(checkout.config); + const childChainId = checkout.config.l2ChainId; try { const data = await checkout.getAllBalances({ @@ -146,8 +144,8 @@ export function Transactions({ const getTokensDetails = async (tokensWithChainSlug: { [p: string]: string; }) => { - const rootChainName = getChainSlugById(getL1ChainId(checkout.config)); - const childChainName = getChainSlugById(getL2ChainId(checkout.config)); + const rootChainName = getChainSlugById(checkout.config.l1ChainId); + const childChainName = getChainSlugById(checkout.config.l2ChainId); const [rootData, childData] = await Promise.all([ rootChainTokensHashmap(), @@ -164,12 +162,12 @@ export function Transactions({ }); // Root provider is always L1 const rootProvider = new JsonRpcProvider( - checkout.config.networkMap.get(getL1ChainId(checkout.config))?.rpcUrls[0], + checkout.config.networkMap.get(checkout.config.l1ChainId)?.rpcUrls[0], ); // Child provider is always L2 const childProvider = new JsonRpcProvider( - checkout.config.networkMap.get(getL2ChainId(checkout.config))?.rpcUrls[0], + checkout.config.networkMap.get(checkout.config.l2ChainId)?.rpcUrls[0], ); const rootTokenInfoPromises: Promise[] = []; diff --git a/packages/checkout/widgets-lib/src/lib/index.ts b/packages/checkout/widgets-lib/src/lib/index.ts index 943e7648b0..ce9ae4d18d 100644 --- a/packages/checkout/widgets-lib/src/lib/index.ts +++ b/packages/checkout/widgets-lib/src/lib/index.ts @@ -1,6 +1,5 @@ export * from './storage'; export * from './constants'; -export * from './networkUtils'; export * from './networkStyles'; export * from './eip1193Events'; export * from './providerEvents'; diff --git a/packages/checkout/widgets-lib/src/lib/networkUtils.ts b/packages/checkout/widgets-lib/src/lib/networkUtils.ts deleted file mode 100644 index 7e1c4c26ff..0000000000 --- a/packages/checkout/widgets-lib/src/lib/networkUtils.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ChainId, CheckoutConfiguration } from '@imtbl/checkout-sdk'; - -// **************************************************** // -// **************************************************** // -// This is duplicated in the sdk project. // -// We are not exposing these functions given that this // -// to keep the Checkout SDK interface as minimal as // -// possible. // -// **************************************************** // -export const getL1ChainId = (config: CheckoutConfiguration): ChainId => { - // DevMode and Sandbox will both use Sepolia. - if (!config.isProduction) return ChainId.SEPOLIA; - return ChainId.ETHEREUM; -}; - -export const getL2ChainId = (config: CheckoutConfiguration): ChainId => { - if (config.isDevelopment) return ChainId.IMTBL_ZKEVM_DEVNET; - if (config.isProduction) return ChainId.IMTBL_ZKEVM_MAINNET; - return ChainId.IMTBL_ZKEVM_TESTNET; -}; -// **************************************************** // -// **************************************************** // diff --git a/packages/checkout/widgets-lib/src/lib/utils.ts b/packages/checkout/widgets-lib/src/lib/utils.ts index 7e1cf386e9..c4d865d099 100644 --- a/packages/checkout/widgets-lib/src/lib/utils.ts +++ b/packages/checkout/widgets-lib/src/lib/utils.ts @@ -5,7 +5,6 @@ import { import { Environment } from '@imtbl/config'; import { Contract, formatUnits } from 'ethers'; import { TransactionResponse } from '@imtbl/dex-sdk'; -import { getL1ChainId, getL2ChainId } from './networkUtils'; import { CHECKOUT_CDN_BASE_URL, DEFAULT_GT_ONE_TOKEN_FORMATTING_DECIMALS, @@ -25,7 +24,7 @@ export const sortTokensByAmount = ( ) => tokens.sort((a, b) => { // make sure IMX is at the top of the list if ( - chainId === getL2ChainId(config) + chainId === config.l2ChainId && a.token.symbol.toLowerCase() === 'imx' && b.token.symbol.toLowerCase() !== 'imx' ) { @@ -33,7 +32,7 @@ export const sortTokensByAmount = ( } if ( - chainId === getL2ChainId(config) + chainId === config.l2ChainId && b.token.symbol.toLowerCase() === 'imx' && a.token.symbol.toLowerCase() !== 'imx' ) { @@ -57,10 +56,10 @@ export const sortNetworksCompareFn = ( config: CheckoutConfiguration, ) => { // make sure zkEVM at start of the list then L1 - if (Number(a.chainId) === getL2ChainId(config)) { + if (a.chainId === config.l2ChainId) { return -1; } - if (Number(a.chainId) === getL1ChainId(config)) { + if (a.chainId === config.l1ChainId) { return 0; } return 1; diff --git a/packages/checkout/widgets-lib/src/widgets/add-tokens/components/TokenDrawerMenu.tsx b/packages/checkout/widgets-lib/src/widgets/add-tokens/components/TokenDrawerMenu.tsx index d95b076ef1..11f2f708bd 100644 --- a/packages/checkout/widgets-lib/src/widgets/add-tokens/components/TokenDrawerMenu.tsx +++ b/packages/checkout/widgets-lib/src/widgets/add-tokens/components/TokenDrawerMenu.tsx @@ -36,7 +36,6 @@ import { useAnalytics, UserJourney, } from '../../../context/analytics-provider/SegmentAnalyticsProvider'; -import { getL2ChainId } from '../../../lib'; import { AddTokensErrorTypes } from '../types'; import { TokenImage } from '../../../components/TokenImage/TokenImage'; import { PULSE_SHADOW } from '../utils/animation'; @@ -133,7 +132,7 @@ export function TokenDrawerMenu({ try { const tokenResponse = await checkout.getTokenAllowList({ type: TokenFilterTypes.SWAP, - chainId: getL2ChainId(checkout.config), + chainId: checkout.config.l2ChainId, }); if (tokenResponse?.tokens.length > 0) { diff --git a/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx b/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx index 3a712e3629..d075b0bd24 100644 --- a/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx +++ b/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx @@ -37,7 +37,6 @@ import { ViewActions, ViewContext, } from '../../../context/view-context/ViewContext'; -import { getL2ChainId } from '../../../lib'; import { orchestrationEvents } from '../../../lib/orchestrationEvents'; import { AddTokensActions, @@ -410,7 +409,7 @@ export function AddTokens({ try { const tokenResponse = await checkout.getTokenAllowList({ type: TokenFilterTypes.ONRAMP, - chainId: getL2ChainId(checkout.config), + chainId: checkout.config.l2ChainId, }); if (tokenResponse?.tokens.length > 0) { diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx index e64bc37e64..a2c765930c 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx @@ -13,9 +13,6 @@ import { } from 'react'; import { BridgeConfiguration, - ETH_MAINNET_TO_ZKEVM_MAINNET, - ETH_SEPOLIA_TO_ZKEVM_DEVNET, - ETH_SEPOLIA_TO_ZKEVM_TESTNET, TokenBridge, } from '@imtbl/bridge-sdk'; import { useTranslation } from 'react-i18next'; @@ -25,7 +22,6 @@ import { StrongCheckoutWidgetsConfig } from '../../lib/withDefaultWidgetConfig'; import { CryptoFiatProvider } from '../../context/crypto-fiat-context/CryptoFiatProvider'; import { StatusView } from '../../components/Status/StatusView'; import { StatusType } from '../../components/Status/StatusType'; -import { getL1ChainId, getL2ChainId } from '../../lib'; import { Transactions } from '../../components/Transactions/Transactions'; import { UserJourney, useAnalytics } from '../../context/analytics-provider/SegmentAnalyticsProvider'; import { TopUpView } from '../../views/top-up/TopUpView'; @@ -108,22 +104,18 @@ export default function BridgeWidget({ checkout, browserProvider: browserProvider ?? null, tokenBridge: (() => { - let bridgeInstance = ETH_SEPOLIA_TO_ZKEVM_TESTNET; - if (checkout.config.isDevelopment) bridgeInstance = ETH_SEPOLIA_TO_ZKEVM_DEVNET; - if (checkout.config.isProduction) bridgeInstance = ETH_MAINNET_TO_ZKEVM_MAINNET; - // Root provider is always L1 const rootProvider = new JsonRpcProvider( - checkout.config.networkMap.get(getL1ChainId(checkout.config))?.rpcUrls[0], + checkout.config.networkMap.get(checkout.config.l1ChainId)?.rpcUrls[0], ); // Child provider is always L2 const childProvider = new JsonRpcProvider( - checkout.config.networkMap.get(getL2ChainId(checkout.config))?.rpcUrls[0], + checkout.config.networkMap.get(checkout.config.l2ChainId)?.rpcUrls[0], ); const bridgeConfiguration = new BridgeConfiguration({ baseConfig: new ImmutableConfiguration({ environment: checkout.config.environment }), - bridgeInstance, + bridgeInstance: checkout.config.bridgeInstance, rootProvider, childProvider, }); diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx index 9e43c867b0..1a0c0e1998 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx @@ -29,8 +29,6 @@ import { IMX_TOKEN_SYMBOL, NATIVE, addChainChangedListener, - getL1ChainId, - getL2ChainId, networkName, removeChainChangedListener, } from '../../../lib'; @@ -119,7 +117,7 @@ export function BridgeReviewSummary() { const isTransfer = useMemo(() => from?.network === to?.network, [from, to]); const isDeposit = useMemo( - () => (getL2ChainId(checkout.config) === to?.network), + () => (checkout.config.l2ChainId === to?.network), [from, to, checkout], ); const insufficientFundsForGas = useMemo(() => { @@ -637,7 +635,7 @@ export function BridgeReviewSummary() { onCloseDrawer={() => setShowNotEnoughGasDrawer(false)} walletAddress={from?.walletAddress || ''} tokenSymbol={ - from?.network === getL1ChainId(checkout?.config) + from?.network === checkout.config.l1ChainId ? ETH_TOKEN_SYMBOL : IMX_TOKEN_SYMBOL } diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx index 05dd75540d..17b0404305 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx @@ -22,7 +22,6 @@ import { isPassportProvider, isWalletConnectProvider, } from '../../../lib/provider'; -import { getL1ChainId, getL2ChainId } from '../../../lib'; import { getChainNameById } from '../../../lib/chains'; import { ViewActions, ViewContext } from '../../../context/view-context/ViewContext'; import { abbreviateAddress } from '../../../lib/addressUtils'; @@ -85,9 +84,9 @@ export function WalletAndNetworkSelector() { } as unknown as WalletChangeEvent : null; // calculating l1/l2 chains to work with based on Checkout environment - const l1NetworkChainId = getL1ChainId(checkout.config); + const l1NetworkChainId = checkout.config.l1ChainId; const l1NetworkName = getChainNameById(l1NetworkChainId); - const imtblZkEvmNetworkChainId = getL2ChainId(checkout.config); + const imtblZkEvmNetworkChainId = checkout.config.l2ChainId; const imtblZkEvmNetworkName = getChainNameById(imtblZkEvmNetworkChainId); /** From wallet and from network local state */ diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/views/ClaimWithdrawal.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/views/ClaimWithdrawal.tsx index 03f389de78..cede1f5557 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/views/ClaimWithdrawal.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/views/ClaimWithdrawal.tsx @@ -12,7 +12,7 @@ import { FeeData } from 'ethers'; import { UserJourney, useAnalytics } from '../../../context/analytics-provider/SegmentAnalyticsProvider'; import { Transaction } from '../../../lib/clients'; import { getChainNameById } from '../../../lib/chains'; -import { WITHDRAWAL_CLAIM_GAS_LIMIT, getL1ChainId } from '../../../lib'; +import { WITHDRAWAL_CLAIM_GAS_LIMIT } from '../../../lib'; import { isPassportProvider } from '../../../lib/provider'; import { isNativeToken } from '../../../lib/utils'; import { NotEnoughEthToWithdraw } from '../../../components/Transactions/NotEnoughEthToWithdraw'; @@ -95,7 +95,6 @@ export function ClaimWithdrawal({ transaction }: ClaimWithdrawalProps) { } let providerToUse = from?.browserProvider; - const l1ChainId = getL1ChainId(checkout.config); setTxProcessing(true); @@ -155,7 +154,7 @@ export function ClaimWithdrawal({ transaction }: ClaimWithdrawalProps) { try { const balancesResult = await checkout.getAllBalances({ provider: providerToUse, - chainId: l1ChainId, + chainId: checkout.config.l1ChainId, }); const ethBalance = balancesResult.balances.find((balance) => isNativeToken(balance.token.address)); @@ -173,11 +172,11 @@ export function ClaimWithdrawal({ transaction }: ClaimWithdrawalProps) { // check that provider is connected to L1 const network = await providerToUse.getNetwork(); - if (Number(network.chainId) !== l1ChainId) { + if (Number(network.chainId) !== checkout.config.l1ChainId) { try { const switchNetworkResult = await checkout.switchNetwork({ provider: providerToUse, - chainId: l1ChainId, + chainId: checkout.config.l1ChainId, }); providerToUse = switchNetworkResult.provider; } catch (err) { @@ -263,7 +262,7 @@ export function ClaimWithdrawal({ transaction }: ClaimWithdrawalProps) { > diff --git a/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx b/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx index 9b4838268d..93954fe2e9 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx @@ -114,12 +114,7 @@ export default function ConnectWidget({ const { identify, page, user } = useAnalytics(); - let targetChain = targetChainId; - if (!targetChain) { - targetChain = checkout.config.isProduction - ? ChainId.IMTBL_ZKEVM_MAINNET - : ChainId.IMTBL_ZKEVM_TESTNET; - } + const targetChain = targetChainId ?? checkout.config.l2ChainId; useEffect(() => { if (!browserProvider) return; diff --git a/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidgetRoot.tsx b/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidgetRoot.tsx index b45e0cfcf9..b82e90e9c7 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidgetRoot.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidgetRoot.tsx @@ -30,10 +30,10 @@ export class Connect extends Base { // validating targetChainId per environment if (!params.targetChainId - && this.checkout.config.isProduction) { + && this.checkout.config.environment === Environment.PRODUCTION) { validatedParams.targetChainId = ChainId.IMTBL_ZKEVM_MAINNET; } else if (params.targetChainId - && this.checkout.config.isProduction + && this.checkout.config.environment === Environment.PRODUCTION && (params.targetChainId !== ChainId.ETHEREUM && params.targetChainId !== ChainId.IMTBL_ZKEVM_MAINNET) ) { // eslint-disable-next-line max-len, no-console diff --git a/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx b/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx index f7f70853d0..8e5c15df58 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx @@ -38,7 +38,7 @@ import { getProviderSlugFromRdns, isPassportProvider, } from '../../../lib/provider'; -import { addProviderListenersForWidgetRoot, getL1ChainId } from '../../../lib'; +import { addProviderListenersForWidgetRoot } from '../../../lib'; import { listItemVariants, listVariants, @@ -96,7 +96,7 @@ export function WalletList(props: WalletListProps) { // Don't allow Passport if targetChainId is L1 const passportProviderDetail = useMemo( - () => targetChainId !== getL1ChainId(checkout!.config) + () => targetChainId !== checkout!.config.l1ChainId && providers .filter((provider) => !blocklistWalletRdns.includes(provider.info.rdns)) .find((provider) => provider.info.rdns === WalletProviderRdns.PASSPORT), diff --git a/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkEth.tsx b/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkEth.tsx index 063fe02358..75e84e4cd3 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkEth.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkEth.tsx @@ -10,7 +10,6 @@ import { EthereumPlanetHero } from '../../../components/Hero/EthereumPlanetHero' import { SimpleLayout } from '../../../components/SimpleLayout/SimpleLayout'; import { ConnectWidgetViews } from '../../../context/view-context/ConnectViewContextTypes'; import { ConnectActions, ConnectContext } from '../context/ConnectContext'; -import { getL1ChainId } from '../../../lib/networkUtils'; import { ViewContext, ViewActions, @@ -45,7 +44,7 @@ export function SwitchNetworkEth() { try { const switchRes = await checkout.switchNetwork({ provider, - chainId: getL1ChainId(checkout.config), + chainId: checkout.config.l1ChainId, }); connectDispatch({ @@ -88,7 +87,7 @@ export function SwitchNetworkEth() { > {t('views.SWITCH_NETWORK.eth.body')} diff --git a/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx b/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx index b954d7b699..2ff49de304 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx @@ -10,7 +10,7 @@ import { SimpleLayout } from '../../../components/SimpleLayout/SimpleLayout'; import { ConnectWidgetViews } from '../../../context/view-context/ConnectViewContextTypes'; import { ConnectActions, ConnectContext } from '../context/ConnectContext'; import { ViewContext, ViewActions } from '../../../context/view-context/ViewContext'; -import { addChainChangedListener, getL2ChainId, removeChainChangedListener } from '../../../lib'; +import { addChainChangedListener, removeChainChangedListener } from '../../../lib'; import { ImmutablePlanetHero } from '../../../components/Hero/ImmutablePlanetHero'; import { UserJourney, useAnalytics } from '../../../context/analytics-provider/SegmentAnalyticsProvider'; @@ -36,7 +36,7 @@ export function SwitchNetworkZkEVM() { const currentChainId = await provider.send('eth_chainId', []); // eslint-disable-next-line radix const parsedChainId = Number(currentChainId.toString()); - if (parsedChainId === getL2ChainId(checkout.config)) { + if (parsedChainId === checkout.config.l2ChainId) { connectDispatch({ payload: { type: ConnectActions.SET_PROVIDER, @@ -79,7 +79,7 @@ export function SwitchNetworkZkEVM() { // eslint-disable-next-line radix const parsedChainId = Number(currentChainId.toString()); - if (parsedChainId === getL2ChainId(checkout.config)) { + if (parsedChainId === checkout.config.l2ChainId) { connectDispatch({ payload: { type: ConnectActions.SET_PROVIDER, @@ -108,7 +108,7 @@ export function SwitchNetworkZkEVM() { try { await checkout.addNetwork({ provider, - chainId: getL2ChainId(checkout.config), + chainId: checkout.config.l2ChainId, }); connectDispatch({ payload: { @@ -134,7 +134,7 @@ export function SwitchNetworkZkEVM() { const switchRes = await checkout.switchNetwork({ provider, - chainId: getL2ChainId(checkout.config), + chainId: checkout.config.l2ChainId, }); connectDispatch({ payload: { diff --git a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/functions/getConnectLoaderParams.ts b/packages/checkout/widgets-lib/src/widgets/immutable-commerce/functions/getConnectLoaderParams.ts index d266f99eb3..20c4d200ee 100644 --- a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/functions/getConnectLoaderParams.ts +++ b/packages/checkout/widgets-lib/src/widgets/immutable-commerce/functions/getConnectLoaderParams.ts @@ -1,17 +1,9 @@ import { - ChainId, Checkout, CommerceFlowType, WrappedBrowserProvider, + Checkout, CommerceFlowType, WrappedBrowserProvider, } from '@imtbl/checkout-sdk'; import { ConnectLoaderParams } from '../../../components/ConnectLoader/ConnectLoader'; -import { getL1ChainId, getL2ChainId } from '../../../lib/networkUtils'; import { View } from '../../../context/view-context/ViewContext'; -/** - * Get the chain id for the checkout - */ -const getChainId = (checkout: Checkout) => (checkout.config.isProduction - ? ChainId.IMTBL_ZKEVM_MAINNET - : ChainId.IMTBL_ZKEVM_TESTNET); - /** * Get the connect loader params for the widget */ @@ -27,10 +19,10 @@ export function getConnectLoaderParams( return { checkout, browserProvider, - targetChainId: getChainId(checkout), + targetChainId: checkout.config.l2ChainId, allowedChains: [ - getL1ChainId(checkout.config), - getL2ChainId(checkout.config), + checkout.config.l1ChainId, + checkout.config.l2ChainId, ], }; case CommerceFlowType.ONRAMP: @@ -38,10 +30,10 @@ export function getConnectLoaderParams( return { checkout, browserProvider, - targetChainId: getChainId(checkout), + targetChainId: checkout.config.l2ChainId, allowedChains: [ - getL1ChainId(checkout.config), - getL2ChainId(checkout.config), + checkout.config.l1ChainId, + checkout.config.l2ChainId, ], }; case CommerceFlowType.SALE: @@ -50,8 +42,8 @@ export function getConnectLoaderParams( return { checkout, browserProvider, - targetChainId: getChainId(checkout), - allowedChains: [getL2ChainId(checkout.config)], + targetChainId: checkout.config.l2ChainId, + allowedChains: [checkout.config.l2ChainId], }; default: return {} as ConnectLoaderParams; diff --git a/packages/checkout/widgets-lib/src/widgets/on-ramp/OnRampWidgetRoot.tsx b/packages/checkout/widgets-lib/src/widgets/on-ramp/OnRampWidgetRoot.tsx index 4ab62006c9..2720b173db 100644 --- a/packages/checkout/widgets-lib/src/widgets/on-ramp/OnRampWidgetRoot.tsx +++ b/packages/checkout/widgets-lib/src/widgets/on-ramp/OnRampWidgetRoot.tsx @@ -1,6 +1,5 @@ import React, { Suspense } from 'react'; import { - ChainId, IMTBLWidgetEvents, OnRampWidgetParams, WidgetConfiguration, @@ -10,7 +9,6 @@ import { } from '@imtbl/checkout-sdk'; import { Base } from '../BaseWidgetRoot'; import { ConnectLoader, ConnectLoaderParams } from '../../components/ConnectLoader/ConnectLoader'; -import { getL1ChainId, getL2ChainId } from '../../lib'; import { isValidAddress, isValidAmount } from '../../lib/validations/widgetValidators'; import { ThemeProvider } from '../../components/ThemeProvider/ThemeProvider'; import { CustomAnalyticsProvider } from '../../context/analytics-provider/CustomAnalyticsProvider'; @@ -76,13 +74,11 @@ export class OnRamp extends Base { const { t } = i18n; const connectLoaderParams: ConnectLoaderParams = { - targetChainId: this.checkout.config.isProduction - ? ChainId.IMTBL_ZKEVM_MAINNET - : ChainId.IMTBL_ZKEVM_TESTNET, + targetChainId: this.checkout.config.l2ChainId, walletProviderName: this.parameters.walletProviderName, browserProvider: this.browserProvider, checkout: this.checkout, - allowedChains: [getL1ChainId(this.checkout.config), getL2ChainId(this.checkout.config)], + allowedChains: [this.checkout.config.l1ChainId, this.checkout.config.l2ChainId], }; this.reactRoot.render( diff --git a/packages/checkout/widgets-lib/src/widgets/sale/SaleWidgetRoot.tsx b/packages/checkout/widgets-lib/src/widgets/sale/SaleWidgetRoot.tsx index 477d1c56b9..bc2b09eb87 100644 --- a/packages/checkout/widgets-lib/src/widgets/sale/SaleWidgetRoot.tsx +++ b/packages/checkout/widgets-lib/src/widgets/sale/SaleWidgetRoot.tsx @@ -1,6 +1,5 @@ import React, { Suspense } from 'react'; import { - ChainId, IMTBLWidgetEvents, SaleItem, SaleWidgetParams, @@ -15,7 +14,6 @@ import { ConnectLoader, ConnectLoaderParams, } from '../../components/ConnectLoader/ConnectLoader'; -import { getL2ChainId } from '../../lib'; import { isValidWalletProvider } from '../../lib/validations/widgetValidators'; import { ThemeProvider } from '../../components/ThemeProvider/ThemeProvider'; import { CustomAnalyticsProvider } from '../../context/analytics-provider/CustomAnalyticsProvider'; @@ -119,12 +117,10 @@ export class Sale extends Base { const { t } = i18n; const connectLoaderParams: ConnectLoaderParams = { - targetChainId: this.checkout.config.isProduction - ? ChainId.IMTBL_ZKEVM_MAINNET - : ChainId.IMTBL_ZKEVM_TESTNET, + targetChainId: this.checkout.config.l2ChainId, browserProvider: this.browserProvider, checkout: this.checkout, - allowedChains: [getL2ChainId(this.checkout!.config)], + allowedChains: [this.checkout.config.l1ChainId, this.checkout.config.l2ChainId], }; const config = this.strongConfig(); diff --git a/packages/checkout/widgets-lib/src/widgets/sale/components/FundingRouteExecute/FundingRouteExecute.tsx b/packages/checkout/widgets-lib/src/widgets/sale/components/FundingRouteExecute/FundingRouteExecute.tsx index b29a5f83e8..723d7e18d7 100644 --- a/packages/checkout/widgets-lib/src/widgets/sale/components/FundingRouteExecute/FundingRouteExecute.tsx +++ b/packages/checkout/widgets-lib/src/widgets/sale/components/FundingRouteExecute/FundingRouteExecute.tsx @@ -16,7 +16,6 @@ import { OnRampEventType, OnRampSuccess, OnRampFailed, - ChainId, } from '@imtbl/checkout-sdk'; import { useCallback, @@ -46,7 +45,6 @@ import { ViewActions, ViewContext, } from '../../../../context/view-context/ViewContext'; -import { getL1ChainId, getL2ChainId } from '../../../../lib/networkUtils'; import { LoadingView } from '../../../../views/loading/LoadingView'; import ConnectWidget from '../../../connect/ConnectWidget'; import SwapWidget from '../../../swap/SwapWidget'; @@ -142,7 +140,7 @@ export function FundingRouteExecute({ tokenAddress: step.fundingItem.token.address, amount: step.fundingItem.fundsRequired.formattedAmount, }); - if (Number(network.chainId) === getL1ChainId(checkout!.config)) { + if (network.chainId === checkout.config.l1ChainId) { setView(FundingRouteExecuteViews.EXECUTE_BRIDGE); return; } @@ -158,7 +156,7 @@ export function FundingRouteExecute({ toTokenAddress: requiredTokenAddress, autoProceed: true, }); - if (Number(network.chainId) === getL2ChainId(checkout!.config)) { + if (network.chainId === checkout.config.l2ChainId) { setView(FundingRouteExecuteViews.EXECUTE_SWAP); return; } @@ -328,9 +326,7 @@ export function FundingRouteExecute({ {view === FundingRouteExecuteViews.SWITCH_NETWORK_ETH && ( { const { t } = i18n; const connectLoaderParams: ConnectLoaderParams = { - targetChainId: this.checkout.config.isProduction - ? ChainId.IMTBL_ZKEVM_MAINNET - : ChainId.IMTBL_ZKEVM_TESTNET, + targetChainId: this.checkout.config.l2ChainId, walletProviderName: this.parameters.walletProviderName, browserProvider: this.browserProvider, checkout: this.checkout, - allowedChains: [getL2ChainId(this.checkout!.config)], + allowedChains: [this.checkout.config.l2ChainId], }; this.reactRoot!.render( diff --git a/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx b/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx index 078bc5c9c4..175c61646d 100644 --- a/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx +++ b/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx @@ -27,7 +27,6 @@ import { NATIVE, DEFAULT_TOKEN_VALIDATION_DECIMALS, ESTIMATE_DEBOUNCE, - getL2ChainId, } from '../../../lib'; import { SelectInput } from '../../../components/FormComponents/SelectInput/SelectInput'; import { @@ -852,7 +851,7 @@ export function SwapForm({ data, theme, cancelAutoProceed }: SwapFromProps) { const currentChainId = await (provider.provider as any).send('eth_chainId', []); // eslint-disable-next-line radix const parsedChainId = parseInt(currentChainId.toString()); - if (parsedChainId !== getL2ChainId(checkout.config)) { + if (parsedChainId !== checkout.config.l2ChainId) { setShowNetworkSwitchDrawer(true); return; } @@ -1134,7 +1133,7 @@ export function SwapForm({ data, theme, cancelAutoProceed }: SwapFromProps) { /> setShowNetworkSwitchDrawer(false)} diff --git a/packages/checkout/widgets-lib/src/widgets/transfer/TransferWidget.tsx b/packages/checkout/widgets-lib/src/widgets/transfer/TransferWidget.tsx index aa3e6d1f87..ee673f0f12 100644 --- a/packages/checkout/widgets-lib/src/widgets/transfer/TransferWidget.tsx +++ b/packages/checkout/widgets-lib/src/widgets/transfer/TransferWidget.tsx @@ -22,7 +22,6 @@ import { } from '../../context/crypto-fiat-context/CryptoFiatContext'; import { CryptoFiatProvider } from '../../context/crypto-fiat-context/CryptoFiatProvider'; import { sendTokens, loadBalances } from './functions'; -import { getL2ChainId } from '../../lib'; import { TransferComplete } from './TransferComplete'; import { SendingTokens } from './SendingTokens'; import { AwaitingApproval } from './AwaitingApproval'; @@ -154,7 +153,7 @@ function TransferWidgetInner(props: TransferWidgetInputs) { setViewState({ type: 'COMPLETE', receipt, - chainId: getL2ChainId(viewState.checkout.config), + chainId: viewState.checkout.config.l2ChainId, checkout: viewState.checkout, provider: viewState.provider, allowedBalances: viewState.allowedBalances, diff --git a/packages/checkout/widgets-lib/src/widgets/wallet/WalletWidgetRoot.tsx b/packages/checkout/widgets-lib/src/widgets/wallet/WalletWidgetRoot.tsx index 6a721fdf48..c59b2afd74 100644 --- a/packages/checkout/widgets-lib/src/widgets/wallet/WalletWidgetRoot.tsx +++ b/packages/checkout/widgets-lib/src/widgets/wallet/WalletWidgetRoot.tsx @@ -1,6 +1,5 @@ import React, { Suspense } from 'react'; import { - ChainId, IMTBLWidgetEvents, WalletWidgetConfiguration, WalletWidgetParams, @@ -10,7 +9,6 @@ import { } from '@imtbl/checkout-sdk'; import { Base } from '../BaseWidgetRoot'; import { ConnectLoader, ConnectLoaderParams } from '../../components/ConnectLoader/ConnectLoader'; -import { getL1ChainId, getL2ChainId } from '../../lib'; import { isValidWalletProvider } from '../../lib/validations/widgetValidators'; import { ThemeProvider } from '../../components/ThemeProvider/ThemeProvider'; import { CustomAnalyticsProvider } from '../../context/analytics-provider/CustomAnalyticsProvider'; @@ -68,13 +66,11 @@ export class Wallet extends Base { const { t } = i18n; const connectLoaderParams: ConnectLoaderParams = { - targetChainId: this.checkout.config.isProduction - ? ChainId.IMTBL_ZKEVM_MAINNET - : ChainId.IMTBL_ZKEVM_TESTNET, + targetChainId: this.checkout.config.l2ChainId, walletProviderName: this.parameters?.walletProviderName, browserProvider: this.browserProvider, checkout: this.checkout, - allowedChains: [getL1ChainId(this.checkout.config), getL2ChainId(this.checkout.config)], + allowedChains: [this.checkout.config.l1ChainId, this.checkout.config.l2ChainId], }; this.reactRoot.render( diff --git a/packages/checkout/widgets-lib/src/widgets/wallet/components/BalanceItem/BalanceItem.tsx b/packages/checkout/widgets-lib/src/widgets/wallet/components/BalanceItem/BalanceItem.tsx index cdd59b127f..3c44ca52d5 100644 --- a/packages/checkout/widgets-lib/src/widgets/wallet/components/BalanceItem/BalanceItem.tsx +++ b/packages/checkout/widgets-lib/src/widgets/wallet/components/BalanceItem/BalanceItem.tsx @@ -14,7 +14,6 @@ import { ShowMenuItem } from './BalanceItemStyles'; import { BalanceInfo } from '../../functions/tokenBalances'; import { WalletContext } from '../../context/WalletContext'; import { orchestrationEvents } from '../../../../lib/orchestrationEvents'; -import { getL1ChainId, getL2ChainId } from '../../../../lib/networkUtils'; import { formatZeroAmount, tokenValueFormat } from '../../../../lib/utils'; import { ConnectLoaderContext } from '../../../../context/connect-loader-context/ConnectLoaderContext'; import { isPassportProvider } from '../../../../lib/provider'; @@ -60,11 +59,11 @@ export function BalanceItem({ if (!checkout) return; const onRampTokens = checkout.getTokenAllowList({ type: TokenFilterTypes.ONRAMP, - chainId: getL2ChainId(checkout.config), + chainId: checkout.config.l2ChainId, }); const swapTokens = checkout.getTokenAllowList({ type: TokenFilterTypes.SWAP, - chainId: getL2ChainId(checkout.config), + chainId: checkout.config.l2ChainId, }); const [onRampAllowedTokensResult, swapAllowedTokensResult] = await Promise.all([onRampTokens, swapTokens]); @@ -77,25 +76,25 @@ export function BalanceItem({ useEffect(() => { if (!network || !supportedTopUps || !checkout) return; - const currentChainId = Number(network.chainId); + const currentChainId = network.chainId; const enableAddCoin = (supportedTopUps?.isAddTokensEnabled ?? true) && (supportedTopUps?.isSwapAvailable ?? true); setIsAddTokensEnabled(enableAddCoin); const enableBuyCoin = !enableAddCoin - && currentChainId === getL2ChainId(checkout.config) + && currentChainId === checkout.config.l2ChainId && (supportedTopUps?.isOnRampEnabled ?? true); setIsOnRampEnabled(enableBuyCoin); const enableMoveCoin = !enableAddCoin - && (currentChainId === getL1ChainId(checkout.config) - || currentChainId === getL2ChainId(checkout.config)) + && (currentChainId === checkout.config.l1ChainId + || currentChainId === checkout.config.l2ChainId) && (supportedTopUps?.isBridgeEnabled ?? true); setIsBridgeEnabled(enableMoveCoin); const enableSwapCoin = !enableAddCoin - && currentChainId === getL2ChainId(checkout.config) + && currentChainId === checkout.config.l2ChainId && (supportedTopUps?.isSwapEnabled ?? true) && (supportedTopUps?.isSwapAvailable ?? true); setIsSwapEnabled(enableSwapCoin); diff --git a/packages/checkout/widgets-lib/src/widgets/wallet/views/WalletBalances.tsx b/packages/checkout/widgets-lib/src/widgets/wallet/views/WalletBalances.tsx index 7db5bd8230..16d6d0c425 100644 --- a/packages/checkout/widgets-lib/src/widgets/wallet/views/WalletBalances.tsx +++ b/packages/checkout/widgets-lib/src/widgets/wallet/views/WalletBalances.tsx @@ -21,7 +21,6 @@ import { walletBalanceLoadingIconStyles, walletBalanceListContainerStyles, } from './WalletBalancesStyles'; -import { getL2ChainId } from '../../../lib/networkUtils'; import { WalletWidgetViews } from '../../../context/view-context/WalletViewContextTypes'; import { ViewActions, @@ -111,7 +110,7 @@ export function WalletBalances({ const showAddCoins = useMemo(() => { if (!checkout || !network) return false; return ( - Number(network.chainId) === getL2ChainId(checkout.config) + network.chainId === checkout.config.l2ChainId && Boolean( supportedTopUps?.isBridgeEnabled || supportedTopUps?.isSwapEnabled diff --git a/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx b/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx index b2fc99ab21..8304bd6f7c 100644 --- a/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx +++ b/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx @@ -178,7 +178,7 @@ export const MainPage = () => { Immutable Checkout Marketplace - +