diff --git a/packages/explorer/src/components/SearchBar.tsx b/packages/explorer/src/components/SearchBar.tsx index 34718d855..4e10ab591 100644 --- a/packages/explorer/src/components/SearchBar.tsx +++ b/packages/explorer/src/components/SearchBar.tsx @@ -1,7 +1,7 @@ import { useContext, useRef } from 'react' import { useNavigate } from 'react-router-dom' import { ComputerContext } from '@bitcoin-computer/components' -import { isValidHexadecimalPublicKey } from '../utils' +import { isPossibleCryptoAddress, isValidHexadecimalPublicKey } from '../utils' export function SearchBar() { const inputRef = useRef(null) @@ -21,6 +21,7 @@ export function SearchBar() { } } else if (isValidHexadecimalPublicKey(searchInput)) navigate(`/?public-key=${searchInput.trim()}`) + else if (isPossibleCryptoAddress(searchInput)) navigate(`/utxos/${searchInput}`) else navigate(`/transactions/${searchInput}`) } } diff --git a/packages/explorer/src/utils.ts b/packages/explorer/src/utils.ts index a7718889a..5a872fe2d 100644 --- a/packages/explorer/src/utils.ts +++ b/packages/explorer/src/utils.ts @@ -96,6 +96,16 @@ export const getValueForType = (type: string, stringValue: string) => { export const capitalizeFirstLetter = (string: string) => string.charAt(0).toUpperCase() + string.slice(1) +export const isPossibleCryptoAddress = (address: string): boolean => { + // Regular expressions for common address formats + const p2pkhRegex = /^[1mn][a-km-zA-HJ-NP-Z1-9]{25,34}$/ // P2PKH (mainnet/testnet) + const p2shRegex = /^[23][a-km-zA-HJ-NP-Z1-9]{25,34}$/ // P2SH (mainnet/testnet) + const bech32Regex = /^(bc1|ltc1|doge1|t[a-z]{2})[a-z0-9]{6,80}$/ // Bech32 (mainnet/testnet) + + // Check if the address matches any of the regex patterns + return p2pkhRegex.test(address) || p2shRegex.test(address) || bech32Regex.test(address) +} + export const isValidHexadecimalPublicKey = (publicKey: string): boolean => { if (!publicKey) return false const trimmedPublicKey = publicKey.trim() diff --git a/packages/vite-template/package.json b/packages/vite-template/package.json index 508949159..3e178fdac 100644 --- a/packages/vite-template/package.json +++ b/packages/vite-template/package.json @@ -15,9 +15,9 @@ "lint:fix": "eslint . --fix", "preview": "vite preview", "start": "vite", - "test": "vitest run", + "test": "vitest run && npm run test:puppeteer:build:headless", "test:dev": "vitest", - "test:puppeteer": "vitest run --config vite.puppeteer.config.ts", + "test:puppeteer": "vitest run --config vitest.puppeteer.config.ts", "test:puppeteer:headless": "HEADLESS=true npm run test:puppeteer", "test:puppeteer:build:headless": "npm run build && (npm run preview & sleep 2 && URL=http://localhost:4173 HEADLESS=true npm run test:puppeteer && pkill -f 'vite preview')", "test:show": "npm run test 2>&1 | tee vite-template-test.log; if [ ${PIPESTATUS[0]} -ne 0 ]; then open vite-template-test.log; fi", diff --git a/packages/vite-template/vite.config.ts b/packages/vite-template/vite.config.ts index 470a456d7..e8c8a8288 100644 --- a/packages/vite-template/vite.config.ts +++ b/packages/vite-template/vite.config.ts @@ -1,12 +1,10 @@ -/// /// -import { defineConfig, loadEnv } from 'vite' -import react from '@vitejs/plugin-react' +import { defineConfig, loadEnv } from 'vite'; +import react from '@vitejs/plugin-react'; -// https://vitejs.dev/config/ export default defineConfig(({ mode }) => { - const env = loadEnv(mode, process.cwd(), '') + const env = loadEnv(mode, process.cwd(), ''); return { plugins: [react()], server: { @@ -16,11 +14,5 @@ export default defineConfig(({ mode }) => { 'Cross-Origin-Embedder-Policy': 'require-corp', }, }, - test: { - globals: true, - include: ['src/**/*.test.tsx'], - environment: 'jsdom', - setupFiles: ['./src/setupTests.ts'], - }, - } -}) + }; +}); \ No newline at end of file diff --git a/packages/vite-template/vite.puppeteer.config.ts b/packages/vite-template/vite.puppeteer.config.ts deleted file mode 100644 index f87e4b413..000000000 --- a/packages/vite-template/vite.puppeteer.config.ts +++ /dev/null @@ -1,25 +0,0 @@ -/// -/// - -import { defineConfig, loadEnv } from 'vite' -import react from '@vitejs/plugin-react' - -// https://vitejs.dev/config/ -export default defineConfig(({ mode }) => { - const env = loadEnv(mode, process.cwd(), '') - return { - plugins: [react()], - server: { - port: parseInt(env.VITE_PORT), - headers: { - 'Cross-Origin-Opener-Policy': 'same-origin', - 'Cross-Origin-Embedder-Policy': 'require-corp', - }, - }, - test: { - include: ['tests/**/*.test.ts'], - environment: 'node', - testTimeout: 30000, - }, - } -}) diff --git a/packages/vite-template/vitest.config.ts b/packages/vite-template/vitest.config.ts new file mode 100644 index 000000000..39bed27e8 --- /dev/null +++ b/packages/vite-template/vitest.config.ts @@ -0,0 +1,25 @@ +/// +/// + +import { defineConfig } from 'vitest/config' +import baseConfig from './vite.config' +import path from 'path' + +export default defineConfig(({ mode }) => { + // Load the base Vite configuration + const base = baseConfig({ mode, command: 'serve' }) + + return { + ...base, + test: { + globals: true, + include: ['src/**/*.test.tsx'], + environment: 'jsdom', + setupFiles: ['./src/setupTests.ts'], + alias: { + // Define the alias pointing to the specific entry point in node_modules + '@bitcoin-computer/lib': path.resolve(__dirname, '../lib/dist/bc-lib.browser.min.mjs'), + }, + }, + } +}) diff --git a/packages/vite-template/vitest.puppeteer.config.ts b/packages/vite-template/vitest.puppeteer.config.ts new file mode 100644 index 000000000..d59b536fc --- /dev/null +++ b/packages/vite-template/vitest.puppeteer.config.ts @@ -0,0 +1,20 @@ +/// +/// + +import { defineConfig } from 'vitest/config' +import baseConfig from './vite.config' + +// Extend the core Vite configuration with Puppeteer-specific test settings +export default defineConfig(({ mode }) => { + // Load the base Vite configuration + const base = baseConfig({ mode, command: 'serve' }) + + return { + ...base, + test: { + include: ['tests/**/*.test.ts'], + environment: 'node', + testTimeout: 30000, + }, + } +})