Skip to content

Checkout overrides #2606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/checkout/sdk/src/availability/availability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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(
Expand Down
14 changes: 2 additions & 12 deletions packages/checkout/sdk/src/availability/availability.ts
Original file line number Diff line number Diff line change
@@ -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<boolean>
};

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<boolean> => {
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
Expand Down
34 changes: 7 additions & 27 deletions packages/checkout/sdk/src/config/config.test.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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) => {
Expand All @@ -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 },
Expand Down Expand Up @@ -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 = [
{
Expand All @@ -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);
});
});

Expand All @@ -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);
});
});
});
Expand Down
97 changes: 46 additions & 51 deletions packages/checkout/sdk/src/config/config.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
Expand All @@ -69,8 +39,6 @@ export class CheckoutConfiguration {

readonly environment: Environment;

readonly networkMap: NetworkMap;

readonly publishableKey: string;

readonly overrides: CheckoutModuleConfiguration['overrides'];
Expand All @@ -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 ?? '<no-publishable-key>';

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 ?? {};
}
Expand All @@ -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;
}
}
Loading
Loading