diff --git a/.github/workflows/bridge-ui-v2.yml b/.github/workflows/bridge-ui-v2.yml index 0b7da856a1..b07dfe5849 100644 --- a/.github/workflows/bridge-ui-v2.yml +++ b/.github/workflows/bridge-ui-v2.yml @@ -31,6 +31,16 @@ jobs: working-directory: ./packages/bridge-ui-v2 run: cp .env.example .env + - name: Export config to .env + working-directory: ./packages/bridge-ui-v2 + run: pnpm export:config + + - name: Build Svelte app + env: + SKIP_ENV_VALDIATION: "true" + working-directory: ./packages/bridge-ui-v2 + run: pnpm build + - name: Svelte check working-directory: ./packages/bridge-ui-v2 run: pnpm svelte:check @@ -40,6 +50,8 @@ jobs: run: pnpm lint - name: Unit tests + env: + SKIP_ENV_VALDIATION: "true" working-directory: ./packages/bridge-ui-v2 run: pnpm test:unit diff --git a/packages/bridge-ui-v2/.gitignore b/packages/bridge-ui-v2/.gitignore index 163f35ec65..3be284d684 100644 --- a/packages/bridge-ui-v2/.gitignore +++ b/packages/bridge-ui-v2/.gitignore @@ -14,4 +14,4 @@ vite.config.ts.timestamp-* !/config/sample/ !/config/schemas/ -src/generated/* +src/generated/ diff --git a/packages/bridge-ui-v2/__mocks__/$env/static/public.ts b/packages/bridge-ui-v2/__mocks__/$env/static/public.ts index c4126e3c48..247539b026 100644 --- a/packages/bridge-ui-v2/__mocks__/$env/static/public.ts +++ b/packages/bridge-ui-v2/__mocks__/$env/static/public.ts @@ -1,30 +1,10 @@ -export const PUBLIC_L1_CHAIN_NAME = 'Ethereum'; -export const PUBLIC_L2_CHAIN_NAME = 'Taiko'; -export const PUBLIC_L3_CHAIN_NAME = 'L3 chain'; -export const PUBLIC_L1_CHAIN_ID = '1'; -export const PUBLIC_L2_CHAIN_ID = '2'; -export const PUBLIC_L3_CHAIN_ID = '3'; -export const PUBLIC_L1_RPC_URL = 'https://l1rpc.com'; -export const PUBLIC_L2_RPC_URL = 'https://l2rpc.com'; -export const PUBLIC_L3_RPC_URL = 'https://l3rpc.com'; -export const PUBLIC_L1_EXPLORER_URL = 'https://l1explorer.com'; -export const PUBLIC_L2_EXPLORER_URL = 'https://l2explorer.com'; -export const PUBLIC_L3_EXPLORER_URL = 'https://l3explorer.com'; export const PUBLIC_RELAYER_URL = 'https://relayer.com'; export const PUBLIC_GUIDE_URL = 'https://guide.com'; -export const PUBLIC_L1_CROSS_CHAIN_SYNC_ADDRESS = '0x123'; -export const PUBLIC_L2_CROSS_CHAIN_SYNC_ADDRESS = '0x234'; -export const PUBLIC_L3_CROSS_CHAIN_SYNC_ADDRESS = '0x345'; -export const PUBLIC_L1_TOKEN_VAULT_ADDRESS = '0x456'; -export const PUBLIC_L2_TOKEN_VAULT_ADDRESS = '0x567'; -export const PUBLIC_L3_TOKEN_VAULT_ADDRESS = '0x678'; -export const PUBLIC_L1_BRIDGE_ADDRESS = '0x789'; -export const PUBLIC_L2_BRIDGE_ADDRESS = '0x890'; -export const PUBLIC_L3_BRIDGE_ADDRESS = '0x901'; -export const PUBLIC_L1_SIGNAL_SERVICE_ADDRESS = '0x012'; -export const PUBLIC_L2_SIGNAL_SERVICE_ADDRESS = '0x098'; -export const PUBLIC_L3_SIGNAL_SERVICE_ADDRESS = '0x987'; export const PUBLIC_TEST_ERC20 = '[{"address": "0x876", "symbol": "BLL", "name": "Bull Token"}, {"address": "0x765", "symbol": "HORSE", "name": "Horse Token"}]'; export const PUBLIC_WALLETCONNECT_PROJECT_ID = '123'; export const PUBLIC_SENTRY_DSN = 'https://sentry.com'; +export const CONFIGURED_BRIDGES = ''; +export const CONFIGURED_CHAINS = ''; +export const CONFIGURED_CUSTOM_TOKEN = ''; +export const CONFIGURED_RELAYER = ''; diff --git a/packages/bridge-ui-v2/__mocks__/@wagmi/core.ts b/packages/bridge-ui-v2/__mocks__/@wagmi/core.ts index f86b4bcb56..88658482f1 100644 --- a/packages/bridge-ui-v2/__mocks__/@wagmi/core.ts +++ b/packages/bridge-ui-v2/__mocks__/@wagmi/core.ts @@ -9,3 +9,11 @@ export const getPublicClient = vi.fn(); export const getContract = vi.fn(); export const fetchBalance = vi.fn(); + +export const configureChains = vi.fn(() => { + return { publicClient: 'mockPublicClient' }; +}); + +export const createConfig = vi.fn(() => { + return 'mockWagmiConfig'; +}); diff --git a/packages/bridge-ui-v2/package.json b/packages/bridge-ui-v2/package.json index a3e844c9ea..b752187558 100644 --- a/packages/bridge-ui-v2/package.json +++ b/packages/bridge-ui-v2/package.json @@ -12,7 +12,7 @@ "test:unit:debug": "vitest run", "test:unit:coverage": "vitest run --silent --coverage", "test:unit:watch": "vitest", - "svelte:check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --ignore ./wagmi.config.ts", + "svelte:check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --ignore ./wagmi.config.ts ./src/generated", "svelte:check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --ignore ./wagmi.config.ts --watch", "format": "prettier --write .", "lint": "prettier --check . && eslint .", @@ -27,7 +27,7 @@ "@sveltejs/kit": "^1.22.3", "@types/debug": "^4.1.7", "@typescript-eslint/eslint-plugin": "^6.6.0", - "@typescript-eslint/parser": "^5.45.0", + "@typescript-eslint/parser": "^6.7.0", "@vitest/coverage-v8": "^0.33.0", "@wagmi/cli": "^1.0.1", "abitype": "^0.8.7", diff --git a/packages/bridge-ui-v2/scripts/exportJsonToEnv.js b/packages/bridge-ui-v2/scripts/exportJsonToEnv.js index 2a131fcf33..0f541563dd 100755 --- a/packages/bridge-ui-v2/scripts/exportJsonToEnv.js +++ b/packages/bridge-ui-v2/scripts/exportJsonToEnv.js @@ -3,7 +3,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import { Logger as LogUtil } from './utils/Logger.js'; +import { PluginLogger as LogUtil } from './utils/PluginLogger.js'; const Logger = new LogUtil('exportJsonToEnv'); diff --git a/packages/bridge-ui-v2/scripts/utils/Logger.js b/packages/bridge-ui-v2/scripts/utils/PluginLogger.js similarity index 97% rename from packages/bridge-ui-v2/scripts/utils/Logger.js rename to packages/bridge-ui-v2/scripts/utils/PluginLogger.js index 37c9d5039b..1428a2e4ec 100644 --- a/packages/bridge-ui-v2/scripts/utils/Logger.js +++ b/packages/bridge-ui-v2/scripts/utils/PluginLogger.js @@ -7,7 +7,7 @@ const Reset = '\x1b[0m'; const timestamp = () => new Date().toLocaleTimeString(); -export class Logger { +export class PluginLogger { /** * @param {string} pluginName */ diff --git a/packages/bridge-ui-v2/scripts/utils/validateJson.ts b/packages/bridge-ui-v2/scripts/utils/validateJson.ts index 924152e368..0c34861d0a 100644 --- a/packages/bridge-ui-v2/scripts/utils/validateJson.ts +++ b/packages/bridge-ui-v2/scripts/utils/validateJson.ts @@ -1,13 +1,13 @@ /* eslint-disable no-console */ import Ajv, { type Schema } from 'ajv'; -import { Logger } from './Logger'; +import { PluginLogger } from './PluginLogger'; const ajv = new Ajv({ strict: false }); type SchmaWithId = Schema & { $id?: string }; -const logger = new Logger('json-validator'); +const logger = new PluginLogger('json-validator'); export const validateJsonAgainstSchema = (json: JSON, schema: SchmaWithId): boolean => { logger.info(`Validating ${schema.$id}`); diff --git a/packages/bridge-ui-v2/scripts/vite-plugins/generateBridgeConfig.ts b/packages/bridge-ui-v2/scripts/vite-plugins/generateBridgeConfig.ts index 2e1d8f46c9..6a400be3d5 100644 --- a/packages/bridge-ui-v2/scripts/vite-plugins/generateBridgeConfig.ts +++ b/packages/bridge-ui-v2/scripts/vite-plugins/generateBridgeConfig.ts @@ -7,12 +7,14 @@ import configuredBridgesSchema from '../../config/schemas/configuredBridges.sche import type { BridgeConfig, ConfiguredBridgesType, RoutingMap } from '../../src/libs/bridge/types'; import { decodeBase64ToJson } from '../utils/decodeBase64ToJson'; import { formatSourceFile } from '../utils/formatSourceFile'; -import { Logger } from '../utils/Logger'; +import { PluginLogger } from '../utils/PluginLogger'; import { validateJsonAgainstSchema } from '../utils/validateJson'; dotenv.config(); const pluginName = 'generateBridgeConfig'; -const logger = new Logger(pluginName); +const logger = new PluginLogger(pluginName); + +const skip = process.env.SKIP_ENV_VALDIATION || false; const currentDir = path.resolve(new URL(import.meta.url).pathname); @@ -22,22 +24,27 @@ export function generateBridgeConfig() { return { name: pluginName, async buildStart() { - if (!process.env.CONFIGURED_BRIDGES) { - throw new Error( - 'CONFIGURED_BRIDGES is not defined in environment. Make sure to run the export step in the documentation.', - ); - } - - // Decode base64 encoded JSON string - const configuredBridgesConfigFile = decodeBase64ToJson(process.env.CONFIGURED_BRIDGES || ''); - - // Valide JSON against schema - const isValid = validateJsonAgainstSchema(configuredBridgesConfigFile, configuredBridgesSchema); - - if (!isValid) { - throw new Error('encoded configuredBridges.json is not valid.'); - } logger.info('Plugin initialized.'); + let configuredBridgesConfigFile; + if (!skip) { + if (!process.env.CONFIGURED_BRIDGES) { + throw new Error( + 'CONFIGURED_BRIDGES is not defined in environment. Make sure to run the export step in the documentation.', + ); + } + + // Decode base64 encoded JSON string + configuredBridgesConfigFile = decodeBase64ToJson(process.env.CONFIGURED_BRIDGES || ''); + + // Valide JSON against schema + const isValid = validateJsonAgainstSchema(configuredBridgesConfigFile, configuredBridgesSchema); + + if (!isValid) { + throw new Error('encoded configuredBridges.json is not valid.'); + } + } else { + configuredBridgesConfigFile = ''; + } const tsFilePath = path.resolve(outputPath); @@ -86,58 +93,70 @@ async function buildBridgeConfig(sourceFile: SourceFile, configuredBridgesConfig const bridges: ConfiguredBridgesType = configuredBridgesConfigFile; - if (!bridges.configuredBridges || !Array.isArray(bridges.configuredBridges)) { - logger.error('configuredBridges is not an array. Please check the content of the configuredBridgesConfigFile.'); - throw new Error(); - } - - bridges.configuredBridges.forEach((item: BridgeConfig) => { - if (!routingContractsMap[item.source]) { - routingContractsMap[item.source] = {}; + if (!skip) { + if (!bridges.configuredBridges || !Array.isArray(bridges.configuredBridges)) { + logger.error('configuredBridges is not an array. Please check the content of the configuredBridgesConfigFile.'); + throw new Error(); } - routingContractsMap[item.source][item.destination] = item.addresses; - }); - - // Add routingContractsMap variable - sourceFile.addVariableStatement({ - declarationKind: VariableDeclarationKind.Const, - declarations: [ - { - name: 'routingContractsMap', - type: 'RoutingMap', - initializer: _formatObjectToTsLiteral(routingContractsMap), - }, - ], - isExported: true, - }); - - logger.info(`Configured ${bridges.configuredBridges.length} bridges.`); + bridges.configuredBridges.forEach((item: BridgeConfig) => { + if (!routingContractsMap[item.source]) { + routingContractsMap[item.source] = {}; + } + routingContractsMap[item.source][item.destination] = item.addresses; + }); + } + if (skip) { + // Add empty routingContractsMap variable + sourceFile.addVariableStatement({ + declarationKind: VariableDeclarationKind.Const, + declarations: [ + { + name: 'routingContractsMap', + type: 'RoutingMap', + initializer: '{}', + }, + ], + isExported: true, + }); + logger.info(`Skipped bridge.`); + } else { + // Add routingContractsMap variable + sourceFile.addVariableStatement({ + declarationKind: VariableDeclarationKind.Const, + declarations: [ + { + name: 'routingContractsMap', + type: 'RoutingMap', + initializer: _formatObjectToTsLiteral(routingContractsMap), + }, + ], + isExported: true, + }); + logger.info(`Configured ${bridges.configuredBridges.length} bridges.`); + } return sourceFile; } const _formatObjectToTsLiteral = (obj: RoutingMap): string => { - const formatValue = (value: any): string => { + const formatValue = (value: string | number | boolean | null): string => { if (typeof value === 'string') { return `"${value}"`; } - if (typeof value === 'number' || typeof value === 'boolean' || value === null) { - return String(value); - } - if (Array.isArray(value)) { - return `[${value.map(formatValue).join(', ')}]`; - } - if (typeof value === 'object') { - return _formatObjectToTsLiteral(value); - } - return 'undefined'; + return String(value); }; - if (Array.isArray(obj)) { - return `[${obj.map(formatValue).join(', ')}]`; - } - const entries = Object.entries(obj); - const formattedEntries = entries.map(([key, value]) => `${key}: ${formatValue(value)}`); + const formattedEntries = entries.map(([key, value]) => { + const innerEntries = Object.entries(value); + const innerFormattedEntries = innerEntries.map(([innerKey, innerValue]) => { + const innerInnerEntries = Object.entries(innerValue); + const innerInnerFormattedEntries = innerInnerEntries.map( + ([innerInnerKey, innerInnerValue]) => `${innerInnerKey}: ${formatValue(innerInnerValue)}`, + ); + return `${innerKey}: {${innerInnerFormattedEntries.join(', ')}}`; + }); + return `${key}: {${innerFormattedEntries.join(', ')}}`; + }); return `{${formattedEntries.join(', ')}}`; }; diff --git a/packages/bridge-ui-v2/scripts/vite-plugins/generateChainConfig.ts b/packages/bridge-ui-v2/scripts/vite-plugins/generateChainConfig.ts index bb46dafb2a..f54ae50487 100644 --- a/packages/bridge-ui-v2/scripts/vite-plugins/generateChainConfig.ts +++ b/packages/bridge-ui-v2/scripts/vite-plugins/generateChainConfig.ts @@ -8,12 +8,14 @@ import configuredChainsSchema from '../../config/schemas/configuredChains.schema import type { ChainConfig, ChainConfigMap, ConfiguredChains } from '../../src/libs/chain/types'; import { decodeBase64ToJson } from './../utils/decodeBase64ToJson'; import { formatSourceFile } from './../utils/formatSourceFile'; -import { Logger } from './../utils/Logger'; +import { PluginLogger } from './../utils/PluginLogger'; import { validateJsonAgainstSchema } from './../utils/validateJson'; dotenv.config(); const pluginName = 'generateChainConfig'; -const logger = new Logger(pluginName); +const logger = new PluginLogger(pluginName); + +const skip = process.env.SKIP_ENV_VALDIATION || false; const currentDir = path.resolve(new URL(import.meta.url).pathname); @@ -24,19 +26,23 @@ export function generateChainConfig() { name: pluginName, async buildStart() { logger.info('Plugin initialized.'); + let configuredChainsConfigFile; + if (!skip) { + if (!process.env.CONFIGURED_CHAINS) { + throw new Error( + 'CONFIGURED_CHAINS is not defined in environment. Make sure to run the export step in the documentation.', + ); + } + // Decode base64 encoded JSON string + configuredChainsConfigFile = decodeBase64ToJson(process.env.CONFIGURED_CHAINS || ''); + // Valide JSON against schema + const isValid = validateJsonAgainstSchema(configuredChainsConfigFile, configuredChainsSchema); - if (!process.env.CONFIGURED_CHAINS) { - throw new Error( - 'CONFIGURED_CHAINS is not defined in environment. Make sure to run the export step in the documentation.', - ); - } - // Decode base64 encoded JSON string - const configuredChainsConfigFile = decodeBase64ToJson(process.env.CONFIGURED_CHAINS || ''); - // Valide JSON against schema - const isValid = validateJsonAgainstSchema(configuredChainsConfigFile, configuredChainsSchema); - - if (!isValid) { - throw new Error('encoded configuredBridges.json is not valid.'); + if (!isValid) { + throw new Error('encoded configuredBridges.json is not valid.'); + } + } else { + configuredChainsConfigFile = ''; } // Path to where you want to save the generated TypeScript file @@ -93,31 +99,33 @@ async function buildChainConfig(sourceFile: SourceFile, configuredChainsConfigFi const chains: ConfiguredChains = configuredChainsConfigFile; - if (!chains.configuredChains || !Array.isArray(chains.configuredChains)) { - console.error('configuredChains is not an array. Please check the content of the configuredChainsConfigFile.'); - throw new Error(); - } + if (!skip) { + if (!chains.configuredChains || !Array.isArray(chains.configuredChains)) { + console.error('configuredChains is not an array. Please check the content of the configuredChainsConfigFile.'); + throw new Error(); + } - chains.configuredChains.forEach((item: Record) => { - for (const [chainIdStr, config] of Object.entries(item)) { - const chainId = Number(chainIdStr); - const type = config.type as LayerType; + chains.configuredChains.forEach((item: Record) => { + for (const [chainIdStr, config] of Object.entries(item)) { + const chainId = Number(chainIdStr); + const type = config.type as LayerType; - // Check for duplicates - if (Object.prototype.hasOwnProperty.call(chainConfig, chainId)) { - logger.error(`Duplicate chainId ${chainId} found in configuredChains.json`); - throw new Error(); - } + // Check for duplicates + if (Object.prototype.hasOwnProperty.call(chainConfig, chainId)) { + logger.error(`Duplicate chainId ${chainId} found in configuredChains.json`); + throw new Error(); + } - // Validate LayerType - if (!Object.values(LayerType).includes(config.type)) { - logger.error(`Invalid LayerType ${config.type} found for chainId ${chainId}`); - throw new Error(); - } + // Validate LayerType + if (!Object.values(LayerType).includes(config.type)) { + logger.error(`Invalid LayerType ${config.type} found for chainId ${chainId}`); + throw new Error(); + } - chainConfig[chainId] = { ...config, type }; - } - }); + chainConfig[chainId] = { ...config, type }; + } + }); + } // Add chainConfig variable to sourceFile sourceFile.addVariableStatement({ @@ -132,7 +140,11 @@ async function buildChainConfig(sourceFile: SourceFile, configuredChainsConfigFi isExported: true, }); - logger.info(`Configured ${Object.keys(chainConfig).length} chains.`); + if (skip) { + logger.info(`Skipped chains.`); + } else { + logger.info(`Configured ${Object.keys(chainConfig).length} chains.`); + } return sourceFile; } diff --git a/packages/bridge-ui-v2/scripts/vite-plugins/generateCustomTokenConfig.ts b/packages/bridge-ui-v2/scripts/vite-plugins/generateCustomTokenConfig.ts index 2a950ee956..144583dbc6 100644 --- a/packages/bridge-ui-v2/scripts/vite-plugins/generateCustomTokenConfig.ts +++ b/packages/bridge-ui-v2/scripts/vite-plugins/generateCustomTokenConfig.ts @@ -7,12 +7,14 @@ import configuredChainsSchema from '../../config/schemas/configuredChains.schema import type { Token } from '../../src/libs/token/types'; import { decodeBase64ToJson } from './../utils/decodeBase64ToJson'; import { formatSourceFile } from './../utils/formatSourceFile'; -import { Logger } from './../utils/Logger'; +import { PluginLogger } from './../utils/PluginLogger'; import { validateJsonAgainstSchema } from './../utils/validateJson'; dotenv.config(); const pluginName = 'generateTokens'; -const logger = new Logger(pluginName); +const logger = new PluginLogger(pluginName); + +const skip = process.env.SKIP_ENV_VALDIATION || false; const currentDir = path.resolve(new URL(import.meta.url).pathname); @@ -23,23 +25,27 @@ export function generateCustomTokenConfig() { name: pluginName, async buildStart() { logger.info('Plugin initialized.'); - - if (!process.env.CONFIGURED_CUSTOM_TOKEN) { - throw new Error( - 'CONFIGURED_CUSTOM_TOKEN is not defined in environment. Make sure to run the export step in the documentation.', - ); - } - - // Decode base64 encoded JSON string - const configuredTokenConfigFile = decodeBase64ToJson(process.env.CONFIGURED_CUSTOM_TOKEN || ''); - - // Valide JSON against schema - const isValid = validateJsonAgainstSchema(configuredTokenConfigFile, configuredChainsSchema); - - if (!isValid) { - throw new Error('encoded configuredBridges.json is not valid.'); + let configuredTokenConfigFile; + + if (!skip) { + if (!process.env.CONFIGURED_CUSTOM_TOKEN) { + throw new Error( + 'CONFIGURED_CUSTOM_TOKEN is not defined in environment. Make sure to run the export step in the documentation.', + ); + } + + // Decode base64 encoded JSON string + configuredTokenConfigFile = decodeBase64ToJson(process.env.CONFIGURED_CUSTOM_TOKEN || ''); + + // Valide JSON against schema + const isValid = validateJsonAgainstSchema(configuredTokenConfigFile, configuredChainsSchema); + + if (!isValid) { + throw new Error('encoded configuredBridges.json is not valid.'); + } + } else { + configuredTokenConfigFile = ''; } - const tsFilePath = path.resolve(outputPath); const project = new Project(); @@ -81,21 +87,35 @@ async function storeTypes(sourceFile: SourceFile) { async function buildCustomTokenConfig(sourceFile: SourceFile, configuredTokenConfigFile: Token[]) { logger.info('Building custom token config...'); - const tokens: Token[] = configuredTokenConfigFile; - - sourceFile.addVariableStatement({ - declarationKind: VariableDeclarationKind.Const, - declarations: [ - { - name: 'customToken', - initializer: _formatObjectToTsLiteral(tokens), - type: 'Token[]', - }, - ], - isExported: true, - }); - - logger.info(`Configured ${tokens.length} tokens.`); + if (skip) { + sourceFile.addVariableStatement({ + declarationKind: VariableDeclarationKind.Const, + declarations: [ + { + name: 'customToken', + initializer: '[]', + type: 'Token[]', + }, + ], + isExported: true, + }); + logger.info(`Skipped token.`); + } else { + const tokens: Token[] = configuredTokenConfigFile; + + sourceFile.addVariableStatement({ + declarationKind: VariableDeclarationKind.Const, + declarations: [ + { + name: 'customToken', + initializer: _formatObjectToTsLiteral(tokens), + type: 'Token[]', + }, + ], + isExported: true, + }); + logger.info(`Configured ${tokens.length} tokens.`); + } return sourceFile; } diff --git a/packages/bridge-ui-v2/scripts/vite-plugins/generateRelayerConfig.ts b/packages/bridge-ui-v2/scripts/vite-plugins/generateRelayerConfig.ts index cffe4ebe69..2cb579621b 100644 --- a/packages/bridge-ui-v2/scripts/vite-plugins/generateRelayerConfig.ts +++ b/packages/bridge-ui-v2/scripts/vite-plugins/generateRelayerConfig.ts @@ -8,13 +8,15 @@ import configuredRelayerSchema from '../../config/schemas/configuredRelayer.sche import type { ConfiguredRelayer, RelayerConfig } from '../../src/libs/relayer/types'; import { decodeBase64ToJson } from './../utils/decodeBase64ToJson'; import { formatSourceFile } from './../utils/formatSourceFile'; -import { Logger } from './../utils/Logger'; +import { PluginLogger } from './../utils/PluginLogger'; import { validateJsonAgainstSchema } from './../utils/validateJson'; dotenv.config(); const pluginName = 'generateRelayerConfig'; -const logger = new Logger(pluginName); +const logger = new PluginLogger(pluginName); + +const skip = process.env.SKIP_ENV_VALDIATION || false; const currentDir = path.resolve(new URL(import.meta.url).pathname); @@ -25,22 +27,26 @@ export function generateRelayerConfig() { name: pluginName, async buildStart() { logger.info('Plugin initialized.'); - - if (!process.env.CONFIGURED_RELAYER) { - throw new Error( - 'CONFIGURED_RELAYER is not defined in environment. Make sure to run the export step in the documentation.', - ); - } - - // Decode base64 encoded JSON string - const configuredRelayerConfigFile = decodeBase64ToJson(process.env.CONFIGURED_RELAYER || ''); - - // Valide JSON against schema - const isValid = validateJsonAgainstSchema(configuredRelayerConfigFile, configuredRelayerSchema); - if (!isValid) { - throw new Error('encoded configuredBridges.json is not valid.'); + let configuredRelayerConfigFile; + + if (!skip) { + if (!process.env.CONFIGURED_RELAYER) { + throw new Error( + 'CONFIGURED_RELAYER is not defined in environment. Make sure to run the export step in the documentation.', + ); + } + + // Decode base64 encoded JSON string + configuredRelayerConfigFile = decodeBase64ToJson(process.env.CONFIGURED_RELAYER || ''); + + // Valide JSON against schema + const isValid = validateJsonAgainstSchema(configuredRelayerConfigFile, configuredRelayerSchema); + if (!isValid) { + throw new Error('encoded configuredBridges.json is not valid.'); + } + } else { + configuredRelayerConfigFile = ''; } - // Path to where you want to save the generated Typ eScript file const tsFilePath = path.resolve(outputPath); @@ -84,25 +90,39 @@ async function buildRelayerConfig(sourceFile: SourceFile, configuredRelayerConfi const relayer: ConfiguredRelayer = configuredRelayerConfigFile; - if (!relayer.configuredRelayer || !Array.isArray(relayer.configuredRelayer)) { - console.error('configuredRelayer is not an array. Please check the content of the configuredRelayerConfigFile.'); - throw new Error(); + if (!skip) { + if (!relayer.configuredRelayer || !Array.isArray(relayer.configuredRelayer)) { + console.error('configuredRelayer is not an array. Please check the content of the configuredRelayerConfigFile.'); + throw new Error(); + } + // Create a constant variable for the configuration + const relayerConfigVariable = { + declarationKind: VariableDeclarationKind.Const, + declarations: [ + { + name: 'configuredRelayer', + initializer: _formatObjectToTsLiteral(relayer.configuredRelayer), + type: 'RelayerConfig[]', + }, + ], + isExported: true, + }; + sourceFile.addVariableStatement(relayerConfigVariable); + } else { + const emptyRelayerConfigVariable = { + declarationKind: VariableDeclarationKind.Const, + declarations: [ + { + name: 'configuredRelayer', + initializer: '[]', + type: 'RelayerConfig[]', + }, + ], + isExported: true, + }; + sourceFile.addVariableStatement(emptyRelayerConfigVariable); } - // Create a constant variable for the configuration - const relayerConfigVariable = { - declarationKind: VariableDeclarationKind.Const, - declarations: [ - { - name: 'configuredRelayer', - initializer: _formatObjectToTsLiteral(relayer.configuredRelayer), - type: 'RelayerConfig[]', - }, - ], - isExported: true, - }; - - sourceFile.addVariableStatement(relayerConfigVariable); logger.info('Relayer config built.'); return sourceFile; } diff --git a/packages/bridge-ui-v2/src/components/Activities/MobileDetailsDialog.svelte b/packages/bridge-ui-v2/src/components/Activities/MobileDetailsDialog.svelte index 6077e55591..4a598f1a10 100644 --- a/packages/bridge-ui-v2/src/components/Activities/MobileDetailsDialog.svelte +++ b/packages/bridge-ui-v2/src/components/Activities/MobileDetailsDialog.svelte @@ -4,7 +4,6 @@ import { chainConfig } from '$chainConfig'; import { Icon } from '$components/Icon'; - import { Tooltip } from '$components/Tooltip'; import type { BridgeTransaction } from '$libs/bridge'; import { noop } from '$libs/util/noop'; import { uid } from '$libs/util/uid'; diff --git a/packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte b/packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte deleted file mode 100644 index 01b57cbbef..0000000000 --- a/packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte +++ /dev/null @@ -1,132 +0,0 @@ - - - -
-
-
- -
- - {#if isAddressValid} - - - {/if} - - {#if imageUrls.length > 0} -

Contract Type: {$contractTypeStore}

- {#if imageUrls.length === 1} -
-
- NFT -
-
- {:else if imageUrls.length > 1 && imageUrls.length <= 3} -
- {#each imageUrls as imageUrl, index (imageUrl)} -
- {`Nft -
- {/each} -
- {:else} -
- {#each imageUrls as imageUrl, index (imageUrl)} -
- {`Nft -
- {/each} -
- {/if} - {/if} - - {#if $errorIdStore.length !== 0} - -

Import failed

-

Are you sure all token exist and that you are the owner?

-

Token with id(s) {$errorIdStore} threw errors.

-
-

Check our guide if you need help!

-
- {/if} - -
- -
- -
-
- - - -
- - -
- diff --git a/packages/bridge-ui-v2/src/components/Bridge/NFTIdInput.svelte b/packages/bridge-ui-v2/src/components/Bridge/NFTIdInput.svelte deleted file mode 100644 index d6555b88d5..0000000000 --- a/packages/bridge-ui-v2/src/components/Bridge/NFTIdInput.svelte +++ /dev/null @@ -1,37 +0,0 @@ - - -
-
- -
-
- - Check our guide if you need help finding your token ID -
-
diff --git a/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte b/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte index 49fa06e357..cfaf50a836 100644 --- a/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte +++ b/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte @@ -11,7 +11,6 @@ import { warningToast } from '$components/NotificationToast'; import { chains } from '$libs/chain'; import { classNames } from '$libs/util/classNames'; - import { getConnectedWallet } from '$libs/util/getConnectedWallet'; import { truncateString } from '$libs/util/truncateString'; import { uid } from '$libs/util/uid'; import { account } from '$stores/account'; @@ -62,7 +61,6 @@ async function openModal() { if (readOnly) return; - const wallet = await getConnectedWallet(); // We want to inform the user that they need to connect // their wallet if they want to change the network if (!$account.isConnected) { diff --git a/packages/bridge-ui-v2/src/libs/relayer/RelayerAPIService.test.ts b/packages/bridge-ui-v2/src/libs/relayer/RelayerAPIService.test.ts index 8ec8e3170d..15873606b2 100644 --- a/packages/bridge-ui-v2/src/libs/relayer/RelayerAPIService.test.ts +++ b/packages/bridge-ui-v2/src/libs/relayer/RelayerAPIService.test.ts @@ -5,6 +5,15 @@ import { RelayerAPIService } from './RelayerAPIService'; vi.mock('axios'); +vi.mock('@wagmi/core'); + +vi.mock('$libs/chain', () => { + return { + chains: ['mockChain1', 'mockChain2'], + getConfiguredChainIds: vi.fn(() => [1, 2, 3]), + }; +}); + function setupMocks() { vi.mock('$customToken', () => { return { diff --git a/packages/bridge-ui-v2/src/libs/relayer/initRelayers.ts b/packages/bridge-ui-v2/src/libs/relayer/initRelayers.ts index e00307b080..bb41e51d49 100644 --- a/packages/bridge-ui-v2/src/libs/relayer/initRelayers.ts +++ b/packages/bridge-ui-v2/src/libs/relayer/initRelayers.ts @@ -3,5 +3,5 @@ import { configuredRelayer } from '$relayerConfig'; import { RelayerAPIService } from './RelayerAPIService'; export const relayerApiServices: RelayerAPIService[] = configuredRelayer.map( - (relayerConfig) => new RelayerAPIService(relayerConfig.url), + (relayerConfig: { url: string }) => new RelayerAPIService(relayerConfig.url), ); diff --git a/packages/bridge-ui-v2/src/libs/util/mergeTransactions.test.ts b/packages/bridge-ui-v2/src/libs/util/mergeTransactions.test.ts index 6d6e9125b8..5c5e4b4364 100644 --- a/packages/bridge-ui-v2/src/libs/util/mergeTransactions.test.ts +++ b/packages/bridge-ui-v2/src/libs/util/mergeTransactions.test.ts @@ -5,6 +5,15 @@ import type { TokenType } from '$libs/token'; import { mergeAndCaptureOutdatedTransactions } from '$libs/util/mergeTransactions'; function setupMocks() { + vi.mock('@wagmi/core'); + + vi.mock('$libs/chain', () => { + return { + chains: ['mockChain1', 'mockChain2'], + getConfiguredChainIds: vi.fn(() => [1, 2, 3]), + }; + }); + vi.mock('$customToken', () => { return { customToken: [ diff --git a/packages/bridge-ui-v2/src/routes/nft/+page.svelte b/packages/bridge-ui-v2/src/routes/nft/+page.svelte deleted file mode 100644 index f42ff136dc..0000000000 --- a/packages/bridge-ui-v2/src/routes/nft/+page.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - - - {#if PUBLIC_NFT_BRIDGE_ENABLED === 'true'} - - {/if} - diff --git a/packages/bridge-ui-v2/tsconfig.json b/packages/bridge-ui-v2/tsconfig.json index 49bf04335f..3c3f3d67fb 100644 --- a/packages/bridge-ui-v2/tsconfig.json +++ b/packages/bridge-ui-v2/tsconfig.json @@ -27,9 +27,10 @@ // https://vitest.dev/config/#globals "types": ["vitest/globals"] - } + }, // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias // // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes // from the referenced tsconfig.json - TypeScript does not merge them in + "exclude": ["scripts/utils/PluginLogger.js"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e061bc6feb..73ebaa3382 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -251,10 +251,10 @@ importers: version: 4.1.7 '@typescript-eslint/eslint-plugin': specifier: ^6.6.0 - version: 6.6.0(@typescript-eslint/parser@5.45.0)(eslint@8.28.0)(typescript@5.2.2) + version: 6.6.0(@typescript-eslint/parser@6.7.0)(eslint@8.28.0)(typescript@5.2.2) '@typescript-eslint/parser': - specifier: ^5.45.0 - version: 5.45.0(eslint@8.28.0)(typescript@5.2.2) + specifier: ^6.7.0 + version: 6.7.0(eslint@8.28.0)(typescript@5.2.2) '@vitest/coverage-v8': specifier: ^0.33.0 version: 0.33.0(vitest@0.32.2) @@ -5851,7 +5851,7 @@ packages: - supports-color dev: true - /@typescript-eslint/eslint-plugin@6.6.0(@typescript-eslint/parser@5.45.0)(eslint@8.28.0)(typescript@5.2.2): + /@typescript-eslint/eslint-plugin@6.6.0(@typescript-eslint/parser@6.7.0)(eslint@8.28.0)(typescript@5.2.2): resolution: {integrity: sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -5863,7 +5863,7 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.8.1 - '@typescript-eslint/parser': 5.45.0(eslint@8.28.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.7.0(eslint@8.28.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 6.6.0 '@typescript-eslint/type-utils': 6.6.0(eslint@8.28.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.6.0(eslint@8.28.0)(typescript@5.2.2) @@ -5980,19 +5980,20 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@5.45.0(eslint@8.28.0)(typescript@5.2.2): - resolution: {integrity: sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/parser@6.7.0(eslint@8.28.0)(typescript@5.2.2): + resolution: {integrity: sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.45.0 - '@typescript-eslint/types': 5.45.0 - '@typescript-eslint/typescript-estree': 5.45.0(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.7.0 + '@typescript-eslint/types': 6.7.0 + '@typescript-eslint/typescript-estree': 6.7.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.7.0 debug: 4.3.4(supports-color@8.1.1) eslint: 8.28.0 typescript: 5.2.2 @@ -6032,6 +6033,14 @@ packages: '@typescript-eslint/visitor-keys': 6.6.0 dev: true + /@typescript-eslint/scope-manager@6.7.0: + resolution: {integrity: sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.7.0 + '@typescript-eslint/visitor-keys': 6.7.0 + dev: true + /@typescript-eslint/type-utils@5.44.0(eslint@7.32.0)(typescript@4.9.3): resolution: {integrity: sha512-A1u0Yo5wZxkXPQ7/noGkRhV4J9opcymcr31XQtOzcc5nO/IHN2E2TPMECKWYpM3e6olWEM63fq/BaL1wEYnt/w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6152,6 +6161,11 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true + /@typescript-eslint/types@6.7.0: + resolution: {integrity: sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + /@typescript-eslint/typescript-estree@4.33.0(typescript@4.9.5): resolution: {integrity: sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==} engines: {node: ^10.12.0 || >=12.0.0} @@ -6236,28 +6250,28 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree@5.45.0(typescript@5.2.2): - resolution: {integrity: sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/typescript-estree@6.6.0(typescript@4.9.3): + resolution: {integrity: sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.45.0 - '@typescript-eslint/visitor-keys': 5.45.0 + '@typescript-eslint/types': 6.6.0 + '@typescript-eslint/visitor-keys': 6.6.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - tsutils: 3.21.0(typescript@5.2.2) - typescript: 5.2.2 + ts-api-utils: 1.0.3(typescript@4.9.3) + typescript: 4.9.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@6.6.0(typescript@4.9.3): + /@typescript-eslint/typescript-estree@6.6.0(typescript@4.9.5): resolution: {integrity: sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -6272,13 +6286,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@4.9.3) - typescript: 4.9.3 + ts-api-utils: 1.0.3(typescript@4.9.5) + typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@6.6.0(typescript@4.9.5): + /@typescript-eslint/typescript-estree@6.6.0(typescript@5.2.2): resolution: {integrity: sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -6293,14 +6307,14 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@4.9.5) - typescript: 4.9.5 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@6.6.0(typescript@5.2.2): - resolution: {integrity: sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==} + /@typescript-eslint/typescript-estree@6.7.0(typescript@5.2.2): + resolution: {integrity: sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -6308,8 +6322,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.6.0 - '@typescript-eslint/visitor-keys': 6.6.0 + '@typescript-eslint/types': 6.7.0 + '@typescript-eslint/visitor-keys': 6.7.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 @@ -6468,6 +6482,14 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@typescript-eslint/visitor-keys@6.7.0: + resolution: {integrity: sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.7.0 + eslint-visitor-keys: 3.4.3 + dev: true + /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: false @@ -24454,16 +24476,6 @@ packages: typescript: 4.9.5 dev: true - /tsutils@3.21.0(typescript@5.2.2): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 5.2.2 - dev: true - /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: