From cbae059f04d372c8da2a21756f827cffdf4f462b Mon Sep 17 00:00:00 2001 From: Timidan Date: Thu, 28 May 2026 11:53:18 +0100 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20codebase=20cleanup=20=E2=80=94=20r?= =?UTF-8?q?emove=20legacy=20CSS,=20stubs,=20and=20unused=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Net effect: ~7.1k lines deleted across 76 files. Removed: - api/vertexAuth.ts (server Vertex auth helper, unused) - src/components/SimpleGridUI.tsx (legacy thin-stub) - src/components/SmartDecoder.tsx (legacy thin-stub) - src/components/shared/Card.tsx, Input.tsx (unused shared primitives) - src/components/icons/IconMap.tsx (unused icon mapping) - src/components/integrations/lifi-earn/SparkleShowcase.tsx (dev/experiment file) - src/components/transaction-builder/SimulationReplayResults.tsx (unused replay UI) - src/styles/ContractComponents.css, SimulatorWorkbench.css (gutted CSS stubs) Modifications: 66 files trimmed for dead code, unused imports, and consolidated styles. --- .env.example | 24 +- .gitignore | 5 + api/vertexAuth.ts | 122 -- edb | 2 +- eslint.config.js | 7 +- index.html | 1 + package-lock.json | 595 +----- package.json | 9 +- src/App.css | 1884 +---------------- src/components/InlineFacetLoader.tsx | 4 +- src/components/SimpleGridUI.tsx | 16 - src/components/SmartDecoder.tsx | 3 - src/components/TransactionBuilderHub.tsx | 2 +- src/components/TransactionBuilderWagmi.tsx | 5 +- .../contract/ContractAddressInput.tsx | 1 - src/components/debug/DebugWindow.tsx | 14 +- src/components/explorer/StorageCells.tsx | 11 - .../storage-viewer/fetchStorageLayout.ts | 14 - .../explorer/storageViewerHelpers.ts | 2 +- .../explorer/useStorageViewerState.ts | 2 +- src/components/icons/IconLibrary.tsx | 379 +--- src/components/icons/IconMap.tsx | 70 - .../integrations/IntegrationsHub.tsx | 10 +- .../lifi-earn/SparkleShowcase.tsx | 503 ----- .../lifi-earn/concierge/ExecutionQueue.tsx | 4 +- .../concierge/VaultRecommendations.tsx | 27 + .../concierge/hooks/useIdleBalances.ts | 21 +- .../hooks/useVaultRecommendations.ts | 29 +- .../concierge/intent/hooks/useIntentParser.ts | 2 +- .../intent/hooks/useIntentRecommendation.ts | 2 +- .../intent/hooks/useVaultsByIntent.ts | 2 +- .../lifi-earn/simulator/projection.ts | 13 - src/components/shared/AddressDisplay.tsx | 10 - src/components/shared/Card.tsx | 60 - src/components/shared/Input.tsx | 77 - src/components/shared/index.ts | 16 +- .../signature-database/ToolsTab.tsx | 2 +- src/components/signature-database/types.ts | 12 - src/components/simple-grid/GridLayout.tsx | 4 +- src/components/simple-grid/SimpleGridMain.tsx | 1 - .../simple-grid/hooks/useFunctionState.ts | 4 +- src/components/simple-grid/tokenDetection.ts | 2 +- .../simple-grid/tokenDetection/universal.ts | 2 +- .../simulation-results/formatters.ts | 27 - src/components/smart-decoder/SmartDecoder.tsx | 17 - .../smart-decoder/useDecodeHandlers.ts | 2 +- src/components/smart-decoder/utils.ts | 119 -- .../SimulationReplayResults.tsx | 241 --- src/components/transaction-builder/types.ts | 3 - src/config/networkConfig.ts | 80 - src/contexts/SimulationContext.tsx | 15 +- src/contexts/debug/structStorageDecoding.ts | 2 +- src/services/DebugBridgeService.ts | 93 - src/styles/CompactArrayStyles.css | 251 --- src/styles/ContractComponents.css | 2 - src/styles/ExecutionStackTrace.css | 193 -- src/styles/SharedComponents.css | 778 ------- src/styles/SimpleGridUI.css | 711 ------- src/styles/SimulationResultsPage.css | 716 ------- src/styles/SimulatorWorkbench.css | 9 - src/styles/StackedOverview.css | 34 - src/styles/TokenMovementsPanel.css | 11 - src/styles/design-tokens.css | 59 - src/types/contractInfo.ts | 9 - src/types/debug.ts | 8 - src/types/transaction.ts | 11 - src/utils/diamondFacetFetcher.ts | 8 +- src/utils/resultFormatter.ts | 2 +- src/utils/traceDecoder/decodeTraceInit.ts | 2 +- src/utils/traceDecoder/jumpAnalysis.ts | 2 +- src/utils/traceDecoder/pcMapper.ts | 2 +- .../bridgeSimulation.ts | 2 +- src/utils/universalTokenDetector.ts | 6 +- tsconfig.app.json | 8 +- vercel.json | 20 +- vite.config.ts | 8 +- 76 files changed, 140 insertions(+), 7286 deletions(-) delete mode 100644 api/vertexAuth.ts delete mode 100644 src/components/SimpleGridUI.tsx delete mode 100644 src/components/SmartDecoder.tsx delete mode 100644 src/components/icons/IconMap.tsx delete mode 100644 src/components/integrations/lifi-earn/SparkleShowcase.tsx delete mode 100644 src/components/shared/Card.tsx delete mode 100644 src/components/shared/Input.tsx delete mode 100644 src/components/transaction-builder/SimulationReplayResults.tsx delete mode 100644 src/styles/ContractComponents.css delete mode 100644 src/styles/SimulatorWorkbench.css diff --git a/.env.example b/.env.example index 6a9964e..cdbd1c4 100644 --- a/.env.example +++ b/.env.example @@ -22,12 +22,30 @@ VITE_WALLETCONNECT_PROJECT_ID=your-walletconnect-project-id # LLM / Yield Concierge AI recommendations # GEMINI_API_KEY — Google AI Studio key for Gemini -# GEMINI_MODEL — Primary model (default: gemini-3.1-pro-preview) -# GEMINI_FALLBACK_MODEL — Fallback on 429/503 (default: gemini-2.5-flash) +# GEMINI_MODEL — Primary model (default: gemini-2.5-flash-lite) + +# LLM mode toggle (browser-side) +# VITE_LLM_MODE — Set to "fixture" to use bundled fixtures instead of live LLM (default: live) # Shared proxy secret (optional — when set, lifi-composer and llm-recommend -# proxies require this value in the x-proxy-secret header instead of origin checks) +# proxies require this value in the x-proxy-secret header instead of origin checks). +# WARNING: setting this disables browser callers — proxyHeaders() does not send +# x-proxy-secret. Use only for server-to-server callers. # PROXY_SECRET — Random secret string # Origin allowlist for lifi-composer and llm-recommend proxies # ALLOWED_ORIGINS — Comma-separated origins (e.g. https://yourdomain.com,https://preview.yourdomain.com) + +# ---- Simulator-bridge runtime tuning (read by scripts/simulator-bridge.mjs etc.) ---- +# These are typically left at defaults; tune only if you understand the impact. +# SIMULATOR_BRIDGE_PORT, EDB_WS_PORT +# TRACE_DETAIL_TTL_MS, TRACE_DETAIL_MAX_ENTRIES, TRACE_DETAIL_MAX_TOTAL_BYTES +# TRACE_DETAIL_GZIP_MIN_BYTES, TRACE_DETAIL_STRIP_OPCODE_LINES +# TRACE_DETAIL_STRIP_OPCODE_TRACE, TRACE_DETAIL_COMPACT_ARTIFACTS +# SIM_TRACE_V2_BRIDGE_JS_FALLBACK, SIM_TRACE_V2_LITE_TRANSPORT +# KEEP_ALIVE_IDLE_TTL_MS, KEEP_ALIVE_SWEEP_INTERVAL_MS, KEEP_ALIVE_MAX_SESSIONS +# KEEP_ALIVE_CLEAN_STALE_ON_STARTUP, KEEP_ALIVE_INCREMENTAL_PARSE_MAX_BYTES +# KEEP_ALIVE_SIM_TIMEOUT_MS, SIMULATION_TIMEOUT_MS, MAX_CONCURRENT_SIMULATIONS +# SIMULATION_QUEUE_MAX, SIMULATION_QUEUE_TIMEOUT_MS +# MEMORY_PRESSURE_THRESHOLD_MB, MEMORY_PRESSURE_HARD_LIMIT_MB +# SIMULATOR_BUILD_PROFILE, SIMULATOR_BINARY, EDB_BINARY diff --git a/.gitignore b/.gitignore index 7b8edfe..96b1c4b 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,11 @@ edb *test* *Test* *TEST* +*.spec.ts +*.spec.tsx +*.spec.js +*.spec.mjs +*.spec.mts /tmp video/out .superpowers diff --git a/api/vertexAuth.ts b/api/vertexAuth.ts deleted file mode 100644 index 010026b..0000000 --- a/api/vertexAuth.ts +++ /dev/null @@ -1,122 +0,0 @@ -import crypto from "crypto"; - -interface ServiceAccountKey { - project_id: string; - private_key: string; - client_email: string; -} - -interface TokenCache { - token: string; - expiresAt: number; -} - -let cachedToken: TokenCache | null = null; - -/** - * Load the service account key from either: - * 1. GOOGLE_SA_KEY_JSON env var (raw JSON string — for Vercel) - * 2. A local JSON file path in GOOGLE_APPLICATION_CREDENTIALS - */ -function loadServiceAccountKey(): ServiceAccountKey | null { - const raw = process.env.GOOGLE_SA_KEY_JSON; - if (raw) { - try { - return JSON.parse(raw); - } catch { - return null; - } - } - - const filePath = process.env.GOOGLE_APPLICATION_CREDENTIALS; - if (filePath) { - try { - // Dynamic require for local dev — Vercel bundles won't hit this path - // eslint-disable-next-line @typescript-eslint/no-var-requires - const fs = require("fs"); - const content = fs.readFileSync(filePath, "utf-8"); - return JSON.parse(content); - } catch { - return null; - } - } - - return null; -} - -function base64url(input: Buffer | string): string { - const buf = typeof input === "string" ? Buffer.from(input) : input; - return buf.toString("base64url"); -} - -/** - * Create a signed JWT for Google OAuth2 token exchange. - */ -function createJwt(sa: ServiceAccountKey): string { - const now = Math.floor(Date.now() / 1000); - const header = { alg: "RS256", typ: "JWT" }; - const payload = { - iss: sa.client_email, - sub: sa.client_email, - aud: "https://oauth2.googleapis.com/token", - scope: "https://www.googleapis.com/auth/cloud-platform", - iat: now, - exp: now + 3600, - }; - - const segments = [ - base64url(JSON.stringify(header)), - base64url(JSON.stringify(payload)), - ]; - const signingInput = segments.join("."); - - const sign = crypto.createSign("RSA-SHA256"); - sign.update(signingInput); - const signature = sign.sign(sa.private_key); - - return `${signingInput}.${base64url(signature)}`; -} - -/** - * Get a valid access token, minting a new one if the cached token is expired. - * Returns null if no service account key is configured. - */ -export async function getAccessToken(): Promise { - // Return cached token if still valid (with 60s buffer) - if (cachedToken && cachedToken.expiresAt > Date.now() + 60_000) { - return cachedToken.token; - } - - const sa = loadServiceAccountKey(); - if (!sa) return null; - - const jwt = createJwt(sa); - - const res = await fetch("https://oauth2.googleapis.com/token", { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: `grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=${jwt}`, - }); - - if (!res.ok) { - const text = await res.text(); - console.error("[vertexAuth] Token exchange failed:", res.status, text); - return null; - } - - const data = (await res.json()) as { access_token: string; expires_in: number }; - cachedToken = { - token: data.access_token, - expiresAt: Date.now() + data.expires_in * 1000, - }; - - return cachedToken.token; -} - -/** - * Get the Vertex AI project ID from the service account key. - */ -export function getProjectId(): string | null { - const sa = loadServiceAccountKey(); - return sa?.project_id ?? null; -} diff --git a/edb b/edb index 1ba2fca..c5b32ca 160000 --- a/edb +++ b/edb @@ -1 +1 @@ -Subproject commit 1ba2fcaca73cee96bf10107b7b0f98ab1ceab1a4 +Subproject commit c5b32ca53e7c2146e647830af486b6481aa37548 diff --git a/eslint.config.js b/eslint.config.js index 2c133c2..3eabd89 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -2,7 +2,6 @@ import js from '@eslint/js'; import tseslint from 'typescript-eslint'; import globals from 'globals'; import reactHooks from 'eslint-plugin-react-hooks'; -import reactRefresh from 'eslint-plugin-react-refresh'; export default tseslint.config( { @@ -17,6 +16,10 @@ export default tseslint.config( 'test-*/**', '**/test-*.js', 'test-app-*/**', + '.claude/worktrees/**', + 'edb/**', + 'starknet-sim/**', + 'fhe/**', ], }, js.configs.recommended, @@ -31,12 +34,10 @@ export default tseslint.config( }, plugins: { 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, }, rules: { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn', - 'react-refresh/only-export-components': 'off', '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], 'no-console': 'off', diff --git a/index.html b/index.html index 6746f42..cc97d12 100644 --- a/index.html +++ b/index.html @@ -70,6 +70,7 @@ +
diff --git a/package-lock.json b/package-lock.json index f91a06a..9e7daa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,16 +63,17 @@ "@vitejs/plugin-react": "^4.7.0", "eslint": "^9.33.0", "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", "happy-dom": "^20.9.0", - "jsdom": "^27.0.1", "tailwindcss": "^4.1.18", "tw-animate-css": "^1.4.0", "typescript": "~5.8.3", "typescript-eslint": "^8.39.1", "vite": "^5.4.19", "vitest": "^1.6.1" + }, + "engines": { + "node": ">=18" } }, "node_modules/@adobe/css-tools": { @@ -100,61 +101,6 @@ "node": ">=6.0.0" } }, - "node_modules/@asamuzakjp/css-color": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", - "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-color-parser": "^3.1.0", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "lru-cache": "^11.2.4" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@asamuzakjp/dom-selector": { - "version": "6.7.6", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.6.tgz", - "integrity": "sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/nwsapi": "^2.3.9", - "bidi-js": "^1.0.3", - "css-tree": "^3.1.0", - "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.4" - } - }, - "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@asamuzakjp/nwsapi": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", - "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -483,141 +429,6 @@ "node": ">=6" } }, - "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.25", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.25.tgz", - "integrity": "sha512-g0Kw9W3vjx5BEBAF8c5Fm2NcB/Fs8jJXh85aXqwEXiL+tqtOut07TWgyaGzAAfTM+gKckrrncyeGEZPcaRgm2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/@ecies/ciphers": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.6.tgz", @@ -10375,16 +10186,6 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, - "node_modules/bidi-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", - "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "require-from-string": "^2.0.2" - } - }, "node_modules/big.js": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.2.tgz", @@ -10904,20 +10705,6 @@ "uncrypto": "^0.1.3" } }, - "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, "node_modules/css-what": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", @@ -10947,32 +10734,6 @@ "node": ">=4" } }, - "node_modules/cssstyle": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", - "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/css-color": "^4.1.1", - "@csstools/css-syntax-patches-for-csstree": "^1.0.21", - "css-tree": "^3.1.0", - "lru-cache": "^11.2.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cssstyle/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -11107,67 +10868,6 @@ "node": ">=12" } }, - "node_modules/data-urls": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", - "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^15.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/data-urls/node_modules/tr46": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", - "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/data-urls/node_modules/webidl-conversions": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", - "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=20" - } - }, - "node_modules/data-urls/node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", - "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^6.0.0", - "webidl-conversions": "^8.0.0" - }, - "engines": { - "node": ">=20" - } - }, "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -11215,13 +10915,6 @@ "node": ">=0.10.0" } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true, - "license": "MIT" - }, "node_modules/decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", @@ -11794,15 +11487,6 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.20", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", - "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", - "dev": true, - "peerDependencies": { - "eslint": ">=8.40" - } - }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", @@ -12668,33 +12352,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -12708,18 +12365,6 @@ "node": ">= 14" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/idb-keyval": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", @@ -12899,13 +12544,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -13010,93 +12648,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsdom": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.0.1.tgz", - "integrity": "sha512-SNSQteBL1IlV2zqhwwolaG9CwhIhTvVHWg3kTss/cLE7H/X4644mtPQqYvCfsSrGQWt9hSZcgOXX8bOZaMN+kA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/dom-selector": "^6.7.2", - "cssstyle": "^5.3.1", - "data-urls": "^6.0.0", - "decimal.js": "^10.6.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", - "is-potential-custom-element-name": "^1.0.1", - "parse5": "^8.0.0", - "rrweb-cssom": "^0.8.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^6.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^8.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^15.1.0", - "ws": "^8.18.3", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "canvas": "^3.0.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/tr46": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", - "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/jsdom/node_modules/webidl-conversions": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", - "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=20" - } - }, - "node_modules/jsdom/node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/jsdom/node_modules/whatwg-url": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", - "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^6.0.0", - "webidl-conversions": "^8.0.0" - }, - "engines": { - "node": ">=20" - } - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -13636,13 +13187,6 @@ "node": ">= 0.4" } }, - "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/media-query-parser": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/media-query-parser/-/media-query-parser-2.0.2.tgz", @@ -14206,32 +13750,6 @@ "node": ">=6" } }, - "node_modules/parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", - "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -15113,13 +14631,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "dev": true, - "license": "MIT" - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -15189,25 +14700,6 @@ "node": ">=10" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", @@ -15534,13 +15026,6 @@ "node": ">=8" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, "node_modules/tailwind-merge": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", @@ -15674,36 +15159,6 @@ "node": ">=8.0" } }, - "node_modules/tough-cookie": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", - "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", - "dev": true, - "dependencies": { - "tldts": "^7.0.5" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tough-cookie/node_modules/tldts": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.17.tgz", - "integrity": "sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==", - "dev": true, - "dependencies": { - "tldts-core": "^7.0.17" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tough-cookie/node_modules/tldts-core": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.17.tgz", - "integrity": "sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==", - "dev": true - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -17061,19 +16516,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/wagmi": { "version": "2.16.9", "resolved": "https://registry.npmjs.org/wagmi/-/wagmi-2.16.9.tgz", @@ -17110,20 +16552,6 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", @@ -17252,23 +16680,6 @@ } } }, - "node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, "node_modules/xmlhttprequest-ssl": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", diff --git a/package.json b/package.json index 1dab314..6806f60 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,11 @@ "name": "web3-toolkit", "private": true, "version": "0.0.0", + "description": "HexKit — Ethereum/EVM developer toolkit with simulation, debugging, decoder, and DeFi yield concierge.", "type": "module", + "engines": { + "node": ">=18" + }, "scripts": { "dev": "vite --host", "dev:hot": "vite --host --force", @@ -11,9 +15,6 @@ "test": "vitest", "test:run": "NODE_OPTIONS='--max-old-space-size=8192' vitest run", "test:coverage": "NODE_OPTIONS='--max-old-space-size=8192' vitest run --coverage", - "perf:debug-matrix": "node scripts/perf/debug-stress-matrix.mjs", - "qa:live:matrix": "node scripts/perf/live-qa-matrix.mjs", - "probe:testnets": "node scripts/testnet-probe.js", "simulator:server": "node scripts/simulator-bridge.mjs", "preview": "vite preview", "check:inline-copy": "node scripts/check-inline-copy.mjs" @@ -74,10 +75,8 @@ "@vitejs/plugin-react": "^4.7.0", "eslint": "^9.33.0", "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", "happy-dom": "^20.9.0", - "jsdom": "^27.0.1", "tailwindcss": "^4.1.18", "tw-animate-css": "^1.4.0", "typescript": "~5.8.3", diff --git a/src/App.css b/src/App.css index 6c0d2b4..cffe479 100644 --- a/src/App.css +++ b/src/App.css @@ -288,55 +288,8 @@ body { /* ========== CLEAN ETHERSCAN-STYLE LAYOUT SYSTEM ========== */ /* Simple form sections - Flat style */ -.form-section { - background: transparent; - border: none; - border-radius: 0; - padding: 0; - margin-bottom: 20px; -} - -.form-section h3 { - margin: 0 0 16px 0; - color: var(--text-primary); - font-size: 19px; - font-weight: 600; - padding-bottom: 8px; - border-bottom: 1px solid var(--border-primary); -} /* Simple input groups */ -.form-group { - margin-bottom: 16px; -} - -.form-group label { - display: block; - margin-bottom: 6px; - font-size: 16px; - font-weight: 500; - color: #374151; -} - -.form-group input, -.form-group select, -.form-group textarea { - width: 100%; - padding: 8px 12px; - border: 1px solid var(--border-primary); - border-radius: 6px; - font-size: 16px; - background: var(--bg-secondary); - color: var(--text-primary); -} - -.form-group input:focus, -.form-group select:focus, -.form-group textarea:focus { - outline: none; - border-color: var(--accent-primary); - box-shadow: 0 0 0 1px var(--accent-primary); -} /* Button groups - simple horizontal layout */ .button-group { @@ -355,29 +308,8 @@ body { } /* Results sections - Flat style */ -.result-section { - background: transparent; - border-top: 1px solid var(--border-primary); - border-radius: 0; - padding: 16px 0; - margin-top: 20px; -} - -.result-section h4 { - margin: 0 0 12px 0; - color: var(--text-primary); - font-size: 17px; - font-weight: 600; -} /* Clean card layout - Flat style */ -.clean-card { - background: transparent; - border: 1px solid var(--border-primary); - border-radius: 8px; - padding: 16px; - margin-bottom: 12px; -} /* Simple responsive adjustments */ @media (max-width: 768px) { @@ -385,10 +317,6 @@ body { padding: 16px; } - .form-section { - padding: 16px; - } - .button-group { flex-direction: column; align-items: stretch; @@ -439,27 +367,7 @@ body { /* ========== CLEAN FORM ELEMENTS ========== */ -.form-group { - margin-bottom: 16px; -} - -.form-group label { - display: block; - font-weight: 500; - font-size: 16px; - color: var(--text-secondary); - margin-bottom: 6px; -} - -.form-group small { - font-size: 14px; - color: #6b7280; - margin-top: 4px; - display: block; -} - /* Clean textarea styling - Dark Theme */ -.input-textarea, textarea { width: 100%; padding: 8px 12px; @@ -472,7 +380,6 @@ textarea { resize: vertical; } -.input-textarea:focus, textarea:focus { outline: none; border-color: var(--accent-primary); @@ -482,80 +389,12 @@ textarea:focus { /* Legacy .btn-primary class - use shadcn Button instead */ /* Etherscan-style argument display */ -.etherscan-args-display { - margin-top: 16px; -} - -.etherscan-args-display .args-header { - font-weight: 600; - background: rgba(59, 130, 246, 0.05); - border-radius: 6px 6px 0 0; - padding: 12px 0 !important; - margin: 0 !important; - border-bottom: 2px solid rgba(59, 130, 246, 0.15) !important; -} - -.etherscan-args-display .arg-row { - border-radius: 0; - transition: background-color 0.2s ease; -} - -.etherscan-args-display .arg-row:hover { - background: rgba(59, 130, 246, 0.02); -} - -.etherscan-args-display .arg-row:last-child { - border-bottom: none !important; - border-radius: 0 0 6px 6px; -} /* Responsive behavior */ -@media (max-width: 768px) { - .etherscan-args-display .args-header, - .etherscan-args-display .arg-row { - grid-template-columns: 1fr !important; - gap: 8px !important; - } - - .etherscan-args-display .args-header span:before { - font-weight: 600; - margin-right: 8px; - } - - .etherscan-args-display .args-header span:nth-child(1):before { - content: "Name: "; - } - - .etherscan-args-display .args-header span:nth-child(2):before { - content: "Type: "; - } - - .etherscan-args-display .args-header span:nth-child(3):before { - content: "Value: "; - } -} /* ========== LEGACY BUTTON CLASSES (for non-shadcn components) ========== */ /* NOTE: All new components should use shadcn Button component directly */ -.decoder-tabs button, -.view-toggle button { - min-height: 36px; - padding: 6px 12px; - font-size: 15px; - border-radius: 4px; - background: hsl(var(--muted)); - color: hsl(var(--muted-foreground)); - border: 1px solid hsl(var(--border)); -} - -.decoder-tabs button.active, -.view-toggle button.active { - background: hsl(var(--primary)); - color: hsl(var(--primary-foreground)); - border-color: hsl(var(--primary)); -} - /* ========== RESULT STYLES ========== */ .result { @@ -598,10 +437,6 @@ textarea:focus { max-width: 100%; } - .app-header { - padding: var(--space-4); - } - .tabs { padding: var(--space-2); } @@ -621,14 +456,6 @@ textarea:focus { .app { padding: var(--space-3); } - - .app-header h1 { - font-size: var(--text-2xl); - } - - .app-header p { - font-size: var(--text-base); - } } /* ========== UTILITY CLASSES ========== */ @@ -649,1717 +476,38 @@ textarea:focus { animation: fadeInUp 0.6s ease-out; } -/* .glow-text removed - no cyber effects */ - /* Segmented control base */ -.segmented-control { - display: inline-flex; - align-items: center; - gap: 4px; -} - -.segmented-control__option { - background: transparent; - border: none; - padding: 0; - cursor: pointer; - font: inherit; - border-radius: 999px; - transition: - color 0.2s ease, - background 0.2s ease, - box-shadow 0.2s ease, - transform 0.2s ease; -} - -.segmented-control__option[disabled] { - cursor: not-allowed; - opacity: 0.5; -} /* ABI mode segmented selector - flat style */ -.abi-source-segmented { - display: inline-flex; - align-items: center; - gap: 4px; - padding: 4px; - border-radius: 8px; - border: 1px solid hsl(var(--border)); - background: hsl(var(--muted) / 0.5); - box-shadow: none; - overflow: hidden; -} - -.abi-source-segmented .segmented-control__option { - background: transparent; - border: none; - border-radius: 6px; - padding: 10px 16px; - font-family: inherit; - display: inline-flex; - align-items: center; - gap: 8px; - font-size: 14px; - font-weight: 500; - letter-spacing: 0.01em; - color: hsl(var(--muted-foreground)); - cursor: pointer; - transition: all 0.15s ease; - min-height: auto; -} - -.abi-source-segmented .segmented-control__option:hover { - color: hsl(var(--foreground)); - background: hsl(var(--accent) / 0.5); -} - -.abi-source-segmented .segmented-control__option:focus-visible { - outline: 2px solid hsl(var(--ring)); - outline-offset: 2px; -} - -.abi-source-segmented .segmented-control__option[data-state="active"] { - background: hsl(var(--primary)); - color: hsl(var(--primary-foreground)); - box-shadow: none; - transform: none; - border-radius: 6px; -} - -.abi-source-segmented .segmented-control__option[data-state="active"]:hover { - color: hsl(var(--primary-foreground)); - background: hsl(var(--primary) / 0.9); -} - -.abi-source-description { - font-size: 12px; - letter-spacing: 0.05em; - text-transform: uppercase; - color: rgba(148, 163, 184, 0.72); - margin-top: 4px; - text-align: center; -} - -.abi-segment-label { - display: flex; - flex-direction: column; - gap: 2px; - line-height: 1.1; - align-items: flex-start; -} - -.abi-segment-label strong { - font-size: 13px; - letter-spacing: 0.02em; - font-weight: 600; - color: inherit; -} - -.abi-segment-label small { - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.08em; - color: rgba(203, 213, 225, 0.7); - transition: color 0.18s ease; -} - -.abi-source-segmented - .segmented-control__option[data-state="active"] - .abi-segment-label - small { - color: rgba(15, 23, 42, 0.65); -} - -.simulation-contract-toggle { - justify-content: flex-start; -} - -.abi-inline-shell { - display: grid; - gap: 18px; - padding: 0; - border-radius: 0; - border: none; - background: transparent; - box-shadow: none; -} - -.abi-inline-shell__header { - display: flex; - flex-direction: column; - gap: 6px; - color: #e2e8f0; -} - -.abi-inline-shell__eyebrow { - font-size: 12px; - letter-spacing: 0.08em; - text-transform: uppercase; - color: #d4d4d4; -} - -.abi-inline-shell__title { - font-size: 19px; - font-weight: 600; - letter-spacing: 0.03em; -} - -.abi-inline-shell__copy { - margin: 0; - font-size: 14px; - color: #94a3b8; - line-height: 1.6; -} - -.abi-inline-shell__selector { - display: flex; - justify-content: center; -} -.abi-inline-shell__description { - font-size: 12px; - letter-spacing: 0.05em; - text-transform: uppercase; - color: rgba(148, 163, 184, 0.75); - text-align: center; -} - -.abi-inline-shell__body { - display: grid; - gap: 20px; -} - -.simulation-hub { - display: grid; - gap: 24px; -} - -.simulation-hub__switch { - display: flex; - justify-content: space-between; - align-items: center; - padding: 14px 18px; - border: 1px solid var(--sim-border, #1f2026); - border-radius: 12px; - background: rgba(12, 12, 18, 0.85); -} - -.simulation-hub__eyebrow { - font-size: 0.7825rem; - letter-spacing: 0.2em; - text-transform: uppercase; - color: var(--sim-text-muted, #9a9aac); -} - -.simulation-hub__title { - margin: 4px 0 0; - font-size: 1rem; - font-weight: 600; - color: var(--sim-text, #f6f6fb); -} - -.simulation-switch { - position: relative; - display: inline-flex; - align-items: center; - cursor: pointer; -} - -.simulation-switch input { - position: absolute; - opacity: 0; - pointer-events: none; -} - -.simulation-switch__track { - --switch-height: 26px; - width: 52px; - height: var(--switch-height); - border-radius: 999px; - background: rgba(5, 5, 10, 0.8); - border: 1px solid rgba(255, 255, 255, 0.08); - position: relative; - transition: background 0.2s ease; -} - -.simulation-switch__track::after { - content: ""; - position: absolute; - top: 50%; - left: 4px; - width: 20px; - height: 20px; - border-radius: 999px; - background: linear-gradient(135deg, #ffffff, #e5e5e5); - box-shadow: 0 6px 18px rgba(255, 255, 255, 0.4); - transform: translate(0, -50%); - transition: transform 0.2s ease; -} +/* ABI section reuses the same field shell; keep variant modifiers minimal */ -.simulation-switch input:checked + .simulation-switch__track::after { - transform: translate(22px, -50%); -} +/* Force network dropdown to show full content */ -.simulation-hub__empty { - padding: 32px; - border: 1px dashed rgba(255, 255, 255, 0.2); - border-radius: 16px; - text-align: center; - color: var(--sim-text-muted, #9a9aac); - background: rgba(7, 8, 13, 0.7); +/* Network dropdown scrollbar styling */ +div[style*="overflowY: auto"]::-webkit-scrollbar { + width: 8px; } -.simulation-hub__empty strong { - display: block; - font-size: 1rem; - color: var(--sim-text, #f6f6fb); +div[style*="overflowY: auto"]::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.2); + border-radius: 4px; } -.simulation-hub__detail { - background: rgba(12, 13, 20, 0.88); +div[style*="overflowY: auto"]::-webkit-scrollbar-thumb { + background: rgba(148, 163, 184, 0.3); + border-radius: 4px; + transition: background 0.2s; } -.simulation-hub__detail-grid { - display: grid; - grid-template-columns: minmax(220px, 280px) 1fr; - gap: 20px; - align-items: stretch; +div[style*="overflowY: auto"]::-webkit-scrollbar-thumb:hover { + background: rgba(148, 163, 184, 0.5); } -@media (max-width: 900px) { - .simulation-hub__detail-grid { - grid-template-columns: 1fr; - } -} - -.simulation-hub__detail-meta { - display: flex; - flex-direction: column; - gap: 12px; - padding: 16px; - border: 1px solid var(--sim-border, #1f2026); - border-radius: 12px; - background: rgba(4, 4, 10, 0.85); -} - -.simulation-hub__detail-meta span { - display: block; - font-size: 0.7825rem; - letter-spacing: 0.15em; - text-transform: uppercase; - color: var(--sim-text-muted, #9a9aac); -} - -.simulation-hub__detail-meta strong { - display: block; - margin-top: 2px; - font-size: 1.0125rem; - color: var(--sim-text, #f6f6fb); -} - -.simulation-hub__code { - margin: 0; - border-radius: 12px; - border: 1px solid var(--sim-border, #1f2026); - background: #07070d; - padding: 16px; - max-height: 320px; - overflow: auto; - font-family: "JetBrains Mono", "SF Mono", monospace; - font-size: 0.9125rem; - line-height: 1.5; -} - -.simulation-hub__panel { - background: rgba(10, 10, 18, 0.82); -} - -.simulation-hub__chips { - display: flex; - flex-wrap: wrap; - gap: 10px; -} - -.simulation-hub__chip { - padding: 6px 14px; - border-radius: 999px; - border: 1px solid rgba(255, 255, 255, 0.12); - font-size: 0.8425rem; - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--sim-text, #f6f6fb); -} - -.simulation-hub__storage { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - gap: 12px; -} - -.simulation-hub__storage > div { - border: 1px solid var(--sim-border, #1f2026); - border-radius: 12px; - padding: 14px; - background: rgba(4, 4, 10, 0.9); -} - -.simulation-hub__storage span { - display: block; - font-size: 0.7625rem; - letter-spacing: 0.1em; - text-transform: uppercase; - color: var(--sim-text-muted, #9a9aac); -} - -.simulation-hub__storage strong { - display: block; - margin: 6px 0; - color: var(--sim-text, #f6f6fb); -} - -.simulation-hub__storage code { - font-family: "JetBrains Mono", "SF Mono", monospace; - font-size: 0.8625rem; - color: var(--sim-text, #f6f6fb); -} - -.decoder-view-wrapper { - display: grid; - gap: 16px; -} - -.decoder-view-shell { - max-width: 520px; - margin: 0 auto; - text-align: center; - padding: 10px 14px; - gap: 0; - border: 0; - background: transparent; - box-shadow: none; -} - -.decoder-view-segmented { - min-width: 0; -} - -.decoder-view-output { - display: grid; - gap: 20px; -} - -.decoder-contract-meta { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 10px; - margin-bottom: 16px; -} - -.decoder-contract-name { - display: inline-flex; - align-items: center; - padding: 6px 16px; - border-radius: 999px; - font-size: 15px; - font-weight: 600; - letter-spacing: 0.04em; - text-transform: uppercase; - background: rgba(148, 163, 184, 0.22); - border: 1px solid rgba(148, 163, 184, 0.38); - color: #f8fafc; - box-shadow: 0 10px 24px rgba(15, 23, 42, 0.28); -} - -.decoder-network-mode { - display: flex; - flex-direction: column; - gap: 12px; -} - -/* .decoder-lookup-segmented moved above to .decoder-advanced-toggle section */ - -.decoder-network-picker { - display: flex; - flex-direction: column; - gap: 8px; -} - -.decoder-address-wrapper { - position: relative; - width: 100%; -} - -.decoder-address-field { - display: flex; - align-items: center; - width: 100%; - min-height: 48px; - gap: 8px; - background: var(--bg-secondary); - border-radius: var(--radius-md); - border: 1px solid var(--border-primary); - transition: - border-color 0.2s ease, - box-shadow 0.2s ease; - padding-right: 0; - overflow: hidden; -} - -.decoder-address-field:focus-within { - border-color: var(--accent-primary); - box-shadow: 0 0 0 1px var(--accent-primary); -} - -.decoder-address-field__input { - flex: 1; - background: transparent; - border: none; - color: var(--text-primary); - font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace; - font-size: 16px; - padding: 12px 8px 12px 14px; - outline: none; -} - -.form-group .decoder-address-field__input { - border: none !important; - background: transparent !important; - padding: 12px 8px 12px 14px !important; - box-shadow: none !important; -} - -.decoder-address-field__input::placeholder { - color: rgba(148, 163, 184, 0.6); -} - -.decoder-address-nudge { - margin: 0 0 18px; - padding: 14px 18px; - border-radius: var(--radius-md); - border: 1px solid rgba(255, 255, 255, 0.32); - background: linear-gradient(120deg, rgba(45, 64, 102, 0.45), rgba(13, 20, 36, 0.85)); - box-shadow: 0 14px 32px rgba(56, 189, 248, 0.14); - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - flex-wrap: wrap; -} - -.decoder-address-nudge__text { - display: flex; - flex-direction: column; - gap: 4px; - color: rgba(226, 232, 240, 0.82); - font-size: 14px; -} - -.decoder-address-nudge__text strong { - font-size: 15px; - letter-spacing: 0.02em; - text-transform: uppercase; - color: #e0e7ff; -} - -.decoder-address-nudge__button { - background: linear-gradient(135deg, rgba(255, 255, 255, 0.98), rgba(56, 189, 248, 0.95)); - border: 1px solid rgba(165, 180, 252, 0.55); - color: #0f172a; - font-weight: 600; - letter-spacing: 0.05em; - text-transform: uppercase; - border-radius: 8px; - padding: 10px 18px; - display: inline-flex; - align-items: center; - gap: 8px; - min-height: auto; - box-shadow: 0 16px 32px rgba(255, 255, 255, 0.28); - transition: transform 0.18s ease, box-shadow 0.18s ease; -} - -.decoder-address-nudge__button:hover { - transform: translateY(-1px); - box-shadow: 0 20px 40px rgba(255, 255, 255, 0.35); -} - -.decoder-address-nudge__button:active { - transform: translateY(0); - box-shadow: 0 10px 20px rgba(255, 255, 255, 0.25); -} - -.decoder-address-field__selector { - flex: 0 0 auto; - display: flex; - align-items: center; - height: 100%; - align-self: stretch; -} - -.decoder-address-field__selector .network-selector__button { - height: 100%; - min-width: 68px; - border-radius: 10px; - background: var(--bg-secondary); - border: 1px solid transparent; - position: relative; -} - -.decoder-address-field__selector:hover .network-selector__button, -.decoder-address-field__selector:focus-within .network-selector__button { - background: rgba(148, 163, 184, 0.12); -} - -.decoder-address-field__badge { - flex: 0 0 auto; - display: inline-flex; - align-items: center; - justify-content: center; - padding: 6px 14px; - border-radius: 10px; - font-size: 12px; - font-weight: 600; - letter-spacing: 0.08em; - text-transform: uppercase; - background: rgba(59, 130, 246, 0.16); - border: 1px solid rgba(59, 130, 246, 0.35); - color: rgba(191, 219, 254, 0.88); -} - -/* ABI section reuses the same field shell; keep variant modifiers minimal */ - -.decoder-address-field__input--abi { - font-family: "JetBrains Mono", "Fira Code", monospace; - font-size: 14px; - color: var(--text-primary); - padding: 12px 14px; -} - -.decoder-address-field__badge--abi { - background: rgba(229, 229, 229, 0.18); - border-color: rgba(229, 229, 229, 0.35); - color: rgba(226, 232, 240, 0.95); -} - -.decoder-network-picker .network-selector { - max-width: 320px; -} - -.network-dropdown__header { - padding: 12px 16px; - border-bottom: 1px solid rgba(148, 163, 184, 0.16); - background: rgba(12, 18, 32, 0.7); - display: flex; - flex-direction: column; - align-items: center; - gap: 12px; - text-align: center; - min-height: fit-content !important; - flex-shrink: 0; -} - -/* Force network dropdown to show full content */ -.network-dropdown-menu-visible { - min-height: 450px !important; - height: auto !important; - max-height: 70vh !important; - overflow-y: auto !important; - display: block !important; -} - -.decoder-address-field__selector > div > div[style*="position: absolute"] { - min-height: 400px !important; - height: auto !important; - max-height: 70vh !important; -} - -.network-dropdown__metrics span { - font-size: 13px; - letter-spacing: 0.02em; - color: rgba(203, 213, 225, 0.8); -} - -.network-category-group { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; -} - -.network-category-group__label { - font-size: 12px; - text-transform: uppercase; - letter-spacing: 0.08em; - color: rgba(148, 163, 184, 0.85); -} - -.network-category-toggle { - display: inline-flex; - align-items: stretch; - border-radius: 6px; - border: 1px solid rgba(255, 255, 255, 0.38); - background: linear-gradient(135deg, rgba(12, 19, 33, 0.92), rgba(20, 27, 46, 0.96)); - box-shadow: 0 10px 24px rgba(56, 189, 248, 0.12); - overflow: hidden; - margin: 0 auto; - flex-shrink: 0; -} - -.network-category-toggle__option { - position: relative; - background: transparent; - border: none; - padding: 9px 18px; - font-size: 12px; - font-weight: 600; - letter-spacing: 0.08em; - text-transform: uppercase; - color: rgba(226, 232, 240, 0.72); - display: inline-flex; - align-items: center; - gap: 10px; - cursor: pointer; - transition: - background 0.18s ease, - color 0.18s ease, - box-shadow 0.18s ease, - transform 0.18s ease; - border-right: 1px solid rgba(255, 255, 255, 0.22); - flex: 0 1 132px; - justify-content: center; - min-width: 116px; -} - -.network-category-toggle__option:focus-visible { - outline: 2px solid rgba(148, 163, 184, 0.45); - outline-offset: 2px; -} - -.network-category-toggle__option:last-of-type { - border-right: none; -} - -.network-category-toggle__option.is-active { - background: linear-gradient(135deg, #ffffff, #e5e5e5); - color: #0f172a; - box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.2), 0 14px 30px rgba(56, 189, 248, 0.2); - transform: translateY(0); -} - -.network-category-toggle__option:hover { - color: rgba(241, 245, 249, 0.9); -} - -.network-category-toggle__option.is-active:hover { - color: #0f172a; - box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.25), 0 20px 40px rgba(56, 189, 248, 0.28); -} - -.network-category-toggle__label { - display: inline-flex; - align-items: center; - gap: 8px; -} - -.network-category-toggle__status { - width: 7px; - height: 7px; - border-radius: 50%; - background: rgba(148, 163, 184, 0.45); - box-shadow: 0 0 8px rgba(148, 163, 184, 0.45); - transition: box-shadow 0.2s ease, opacity 0.2s ease; -} - -.network-category-toggle__status--live { - background: linear-gradient(135deg, #34d399, #22c55e); - box-shadow: 0 0 10px rgba(34, 197, 94, 0.5); -} - -.network-category-toggle__status--testnet { - background: linear-gradient(135deg, #facc15, #f97316); - box-shadow: 0 0 10px rgba(249, 115, 22, 0.45); -} - -.network-category-toggle__option:not(.is-active) .network-category-toggle__status { - opacity: 0.7; -} - -/* Network dropdown scrollbar styling */ -div[style*="overflowY: auto"]::-webkit-scrollbar { - width: 8px; -} - -div[style*="overflowY: auto"]::-webkit-scrollbar-track { - background: rgba(0, 0, 0, 0.2); - border-radius: 4px; -} - -div[style*="overflowY: auto"]::-webkit-scrollbar-thumb { - background: rgba(148, 163, 184, 0.3); - border-radius: 4px; - transition: background 0.2s; -} - -div[style*="overflowY: auto"]::-webkit-scrollbar-thumb:hover { - background: rgba(148, 163, 184, 0.5); -} - -.signature-tabs { - margin-bottom: 24px; - display: flex; - justify-content: center; -} - -.signature-tabs__control { - display: inline-flex; - padding: 4px; - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.36); - background: linear-gradient(130deg, rgba(21, 32, 59, 0.85), rgba(14, 23, 42, 0.92)); - box-shadow: 0 16px 32px rgba(56, 189, 248, 0.16); - gap: 0; -} - -.signature-tabs__control .segmented-control__option { - padding: 12px 20px; - border-radius: 0; - background: transparent; - border: none; - color: rgba(226, 232, 240, 0.78); - min-width: 140px; - justify-content: center; - transition: background 0.18s ease, color 0.18s ease, box-shadow 0.2s ease; -} - -.signature-tabs__control .segmented-control__option + .segmented-control__option { - border-left: 1px solid rgba(255, 255, 255, 0.22); -} - -.signature-tabs__control .segmented-control__option[data-state="active"] { - background: linear-gradient(135deg, #ffffff, #e5e5e5); - color: #0f172a; - box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.2), 0 18px 34px rgba(56, 189, 248, 0.25); - transform: translateY(0); -} - -.signature-tabs__control .segmented-control__option[data-state="active"] .signature-tabs__label small { - color: rgba(15, 23, 42, 0.75); -} - -.signature-tabs__control .segmented-control__option[data-state="active"]:hover { - box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.25), 0 22px 40px rgba(56, 189, 248, 0.32); -} - -.signature-tabs__control .segmented-control__option:hover { - color: rgba(241, 245, 249, 0.92); -} - -.signature-tabs__label { - display: flex; - flex-direction: column; - align-items: center; - gap: 2px; - line-height: 1; - text-transform: uppercase; -} - -.signature-tabs__label strong { - font-size: 13px; - letter-spacing: 0.08em; -} - -.signature-tabs__label small { - font-size: 11px; - letter-spacing: 0.12em; - color: rgba(203, 213, 225, 0.75); -} - -.decoder-network-picker small, -.decoder-network-help { - font-size: 14px; - color: rgba(148, 163, 184, 0.85); -} - -.decoder-contract-badge { - display: inline-flex; - align-items: center; - gap: 4px; - padding: 4px 10px; - border-radius: 999px; - background: rgba(229, 229, 229, 0.12); - color: rgba(148, 163, 184, 0.92); - font-size: 12px; - letter-spacing: 0.08em; - text-transform: uppercase; - border: 1px solid rgba(255, 255, 255, 0.32); - transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease; -} - -.decoder-contract-badge--source { - background: rgba(59, 130, 246, 0.18); - border-color: rgba(59, 130, 246, 0.42); - color: rgba(191, 219, 254, 0.95); -} - -.decoder-contract-badge:hover { - background: rgba(56, 189, 248, 0.16); - color: #e0f2fe; - border-color: rgba(56, 189, 248, 0.35); -} - -.abi-inline-sheet__form { - display: grid; - gap: 14px; - border: 1px solid var(--border-primary); - border-radius: 14px; - padding: 18px; - background: var(--bg-glass); - box-shadow: none; -} - -.abi-inline-sheet__label { - font-size: 13px; - letter-spacing: 0.08em; - text-transform: uppercase; - color: #c7d2fe; -} - -.abi-inline-sheet__input { - width: 100%; - padding: 12px 14px; - border-radius: 12px; - border: 1px solid var(--border-primary); - background: var(--bg-secondary); - color: var(--text-primary); - font-family: "JetBrains Mono", "Fira Code", monospace; - font-size: 14px; - transition: - border-color 0.2s ease, - box-shadow 0.2s ease; -} - -.abi-inline-sheet__input::placeholder { - color: rgba(148, 163, 184, 0.6); -} - -.abi-inline-sheet__input:focus { - outline: none; - border-color: rgba(229, 229, 229, 0.7); - box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25); -} - -.abi-inline-sheet__button { - width: 100%; - justify-content: center; -} - -.abi-inline-sheet__button .glass-button-text { - font-size: 16px; -} - -.abi-inline-sheet__hint { - font-size: 12px; - color: #e5e5e5; - line-height: 1.6; -} - -.abi-local-block { - border: 1px solid rgba(148, 163, 184, 0.24); - background: rgba(15, 23, 42, 0.5); - border-radius: 10px; - padding: 16px; - transition: - border-color 0.2s ease, - box-shadow 0.2s ease, - background 0.2s ease; -} - -.abi-local-block.is-active { - border-color: rgba(229, 229, 229, 0.6); - box-shadow: 0 0 0 1px rgba(229, 229, 229, 0.35); - background: rgba(30, 41, 59, 0.65); -} - -.abi-local-header { - display: flex; - justify-content: space-between; - align-items: center; - gap: 12px; - margin-bottom: 8px; -} - -.abi-local-actions { - display: inline-flex; - align-items: center; - gap: 12px; -} - -.inline-copy-icon.abi-inline-upload { - background: transparent; - color: rgba(148, 163, 184, 0.82); - box-shadow: none; - border-radius: 8px; - transition: - color 0.18s ease, - transform 0.18s ease, - outline 0.18s ease; -} - -.inline-copy-icon.abi-inline-upload:hover { - color: #d4d4d4; - transform: translateY(-1px); -} - -.inline-copy-icon.abi-inline-upload:focus-visible { - color: #cbd5f5; - outline: 2px solid rgba(125, 211, 252, 0.65); - outline-offset: 2px; -} - -@media (max-width: 640px) { - .abi-source-segmented { - width: 100%; - justify-content: center; - flex-wrap: wrap; - } - - .abi-source-segmented .segmented-control__option { - flex: 1 1 50%; - text-align: center; - } - - .abi-inline-shell { - padding: 16px; - } - - .abi-inline-shell__body { - gap: 16px; - } -} -.decoder-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: 20px; - margin-bottom: 20px; -} - -.decoder-headline h2 { - margin: 0 0 6px 0; -} - -.decoder-headline p { - margin: 0; - color: rgba(203, 213, 225, 0.85); -} - -.decoder-settings-button { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 10px 18px; - border-radius: 999px; - border: 1px solid rgba(147, 197, 253, 0.4); - background: linear-gradient(135deg, rgba(59, 130, 246, 0.25), rgba(14, 165, 233, 0.25)); - color: rgba(226, 232, 240, 0.95); - font-size: 14px; - letter-spacing: 0.08em; - text-transform: uppercase; - cursor: pointer; - transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, background 0.18s ease; - backdrop-filter: blur(14px); - -webkit-backdrop-filter: blur(14px); -} - -.decoder-settings-button:hover, -.decoder-settings-button.is-active { - background: linear-gradient(135deg, rgba(59, 130, 246, 0.35), rgba(14, 165, 233, 0.35)); - border-color: rgba(191, 219, 254, 0.6); - box-shadow: 0 14px 32px rgba(59, 130, 246, 0.35); - transform: translateY(-1px); -} - -.decoder-settings-icon { - display: inline-flex; -} - -.decoder-settings-button svg { - width: 16px; - height: 16px; - stroke: currentColor; -} - -.decoder-settings-arrow { - font-size: 13px; - opacity: 0.85; -} - -.decoder-settings-trigger { - background: transparent; - border: none; - color: rgba(191, 219, 254, 0.8); - cursor: pointer; - padding: 4px; - border-radius: 10px; - transition: color 0.18s ease, background 0.18s ease, transform 0.18s ease; -} - -.decoder-settings-trigger:hover, -.decoder-settings-trigger:focus-visible { - color: rgba(244, 244, 255, 0.98); - background: rgba(59, 130, 246, 0.2); - outline: none; - transform: translateY(-1px); -} - -.decoder-settings-overlay { - position: fixed; - inset: 0; - pointer-events: none; - z-index: 1100; -} - -.decoder-settings-overlay::before { - content: ''; - position: absolute; - inset: 0; - background: radial-gradient(circle at center, rgba(14, 116, 144, 0.16), rgba(2, 6, 23, 0.88)); -} - -.decoder-settings-overlay.active { - pointer-events: auto; -} - -.decoder-settings-modal { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: min(480px, calc(100% - 36px)); - background: rgba(13, 23, 44, 0.92); - border: 1px solid rgba(59, 130, 246, 0.2); - border-radius: 18px; - padding: 24px; - box-shadow: 0 32px 60px rgba(5, 12, 28, 0.55); - color: rgba(226, 232, 240, 0.95); -} - -.decoder-settings-modal-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: 16px; - margin-bottom: 18px; -} - -.decoder-settings-modal-header p { - margin: 0; - font-size: 17px; - font-weight: 600; - letter-spacing: 0.04em; - text-transform: uppercase; - color: rgba(191, 219, 254, 0.95); -} - -.decoder-settings-modal-header span { - display: block; - font-size: 14px; - color: rgba(148, 163, 184, 0.75); - margin-top: 4px; -} - -.decoder-settings-close { - background: rgba(15, 23, 42, 0.6); - border: 1px solid rgba(148, 163, 184, 0.25); - border-radius: 10px; - padding: 6px; - color: rgba(226, 232, 240, 0.85); - cursor: pointer; - transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease; -} - -.decoder-settings-close:hover, -.decoder-settings-close:focus-visible { - background: rgba(59, 130, 246, 0.25); - border-color: rgba(191, 219, 254, 0.45); - outline: none; - transform: translateY(-1px); -} - -.decoder-advanced-panel { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); - gap: 12px; - padding: 16px; - background: rgba(30, 41, 59, 0.45); - border: 1px solid rgba(59, 130, 246, 0.18); - border-radius: 12px; - margin-bottom: 18px; - box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.35); -} - -.decoder-advanced-title { - grid-column: 1 / -1; - margin: 0; - font-size: 13px; - letter-spacing: 0.08em; - text-transform: uppercase; - color: rgba(191, 219, 254, 0.7); -} - -.decoder-lookup-segmented { - width: fit-content; - max-width: 320px; - flex-shrink: 0; -} - -.decoder-advanced-toggle { - display: grid; - grid-template-columns: auto minmax(0, 1fr) auto; - align-items: center; - gap: 16px; - padding: 14px 16px; - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.28); - background: rgba(17, 24, 39, 0.65); - color: rgba(226, 232, 240, 0.9); - font-size: 14px; - transition: border-color 0.18s ease, background 0.18s ease; -} - -.decoder-advanced-toggle .decoder-advanced-icon { - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.decoder-advanced-toggle .decoder-advanced-text { - min-width: 0; - overflow-wrap: break-word; - word-break: break-word; - display: flex; - flex-direction: column; - gap: 4px; -} - -.decoder-advanced-toggle .decoder-advanced-text strong { - display: block; - font-weight: 600; - color: rgba(226, 232, 240, 0.95); -} - -.decoder-advanced-toggle .decoder-advanced-text small { - display: block; - font-size: 12px; - color: rgba(148, 163, 184, 0.75); - line-height: 1.4; -} - -.decoder-advanced-toggle .decoder-lookup-segmented { - flex-shrink: 0; - min-width: fit-content; - max-width: 320px; - grid-column: 3; -} - -@media (max-width: 768px) { - .decoder-advanced-toggle { - grid-template-columns: 1fr; - gap: 12px; - } - - .decoder-advanced-toggle .decoder-lookup-segmented { - max-width: 100%; - width: 100%; - grid-column: 1; - } -} - -.decoder-advanced-toggle:hover { - border-color: rgba(147, 197, 253, 0.45); - background: rgba(30, 41, 59, 0.75); -} - -.decoder-advanced-toggle label { - cursor: pointer; -} - -.decoder-advanced-toggle input { - width: 18px; - height: 18px; - cursor: pointer; -} - -.decoder-advanced-icon svg { - width: 16px; - height: 16px; -} - -.decoder-advanced-text { - display: flex; - flex-direction: column; - gap: 2px; -} - -.decoder-advanced-text small { - font-size: 13px; - color: rgba(148, 163, 184, 0.82); -} -.signature-copy-button.inline-copy-icon { - --inline-copy-size: 30px; - background: transparent !important; - border: none !important; - color: rgba(226, 232, 240, 0.82); - box-shadow: none !important; - transform: none !important; -} - -.signature-copy-button.inline-copy-icon:hover:not([aria-disabled="true"]), -.signature-copy-button.inline-copy-icon:focus-visible { - background: transparent !important; - color: #f8fafc; - transform: none !important; -} - -.signature-copy-button.inline-copy-icon[data-state="copied"] { - background: transparent !important; - color: #34d399; - transform: none !important; -} - -.signature-copy-button.inline-copy-icon[data-state="error"] { - background: transparent !important; - color: #f87171; - transform: none !important; -} - -.signature-inline-action.inline-action-icon { - --inline-copy-size: 30px; - background: transparent !important; - border: none !important; - color: rgba(148, 163, 184, 0.75); - box-shadow: none !important; - transform: none !important; -} - -.signature-inline-action.inline-action-icon:hover, -.signature-inline-action.inline-action-icon:focus-visible { - background: transparent !important; - color: rgba(248, 250, 252, 0.92); - transform: none !important; -} - -/* RPC Settings Button */ -/* Modal Base Styles */ -.modal-overlay { - position: fixed; - inset: 0; - z-index: 2000; - display: flex; - align-items: center; - justify-content: center; - padding: 24px; - background: radial-gradient(circle at center, rgba(15, 23, 42, 0.78), rgba(2, 6, 23, 0.92)); - backdrop-filter: blur(20px); - overflow-y: auto; -} - -.modal-content { - width: min(520px, 100%); - background: rgba(13, 23, 44, 0.92); - border-radius: 18px; - border: 1px solid rgba(59, 130, 246, 0.25); - box-shadow: 0 28px 60px rgba(3, 7, 18, 0.6); - padding: 28px; - color: rgba(226, 232, 240, 0.95); - max-height: calc(100vh - 48px); - overflow: hidden auto; -} - -@media (max-width: 640px) { - .modal-content { - padding: 22px; - } -} - -.modal-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: var(--space-4); -} - -.modal-header h3 { - margin: 0; - font-size: 21px; - font-weight: 600; - letter-spacing: 0.05em; - text-transform: uppercase; -} - -.modal-close { - background: none; - border: none; - border-radius: 999px; - color: rgba(226, 232, 240, 0.82); - cursor: pointer; - transition: color var(--transition-fast), transform var(--transition-fast); - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0; - font-size: 21px; -} - -.modal-close:hover, -.modal-close:focus-visible { - outline: none; - color: rgba(248, 250, 252, 0.95); - transform: translateY(-1px); -} - -.modal-body { - display: flex; - flex-direction: column; - gap: var(--space-4); - color: rgba(203, 213, 225, 0.9); -} - -.modal-footer { - display: flex; - justify-content: flex-end; - gap: var(--space-3); - margin-top: var(--space-5); -} - -.form-group { - display: flex; - flex-direction: column; - gap: var(--space-2); -} - -.form-group label { - font-size: var(--text-sm); - letter-spacing: 0.08em; - text-transform: uppercase; - color: rgba(191, 219, 254, 0.9); -} - -.form-group input { - background: rgba(15, 23, 42, 0.7); - border: 1px solid rgba(148, 163, 184, 0.35); - border-radius: 12px; - padding: 12px 14px; - color: rgba(226, 232, 240, 0.95); - font-family: var(--font-mono); - transition: border var(--transition-fast), box-shadow var(--transition-fast); -} - -.form-group input:focus { - outline: none; - border-color: rgba(56, 189, 248, 0.6); - box-shadow: 0 0 0 2px rgba(56, 189, 248, 0.25); -} - -.form-error { - font-size: var(--text-sm); - color: var(--error); -} - -.form-hint { - font-size: var(--text-sm); - color: rgba(148, 163, 184, 0.85); -} +/* RPC Settings Button */ +/* Modal Base Styles */ /* RPC Settings Popover */ -.rpc-settings-popover { - position: fixed; - top: clamp(56px, 4.5vh, 84px); - right: clamp(12px, 2.5vw, 40px); - width: min(400px, calc(100vw - 24px)); - background: rgba(9, 14, 28, 0.96); - border: 1px solid rgba(59, 130, 246, 0.3); - border-radius: 14px; - box-shadow: 0 20px 60px rgba(2, 6, 23, 0.58); - padding: 18px; - backdrop-filter: blur(24px); - z-index: 2200; - color: rgba(226, 232, 240, 0.95); - font-size: 1.0125rem; -} - -.rpc-settings-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: var(--space-3); -} - -.rpc-settings-eyebrow { - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.25em; - color: rgba(148, 163, 184, 0.8); - margin: 0 0 2px; -} - -.rpc-settings-header h3 { - margin: 0; - font-size: 19px; - letter-spacing: 0.06em; - text-transform: uppercase; -} - -.rpc-settings-actions { - display: flex; - align-items: center; - gap: var(--space-2); -} - -.rpc-autosave { - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.1em; - border-radius: 999px; - padding: 3px 8px; - border: 1px solid rgba(148, 163, 184, 0.35); - color: rgba(203, 213, 225, 0.92); - background: rgba(15, 23, 42, 0.55); -} - -.rpc-autosave--saving { - color: #fbbf24; - border-color: rgba(251, 191, 36, 0.5); - background: rgba(251, 191, 36, 0.08); -} - -.rpc-autosave--saved { - color: #34d399; - border-color: rgba(52, 211, 153, 0.5); - background: rgba(16, 185, 129, 0.12); -} - -.rpc-autosave--error { - color: #f87171; - border-color: rgba(248, 113, 113, 0.65); - background: rgba(248, 113, 113, 0.08); -} - -.rpc-popover-close.inline-copy-icon { - color: rgba(226, 232, 240, 0.8); - transition: color var(--transition-fast), transform var(--transition-fast); -} - -.rpc-popover-close.inline-copy-icon:hover, -.rpc-popover-close.inline-copy-icon:focus-visible { - color: rgba(248, 250, 252, 0.95); - transform: translateY(-1px); -} - -.rpc-settings-description { - margin: var(--space-2) 0 var(--space-3); - color: rgba(203, 213, 225, 0.85); - line-height: 1.45; -} - -.rpc-settings-card { - border: 1px solid rgba(59, 130, 246, 0.18); - border-radius: 14px; - padding: 14px; - background: rgba(13, 23, 44, 0.8); - display: flex; - flex-direction: column; - gap: var(--space-2); -} - -.rpc-provider-control { - display: flex; - width: 100%; - flex-wrap: wrap; - gap: var(--space-2); -} - -.rpc-provider-control .segmented-control__option { - flex: 1 1 calc(50% - var(--space-2)); - min-width: 170px; - padding: 9px 11px; - border-radius: 11px; - border: 1px solid rgba(59, 130, 246, 0.18); - background: rgba(15, 23, 42, 0.65); - color: rgba(226, 232, 240, 0.88); - text-align: left; - white-space: normal; -} - -.rpc-provider-control .segmented-control__option:hover { - border-color: rgba(56, 189, 248, 0.35); - color: rgba(248, 250, 252, 0.95); - transform: translateY(-1px); -} - -.rpc-provider-control .segmented-control__option[data-state="active"] { - border-color: rgba(56, 189, 248, 0.65); - background: rgba(37, 99, 235, 0.22); - box-shadow: 0 10px 24px rgba(2, 132, 199, 0.25); - color: rgba(248, 250, 252, 0.98); -} - -.rpc-segment-label { - display: inline-flex; - flex-direction: column; - align-items: flex-start; - gap: 4px; - text-transform: uppercase; -} - -.rpc-segment-label strong { - letter-spacing: 0.08em; - font-size: 13px; -} - -.rpc-segment-label small { - letter-spacing: 0.1em; - font-size: 11px; - color: rgba(148, 163, 184, 0.85); -} - -.rpc-provider-details h4 { - margin: 0 0 4px; - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.16em; - color: rgba(148, 163, 184, 0.9); -} - -.rpc-provider-details p { - margin: 0; - color: rgba(226, 232, 240, 0.95); - line-height: 1.45; -} - -.rpc-provider-hint { - margin-top: 10px; - font-size: 13px; - color: rgba(148, 163, 184, 0.85); - background: rgba(15, 23, 42, 0.6); - border: 1px solid rgba(148, 163, 184, 0.25); - border-radius: 10px; - padding: 8px 10px; -} - -.rpc-input-card { - margin-top: var(--space-3); - border: 1px solid rgba(148, 163, 184, 0.2); - border-radius: 12px; - padding: 12px; - background: rgba(11, 17, 33, 0.85); - display: flex; - flex-direction: column; - gap: var(--space-2); -} - -.rpc-input-card label { - font-size: 11px; - letter-spacing: 0.14em; - text-transform: uppercase; - color: rgba(191, 219, 254, 0.9); -} - -.rpc-input-field { - position: relative; - width: 100%; -} - -.rpc-input-card input { - width: 100%; - background: rgba(7, 12, 25, 0.85); - border: 1px solid rgba(148, 163, 184, 0.35); - border-radius: 10px; - padding: 9px 40px 9px 11px; - color: rgba(226, 232, 240, 0.95); - font-family: var(--font-mono); - transition: border var(--transition-fast), box-shadow var(--transition-fast); -} - -.rpc-input-field--no-toggle input { - padding-right: 12px; -} - -.rpc-input-toggle.inline-copy-icon { - position: absolute; - top: 50%; - right: 6px; - transform: translateY(-55%); - color: rgba(148, 163, 184, 0.85); - transition: color var(--transition-fast); -} - -.rpc-input-toggle.inline-copy-icon:hover, -.rpc-input-toggle.inline-copy-icon:focus-visible { - color: rgba(248, 250, 252, 0.98); -} - -.rpc-input-card input:focus { - outline: none; - border-color: rgba(56, 189, 248, 0.6); - box-shadow: 0 0 0 2px rgba(56, 189, 248, 0.25); -} - -.rpc-input-card p { - margin: 0; - color: rgba(203, 213, 225, 0.9); - line-height: 1.5; -} - -.rpc-support { - border-top: 1px solid rgba(148, 163, 184, 0.2); - padding-top: var(--space-2); - display: flex; - flex-direction: column; - gap: 6px; -} - -.rpc-support > span { - text-transform: uppercase; - letter-spacing: 0.16em; - font-size: 11px; - color: rgba(148, 163, 184, 0.8); -} - -.rpc-support-grid { - display: flex; - flex-wrap: wrap; - gap: 6px; -} - -.rpc-support-chip { - padding: 2px 7px; - border-radius: 999px; - background: rgba(59, 130, 246, 0.1); - border: 1px solid rgba(59, 130, 246, 0.35); - font-size: 10px; - letter-spacing: 0.05em; - text-transform: uppercase; - color: rgba(226, 232, 240, 0.9); -} - -@media (max-width: 768px) { - .rpc-settings-popover { - left: 16px; - right: 16px; - top: 64px; - padding: 16px; - width: auto; - transform-origin: top center; - } - - .rpc-provider-control .segmented-control__option { - min-width: 100%; - flex-basis: 100%; - } -} /* ============================================ WEB3MODAL CUSTOM STYLING diff --git a/src/components/InlineFacetLoader.tsx b/src/components/InlineFacetLoader.tsx index e7eaa15..13a5f0b 100644 --- a/src/components/InlineFacetLoader.tsx +++ b/src/components/InlineFacetLoader.tsx @@ -6,7 +6,7 @@ import { } from "../utils/diamondFacetFetcher"; import { networkConfigManager } from "../config/networkConfig"; import type { Chain } from "../types"; -import { UIIcons } from "./icons/IconMap"; +import { ArrowClockwise } from "@phosphor-icons/react"; import { Button } from "./ui/button"; interface InlineFacetLoaderProps { @@ -445,7 +445,7 @@ export const InlineFacetLoader: React.FC = ({ color: "#60a5fa", }} > - + {abbreviate(currentFacetEntry.address)} )} diff --git a/src/components/SimpleGridUI.tsx b/src/components/SimpleGridUI.tsx deleted file mode 100644 index 4bb6e2c..0000000 --- a/src/components/SimpleGridUI.tsx +++ /dev/null @@ -1,16 +0,0 @@ -/** - * SimpleGridUI - Thin re-export from the simple-grid sub-module. - * - * The monolithic component has been decomposed into: - * src/components/simple-grid/SimpleGridMain.tsx - Core logic & state orchestrator - * src/components/simple-grid/ContractCardSection.tsx - Contract address/ABI/info UI - * src/components/simple-grid/FunctionSelectorSection.tsx - Function type & search UI - * src/components/simple-grid/FunctionDropdownSection.tsx - Function dropdown, params, execution - * src/components/simple-grid/RawCalldataSection.tsx - Raw calldata input/decode/execute - * src/components/simple-grid/DiamondLoaderSection.tsx - Diamond facet progress UI - * src/components/simple-grid/GridContext.tsx - Internal context for sub-component communication - * src/components/simple-grid/tokenDetectionHelpers.ts - Pure token detection functions - * src/components/simple-grid/utils.ts - Pure utility functions - * src/components/simple-grid/types.ts - Shared type definitions - */ -export { SimpleGridUI as default } from "./simple-grid"; diff --git a/src/components/SmartDecoder.tsx b/src/components/SmartDecoder.tsx deleted file mode 100644 index dd3ea5b..0000000 --- a/src/components/SmartDecoder.tsx +++ /dev/null @@ -1,3 +0,0 @@ -// Re-export SmartDecoder from the smart-decoder submodule. -// This file exists for backward compatibility with existing imports. -export { SmartDecoder as default } from './smart-decoder'; diff --git a/src/components/TransactionBuilderHub.tsx b/src/components/TransactionBuilderHub.tsx index 6aa6ca2..a034d6d 100644 --- a/src/components/TransactionBuilderHub.tsx +++ b/src/components/TransactionBuilderHub.tsx @@ -13,7 +13,7 @@ type BuilderIntentMode = "live" | "simulation" | "replay"; const TXHASH_REPLAY_KEY = 'web3-toolkit:txhash-replay'; -const loadSimpleGridUI = () => import("./SimpleGridUI"); +const loadSimpleGridUI = () => import("./simple-grid"); const loadTransactionBuilderWagmi = () => import("./TransactionBuilderWagmi"); const SimpleGridUI = React.lazy(loadSimpleGridUI); diff --git a/src/components/TransactionBuilderWagmi.tsx b/src/components/TransactionBuilderWagmi.tsx index 749b20c..d9b1c21 100644 --- a/src/components/TransactionBuilderWagmi.tsx +++ b/src/components/TransactionBuilderWagmi.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react"; import { useLocation } from "react-router-dom"; import { LayoutTransitionWrapper } from "./ui/animated-tabs"; import { ethers } from "ethers"; -import SimpleGridUI from "./SimpleGridUI"; +import SimpleGridUI from "./simple-grid"; import { EXTENDED_NETWORKS } from "./shared/NetworkSelector"; import { SUPPORTED_CHAINS } from "../utils/chains"; import { useSimulation } from "../contexts/SimulationContext"; @@ -13,15 +13,12 @@ import { TXHASH_REPLAY_EVENT, TXHASH_REPLAY_LAST_INTENT_KEY, } from "./transaction-builder/types"; -import { SimulationReplayResults } from "./transaction-builder/SimulationReplayResults"; import { TransactionReplayView } from "./transaction-builder/TransactionReplayView"; import { renderModeToggle } from "./transaction-builder/renderModeToggle"; import { attemptCalldataDecodeNotification } from "./transaction-builder/calldataDecodeNotification"; import "../styles/SharedComponents.css"; -import "../styles/SimulatorWorkbench.css"; // Re-export public API so existing consumers are not broken -export { SimulationReplayResults } from "./transaction-builder/SimulationReplayResults"; export { TXHASH_REPLAY_KEY, TXHASH_REPLAY_EVENT, diff --git a/src/components/contract/ContractAddressInput.tsx b/src/components/contract/ContractAddressInput.tsx index e5df2c1..b1932f0 100644 --- a/src/components/contract/ContractAddressInput.tsx +++ b/src/components/contract/ContractAddressInput.tsx @@ -10,7 +10,6 @@ import NetworkSelector, { type ExtendedChain, } from "../shared/NetworkSelector"; import type { Chain } from "../../types"; -import "@/styles/ContractComponents.css"; import { cn } from "@/lib/utils"; const DEFAULT_NATIVE_CURRENCY = { diff --git a/src/components/debug/DebugWindow.tsx b/src/components/debug/DebugWindow.tsx index 9d86b19..1a848e0 100644 --- a/src/components/debug/DebugWindow.tsx +++ b/src/components/debug/DebugWindow.tsx @@ -7,7 +7,7 @@ import { ResizablePanel, ResizablePanelGroup, } from '../ui/resizable'; -import { useDebug, DebugProvider } from '../../contexts/DebugContext'; +import { useDebug } from '../../contexts/DebugContext'; import { useSimulation } from '../../contexts/SimulationContext'; import DebugToolbar from './DebugToolbar'; import SourceViewPanel from './SourceViewPanel'; @@ -392,20 +392,8 @@ const DebugWindowInner: React.FC = React.memo(({ className }) DebugWindowInner.displayName = 'DebugWindowInner'; -export const DebugWindow: React.FC = React.memo((props) => { - return ( - - - - ); -}); - -DebugWindow.displayName = 'DebugWindow'; - export const DebugWindowWithContext: React.FC = React.memo((props) => { return ; }); DebugWindowWithContext.displayName = 'DebugWindowWithContext'; - -export default DebugWindow; diff --git a/src/components/explorer/StorageCells.tsx b/src/components/explorer/StorageCells.tsx index ef5ca5a..5cae6ce 100644 --- a/src/components/explorer/StorageCells.tsx +++ b/src/components/explorer/StorageCells.tsx @@ -1,7 +1,5 @@ import React from 'react'; -import { Database, Hash, Shield, BracketsCurly, WarningCircle } from '@phosphor-icons/react'; import { middleTruncate } from './storageViewerHelpers'; -import type { ResolvedSlot } from './storageViewerTypes'; export const CopyableCell: React.FC<{ value: string; @@ -80,12 +78,3 @@ export const ClickableValue: React.FC<{ ); }; -export function DecodeKindIcon({ kind }: { kind: ResolvedSlot['decodeKind'] }) { - switch (kind) { - case 'exact': return ; - case 'derived': return ; - case 'proxy_slot': return ; - case 'namespace_root': return ; - case 'unknown': return ; - } -} diff --git a/src/components/explorer/storage-viewer/fetchStorageLayout.ts b/src/components/explorer/storage-viewer/fetchStorageLayout.ts index 5bebb94..04f1184 100644 --- a/src/components/explorer/storage-viewer/fetchStorageLayout.ts +++ b/src/components/explorer/storage-viewer/fetchStorageLayout.ts @@ -69,20 +69,6 @@ function extractSources(data: Record): { return { files, contractName, compilerVersion }; } -/** - * Fetch storage layout from Sourcify V2 API. - * Uses the shared cache to avoid redundant requests. - */ -export async function fetchStorageLayoutFromSourcify( - chainId: number, - address: string, - signal?: AbortSignal -): Promise { - const data = await fetchSourcifyV2Cached(chainId, address, ['storageLayout'], signal); - if (!data) return null; - return extractStorageLayout(data); -} - /** * Fetch source files from Sourcify V2 API for AST-based reconstruction. * Uses the shared cache to avoid redundant requests. diff --git a/src/components/explorer/storageViewerHelpers.ts b/src/components/explorer/storageViewerHelpers.ts index 48fa7eb..a83e721 100644 --- a/src/components/explorer/storageViewerHelpers.ts +++ b/src/components/explorer/storageViewerHelpers.ts @@ -11,7 +11,7 @@ export function shortHex(hex: string, head = 8, tail = 6): string { /** Clean variable labels for display -- keep mapping signatures, strip simple type suffixes */ export function cleanLabel(label: string): string { // Strip "[base slot]" suffix - let cleaned = label.replace(/\s*\[base slot\]$/, ''); + const cleaned = label.replace(/\s*\[base slot\]$/, ''); // For mappings: "s.foo (mapping(address -> bool))" -> "s.foo(address -> bool)" const mappingMatch = cleaned.match(/^(.+?)\s*\(mapping\((.+)\)\)$/); if (mappingMatch) return `${mappingMatch[1]}(${mappingMatch[2]})`; diff --git a/src/components/explorer/useStorageViewerState.ts b/src/components/explorer/useStorageViewerState.ts index d5f8879..8b03c8d 100644 --- a/src/components/explorer/useStorageViewerState.ts +++ b/src/components/explorer/useStorageViewerState.ts @@ -239,7 +239,7 @@ export function useStorageViewerState() { // Resolve contract context let proxyType: import('../../utils/resolver/types').ProxyType | undefined; let diamondFacets: import('../../utils/resolver/types').FacetInfo[] | null = null; - let implAddresses: string[] = []; + const implAddresses: string[] = []; let sourceBundle: { files: Record; contractName?: string; compilerVersion?: string } | undefined; const chain = getChainById(chainId); if (chain) { diff --git a/src/components/icons/IconLibrary.tsx b/src/components/icons/IconLibrary.tsx index 2377cba..8a5faed 100644 --- a/src/components/icons/IconLibrary.tsx +++ b/src/components/icons/IconLibrary.tsx @@ -4,7 +4,7 @@ import React from 'react'; // Component Props Interface -export interface IconProps { +interface IconProps { size?: number | string; color?: string; className?: string; @@ -20,94 +20,12 @@ export const PlusIcon: React.FC = ({ width = 24, height = 24, color = ); -export const MinusIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const CollapseAllIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); - -export const ExpandAllIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); - export const XCloseIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( ); -export const CheckIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const ClockIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const ClipboardIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const InfoIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); - -export const ExclamationIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); - export const EditIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -121,29 +39,6 @@ export const TrashIcon: React.FC = ({ width = 24, height = 24, color ); -export const CopyIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const SaveIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); - -export const ExternalLinkIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); - // Search & Navigation export const SearchIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -152,58 +47,6 @@ export const SearchIcon: React.FC = ({ width = 24, height = 24, color ); -export const SearchMdIcon: React.FC = ({ width = 20, height = 20, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const SearchSmIcon: React.FC = ({ width = 16, height = 16, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const FilterIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const ChevronDownIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const ChevronUpIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const ChevronLeftIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const ChevronRightIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -// Settings & Configuration -export const SettingsIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - // Actions & Operations export const PlayIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -295,20 +138,6 @@ export const AnimatedClockIcon: React.FC = ({ width = 24, height = 24 ); -export const RefreshIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); - -export const ShuffleIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - // Status & Feedback export const XCircleIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -324,13 +153,6 @@ export const CheckCircleIcon: React.FC = ({ width = 24, height = 24, ); -export const AlertCircleIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - export const AlertTriangleIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -338,36 +160,12 @@ export const AlertTriangleIcon: React.FC = ({ width = 24, height = 24 ); -export const InfoCircleIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - export const Loader2Icon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( ); -// Security & Vision -export const EyeIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const EyeOffIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - - -); - // Web3 Specific Icons export const HashIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -413,72 +211,6 @@ export const DiamondExplodeIcon: React.FC = ({ width = 24, height = 2 ); -export const DiamondLayersIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - {/* Top layer */} - - {/* Middle layer */} - - {/* Bottom layer */} - - - {/* Separation lines */} - - -); - -export const DiamondCutIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - {/* Left half of diamond */} - - - - - {/* Right half separated */} - - - - - {/* Cut line */} - - -); - -export const DiamondAnalyzeIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - {/* Main diamond */} - - - - - {/* Analysis grid overlay */} - - - {/* Magnifying glass */} - - - -); - -export const DiamondFacetsIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - {/* Diamond outline */} - - - {/* Visible facet lines */} - - - - - - {/* Floating info points */} - - - - - -); - export const BookOpenIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -486,13 +218,6 @@ export const BookOpenIcon: React.FC = ({ width = 24, height = 24, col ); -export const BlockIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - export const DatabaseIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -501,41 +226,6 @@ export const DatabaseIcon: React.FC = ({ width = 24, height = 24, col ); -export const FolderIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const LinkIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const LightbulbIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const FolderOpenIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const PenToolIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - - -); - export const HashtagIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( @@ -548,70 +238,3 @@ export const FileTextIcon: React.FC = ({ width = 24, height = 24, col ); - -// Icon Component Wrapper for consistent sizing and styling -export const Icon: React.FC<{ - icon: React.ComponentType; - size?: number | string; - color?: string; - className?: string; - style?: React.CSSProperties; -}> = ({ icon: IconComponent, size = 20, color = 'currentColor', className = '', style = {} }) => { - return ( - - ); -}; - -// Utility function to get icon by name (for dynamic usage) -export const getIcon = (iconName: string): React.ComponentType | null => { - const iconMap: { [key: string]: React.ComponentType } = { - plus: PlusIcon, - minus: MinusIcon, - 'x-close': XCloseIcon, - check: CheckIcon, - edit: EditIcon, - trash: TrashIcon, - copy: CopyIcon, - save: SaveIcon, - search: SearchIcon, - filter: FilterIcon, - 'chevron-down': ChevronDownIcon, - 'chevron-up': ChevronUpIcon, - settings: SettingsIcon, - play: PlayIcon, - // Add more mappings as needed - }; - - return iconMap[iconName] || null; -}; -export const PendingIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const ActiveIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - -); - -export const CompletedIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - -); - -export const ErrorIcon: React.FC = ({ width = 24, height = 24, color = 'currentColor', className = '', style = {} }) => ( - - - - - -); diff --git a/src/components/icons/IconMap.tsx b/src/components/icons/IconMap.tsx deleted file mode 100644 index c805f1e..0000000 --- a/src/components/icons/IconMap.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React from 'react'; -import { - Buildings, - CheckCircle, - Circle, - Clipboard, - FileCode, - Hash, - Info, - MapPin, - ArrowClockwise, - XCircle, -} from '@phosphor-icons/react'; - -export const iconMap = { - success: CheckCircle, - error: XCircle, - info: Info, - loading: ArrowClockwise, - address: MapPin, - number: Hash, - boolean: Circle, - bytes: FileCode, - array: Clipboard, - struct: Buildings, -} as const; - -interface IconProps { - name: keyof typeof iconMap; - size?: number; - className?: string; - color?: string; -} - -export const Icon: React.FC = ({ - name, - size = 16, - className = '', - color -}) => { - const IconComponent = iconMap[name]; - - if (!IconComponent) return {name}; - - return ( - - ); -}; - -export const UIIcons = { - // Status - success: , - error: , - info: , - loading: , - - // Data types - address: , - number: , - boolean: , - bytes: , - array: , - struct: , -}; - -export default Icon; diff --git a/src/components/integrations/IntegrationsHub.tsx b/src/components/integrations/IntegrationsHub.tsx index 0466e89..f98335e 100644 --- a/src/components/integrations/IntegrationsHub.tsx +++ b/src/components/integrations/IntegrationsHub.tsx @@ -5,9 +5,6 @@ import LoadingSpinner from "../shared/LoadingSpinner"; const LifiEarnPage = React.lazy( () => import("./lifi-earn/LifiEarnPage") ); -const SparkleShowcase = React.lazy( - () => import("./lifi-earn/SparkleShowcase") -); const IntegrationsHub: React.FC = () => { const { pathname } = useLocation(); @@ -25,10 +22,13 @@ const IntegrationsHub: React.FC = () => { return ; } + if (segment !== "lifi-earn") { + return ; + } + return ( }> - {segment === "sparkle-test" && } - {segment === "lifi-earn" && } + ); }; diff --git a/src/components/integrations/lifi-earn/SparkleShowcase.tsx b/src/components/integrations/lifi-earn/SparkleShowcase.tsx deleted file mode 100644 index f36cf40..0000000 --- a/src/components/integrations/lifi-earn/SparkleShowcase.tsx +++ /dev/null @@ -1,503 +0,0 @@ -import React, { useEffect, useRef, useState } from "react"; - -/** - * 20 animated sparkle/loading indicators — pick one to replace the current - * ShimmerSparkle in IntentPanel. Open via the Earn page or import directly. - */ - -// ─── 1. Hue-cycling ✦ (current) ────────────────────────────────────────────── -function S01() { - return ( - - ✦ - - - ); -} - -// ─── 2. Pulsing gradient dot ────────────────────────────────────────────────── -function S02() { - return ( - - - - ); -} - -// ─── 3. Three-dot breathing ─────────────────────────────────────────────────── -function S03() { - return ( - - {[0, 1, 2].map((i) => ( - - ))} - - - ); -} - -// ─── 4. SVG rotating star with gradient ─────────────────────────────────────── -function S04() { - return ( - - - - - - - - - - - ); -} - -// ─── 5. Orbit dots ──────────────────────────────────────────────────────────── -function S05() { - return ( - - - - - - - ); -} - -// ─── 6. Morphing blob ───────────────────────────────────────────────────────── -function S06() { - return ( - - - - - - ); -} - -// ─── 7. Waveform bars ───────────────────────────────────────────────────────── -function S07() { - return ( - - {[0, 1, 2, 3, 4].map((i) => ( - - ))} - - - ); -} - -// ─── 8. DNA helix dots ──────────────────────────────────────────────────────── -function S08() { - return ( - - {[0, 1, 2, 3].map((i) => ( - - - - - ))} - - - ); -} - -// ─── 9. Ripple ring ─────────────────────────────────────────────────────────── -function S09() { - return ( - - - - - - - ); -} - -// ─── 10. Rotating diamond chain ─────────────────────────────────────────────── -function S10() { - return ( - - {[0, 1, 2].map((i) => ( - - ))} - - - ); -} - -// ─── 11. SVG draw-in sparkle ────────────────────────────────────────────────── -function S11() { - return ( - - - - - - ); -} - -// ─── 12. Breathing ring with inner glow ─────────────────────────────────────── -function S12() { - return ( - - - - - - ); -} - -// ─── 13. Staggered cross ───────────────────────────────────────────────────── -function S13() { - const arms = [ - { x: 0, y: -5 }, { x: 5, y: 0 }, { x: 0, y: 5 }, { x: -5, y: 0 }, - { x: -3.5, y: -3.5 }, { x: 3.5, y: -3.5 }, { x: 3.5, y: 3.5 }, { x: -3.5, y: 3.5 }, - ]; - return ( - - {arms.map((a, i) => ( - - ))} - - - ); -} - -// ─── 14. Rotating gradient arc ──────────────────────────────────────────────── -function S14() { - return ( - - - - - - - - - - - ); -} - -// ─── 15. Layered spinning squares ───────────────────────────────────────────── -function S15() { - return ( - - - - - - ); -} - -// ─── 16. Twinkling star field ───────────────────────────────────────────────── -function S16() { - const stars = [ - { x: 2, y: 3, s: 0 }, { x: 10, y: 1, s: 0.3 }, { x: 6, y: 8, s: 0.6 }, - { x: 14, y: 5, s: 0.9 }, { x: 1, y: 10, s: 0.4 }, { x: 12, y: 11, s: 0.7 }, - ]; - return ( - - {stars.map((s, i) => ( - - ✦ - - ))} - - - ); -} - -// ─── 17. Canvas particle swirl ──────────────────────────────────────────────── -function S17() { - const ref = useRef(null); - useEffect(() => { - const c = ref.current!; - const ctx = c.getContext("2d")!; - const dpr = 2; - c.width = 32; c.height = 32; - const particles = Array.from({ length: 12 }, (_, i) => ({ - angle: (i / 12) * Math.PI * 2, - r: 6 + Math.random() * 4, - speed: 0.02 + Math.random() * 0.02, - size: 1 + Math.random(), - hue: (i / 12) * 360, - })); - let raf: number; - const draw = () => { - ctx.clearRect(0, 0, 32, 32); - for (const p of particles) { - p.angle += p.speed; - const x = 16 + Math.cos(p.angle) * p.r; - const y = 16 + Math.sin(p.angle) * p.r; - ctx.beginPath(); - ctx.arc(x, y, p.size, 0, Math.PI * 2); - ctx.fillStyle = `hsla(${p.hue}, 70%, 65%, 0.8)`; - ctx.fill(); - p.hue = (p.hue + 0.5) % 360; - } - raf = requestAnimationFrame(draw); - }; - draw(); - return () => cancelAnimationFrame(raf); - }, []); - return ; -} - -// ─── 18. Neon pulse ─────────────────────────────────────────────────────────── -function S18() { - return ( - - ✧ - - - ); -} - -// ─── 19. Pendulum wave ──────────────────────────────────────────────────────── -function S19() { - return ( - - {[0, 1, 2, 3, 4, 5, 6].map((i) => ( - - ))} - - - ); -} - -// ─── 20. Converging triangles ───────────────────────────────────────────────── -function S20() { - return ( - - - - - - - - ); -} - -// ─── Showcase grid ──────────────────────────────────────────────────────────── -const ALL: { name: string; C: React.FC }[] = [ - { name: "1. Hue-cycling ✦", C: S01 }, - { name: "2. Conic gradient dot", C: S02 }, - { name: "3. Breathing dots", C: S03 }, - { name: "4. Gradient star", C: S04 }, - { name: "5. Orbit dots", C: S05 }, - { name: "6. Morphing blob", C: S06 }, - { name: "7. Waveform bars", C: S07 }, - { name: "8. DNA helix", C: S08 }, - { name: "9. Ripple ring", C: S09 }, - { name: "10. Diamond chain", C: S10 }, - { name: "11. Draw-in sparkle", C: S11 }, - { name: "12. Breathing glow", C: S12 }, - { name: "13. Staggered cross", C: S13 }, - { name: "14. Gradient arc", C: S14 }, - { name: "15. Spinning squares", C: S15 }, - { name: "16. Twinkling field", C: S16 }, - { name: "17. Particle swirl", C: S17 }, - { name: "18. Neon pulse", C: S18 }, - { name: "19. Pendulum wave", C: S19 }, - { name: "20. Converging triangles", C: S20 }, -]; - -// Fake typewriter for preview -function TypewriterPreview() { - const words = ["Pondering", "Analyzing", "Searching", "Evaluating"]; - const [wordIdx, setWordIdx] = useState(0); - const [charIdx, setCharIdx] = useState(0); - const [deleting, setDeleting] = useState(false); - - useEffect(() => { - const word = words[wordIdx]; - if (!deleting) { - if (charIdx < word.length) { - const id = setTimeout(() => setCharIdx((c) => c + 1), 60); - return () => clearTimeout(id); - } - const id = setTimeout(() => setDeleting(true), 1400); - return () => clearTimeout(id); - } - if (charIdx > 0) { - const id = setTimeout(() => setCharIdx((c) => c - 1), 30); - return () => clearTimeout(id); - } - setDeleting(false); - setWordIdx((i) => (i + 1) % words.length); - }, [wordIdx, charIdx, deleting]); - - return ( - - {words[wordIdx].slice(0, charIdx)} - | - - ); -} - -export function SparkleShowcase() { - const [selected, setSelected] = useState(null); - - return ( -
-
-

Sparkle Indicators

-

- Pick a sparkle to preview it in the button context below. -

-
- - {/* Grid of all 20 */} -
- {ALL.map(({ name, C }, i) => ( - - ))} -
- - {/* Live preview in button context */} -
-

- Button preview -

-
- {/* Idle state */} - - {/* Active state with selected sparkle */} - -
-
-
- ); -} - -export default SparkleShowcase; diff --git a/src/components/integrations/lifi-earn/concierge/ExecutionQueue.tsx b/src/components/integrations/lifi-earn/concierge/ExecutionQueue.tsx index 4ceeefb..504d264 100644 --- a/src/components/integrations/lifi-earn/concierge/ExecutionQueue.tsx +++ b/src/components/integrations/lifi-earn/concierge/ExecutionQueue.tsx @@ -14,7 +14,10 @@ interface ExecutionQueueProps { export function ExecutionQueue({ state, dispatch }: ExecutionQueueProps) { if (state.legs.length === 0) return null; + return ; +} +function ExecutionQueueBody({ state, dispatch }: ExecutionQueueProps) { const current = state.currentIndex >= 0 ? state.legs[state.currentIndex] : null; const allDone = state.legs.every( (l) => l.status === "done" || l.status === "failed" @@ -33,7 +36,6 @@ export function ExecutionQueue({ state, dispatch }: ExecutionQueueProps) { requestAnimationFrame(() => { queueRef.current?.scrollIntoView({ behavior: "smooth", block: "center" }); }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/src/components/integrations/lifi-earn/concierge/VaultRecommendations.tsx b/src/components/integrations/lifi-earn/concierge/VaultRecommendations.tsx index 19fdb04..2a5f106 100644 --- a/src/components/integrations/lifi-earn/concierge/VaultRecommendations.tsx +++ b/src/components/integrations/lifi-earn/concierge/VaultRecommendations.tsx @@ -217,6 +217,33 @@ function VaultPill({ ); } + return ( + + ); +} + +function VaultPillBody({ + label, + pick, + isDestination, + onPick, + sourceTokenSymbol, + sourceChainId, +}: { + label: string; + pick: RecommendationPick; + isDestination: boolean; + onPick: (v: EarnVault) => void; + sourceTokenSymbol?: string | null; + sourceChainId?: number; +}) { const apy = pick.vault.analytics.apy.total; const apyStr = apy != null ? `${apy.toFixed(2)}%` : "—"; const vaultName = pick.vault.name ?? pick.vault.slug; diff --git a/src/components/integrations/lifi-earn/concierge/hooks/useIdleBalances.ts b/src/components/integrations/lifi-earn/concierge/hooks/useIdleBalances.ts index 3789da9..0d3812b 100644 --- a/src/components/integrations/lifi-earn/concierge/hooks/useIdleBalances.ts +++ b/src/components/integrations/lifi-earn/concierge/hooks/useIdleBalances.ts @@ -23,10 +23,6 @@ export function useIdleBalances(targetAddress: string | null, perChainTimeoutMs if (!page.nextCursor) return all; cursor = page.nextCursor; } - console.warn( - `[concierge] earn-vaults pagination hit safety cap (${SAFETY_MAX_PAGES} pages); ` + - `subsequent vaults were not loaded.` - ); return all; }, staleTime: 5 * 60 * 1000, @@ -56,15 +52,6 @@ export function useIdleBalances(targetAddress: string | null, perChainTimeoutMs (id) => !isTestnet(id as number) ) as number[]; - // eslint-disable-next-line no-console - console.log( - `[concierge] scanning ${chainIds.length} chains:`, - chainIds.map((id) => { - const meta = CHAIN_REGISTRY.find((c) => c.id === id); - return `${meta?.name ?? id}(${(underlyingsByChain.get(id) ?? []).length} tokens)`; - }) - ); - const chainResults = await Promise.all( chainIds.map((chainId) => scanSingleChain({ @@ -72,13 +59,7 @@ export function useIdleBalances(targetAddress: string | null, perChainTimeoutMs address: targetAddress as `0x${string}`, tokens: underlyingsByChain.get(chainId) ?? [], timeoutMs: perChainTimeoutMs, - }).catch((err) => { - console.warn( - `[concierge] chain ${chainId} (${CHAIN_REGISTRY.find((c) => c.id === chainId)?.name ?? "?"}) scan failed:`, - err?.message ?? err - ); - return null; - }) + }).catch(() => null) ) ); diff --git a/src/components/integrations/lifi-earn/concierge/hooks/useVaultRecommendations.ts b/src/components/integrations/lifi-earn/concierge/hooks/useVaultRecommendations.ts index 7a6259b..9fc5cfb 100644 --- a/src/components/integrations/lifi-earn/concierge/hooks/useVaultRecommendations.ts +++ b/src/components/integrations/lifi-earn/concierge/hooks/useVaultRecommendations.ts @@ -103,16 +103,6 @@ export function useVaultRecommendations(args: { const viable = filterByViability(raw, a); const capped = viable.slice(0, DEFAULT_CONFIG.maxCandidatesPerAsset); - // eslint-disable-next-line no-console - const routeCounts = { direct: 0, swap: 0, bridge: 0, bridge_and_swap: 0 }; - for (const v of capped) routeCounts[classifyRoute(a, v)]++; - // eslint-disable-next-line no-console - console.log( - `[concierge] candidates for ${a.token.symbol}@${a.chainName}:`, - `raw=${raw.length} viable=${viable.length} sent=${capped.length}`, - routeCounts - ); - map.set(keyOf(a), capped); } return map; @@ -219,21 +209,11 @@ async function fetchRecommendationForAsset( try { const raw = await postLlmRecommend(request); const text = extractGeminiText(raw); - if (!text) { - // eslint-disable-next-line no-console - console.warn("[concierge] raw LLM response (no text extracted):", raw); - throw new Error("empty LLM response"); - } + if (!text) throw new Error("empty LLM response"); const json = safeParseJson(text); - if (!json) { - // eslint-disable-next-line no-console - console.warn("[concierge] LLM text (not valid JSON):", text.slice(0, 500)); - throw new Error("LLM did not return JSON"); - } + if (!json) throw new Error("LLM did not return JSON"); const result = llmRecommendationSchema.safeParse(json); if (!result.success) { - // eslint-disable-next-line no-console - console.warn("[concierge] schema validation failed:", result.error.issues, "\nparsed JSON:", JSON.stringify(json).slice(0, 800)); throw new Error( `schema: ${result.error.issues[0]?.path.join(".") ?? "?"}: ${result.error.issues[0]?.message ?? "unknown"}` ); @@ -244,11 +224,6 @@ async function fetchRecommendationForAsset( } catch (err) { const msg = err instanceof Error ? err.message : String(err); lastError = msg; - // eslint-disable-next-line no-console - console.warn( - `[concierge] LLM attempt ${attempt + 1} failed for ${keyOf(asset)}:`, - msg - ); if (attempt === 1) parsed = null; } } diff --git a/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentParser.ts b/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentParser.ts index 49b7ef0..968c5a9 100644 --- a/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentParser.ts +++ b/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentParser.ts @@ -52,7 +52,7 @@ export function useIntentParser() { } catch (err) { const msg = err instanceof Error ? err.message : String(err); lastError = msg; - // eslint-disable-next-line no-console + console.warn(`[intent-parser] attempt ${attempt + 1} failed:`, msg); } } diff --git a/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentRecommendation.ts b/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentRecommendation.ts index eb0f40a..ab701eb 100644 --- a/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentRecommendation.ts +++ b/src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentRecommendation.ts @@ -237,7 +237,7 @@ export async function buildRecommendation( } catch (err) { const msg = err instanceof Error ? err.message : String(err); lastError = msg; - // eslint-disable-next-line no-console + console.warn(`[intent-rec] LLM attempt ${attempt + 1} failed:`, msg); } } diff --git a/src/components/integrations/lifi-earn/concierge/intent/hooks/useVaultsByIntent.ts b/src/components/integrations/lifi-earn/concierge/intent/hooks/useVaultsByIntent.ts index c23e89d..e310bf6 100644 --- a/src/components/integrations/lifi-earn/concierge/intent/hooks/useVaultsByIntent.ts +++ b/src/components/integrations/lifi-earn/concierge/intent/hooks/useVaultsByIntent.ts @@ -24,7 +24,7 @@ function useAllEarnVaults() { if (!page.nextCursor) return all; cursor = page.nextCursor; } - // eslint-disable-next-line no-console + console.warn( `[intent] earn-vaults pagination hit safety cap (${SAFETY_MAX_PAGES} pages)` ); diff --git a/src/components/integrations/lifi-earn/simulator/projection.ts b/src/components/integrations/lifi-earn/simulator/projection.ts index d95002c..ba84d53 100644 --- a/src/components/integrations/lifi-earn/simulator/projection.ts +++ b/src/components/integrations/lifi-earn/simulator/projection.ts @@ -23,16 +23,3 @@ export function projectEarnings( return projectBalance(deposit, apyPercent, days) - (Number.isFinite(deposit) ? deposit : 0); } -export function sampleBalanceCurve( - deposit: number, - apyPercent: number | null | undefined, - days: number, - samples = 60, -): number[] { - const out: number[] = new Array(samples); - for (let i = 0; i < samples; i++) { - const d = (days * i) / (samples - 1); - out[i] = projectBalance(deposit, apyPercent, d); - } - return out; -} diff --git a/src/components/shared/AddressDisplay.tsx b/src/components/shared/AddressDisplay.tsx index 80a8d06..aada105 100644 --- a/src/components/shared/AddressDisplay.tsx +++ b/src/components/shared/AddressDisplay.tsx @@ -19,13 +19,3 @@ export function shortenAddress( return `${address.slice(0, prefixLength)}\u2026${address.slice(-suffixLength)}`; } -/** Pure utility: truncate a hex hash (tx hash, slot, etc.) */ -export function shortenHash( - hash: string | null | undefined, - prefixLength = 10, - suffixLength = 6, -): string { - if (!hash) return '\u2014'; - if (hash.length <= prefixLength + suffixLength + 2) return hash; - return `${hash.slice(0, prefixLength)}\u2026${hash.slice(-suffixLength)}`; -} diff --git a/src/components/shared/Card.tsx b/src/components/shared/Card.tsx deleted file mode 100644 index 2594c95..0000000 --- a/src/components/shared/Card.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react'; -import '../../styles/SharedComponents.css'; - -export interface CardProps { - children: React.ReactNode; - title?: string; - subtitle?: string; - className?: string; - variant?: 'default' | 'elevated' | 'glass' | 'accent'; - padding?: 'none' | 'sm' | 'md' | 'lg'; - hoverable?: boolean; - onClick?: () => void; - style?: React.CSSProperties; -} - -const Card: React.FC = ({ - children, - title, - subtitle, - className = '', - variant = 'default', - padding = 'md', - hoverable = false, - onClick, - style -}) => { - const classes = [ - 'shared-card', - `shared-card-${variant}`, - `shared-card-padding-${padding}`, - (onClick || hoverable) ? 'shared-card-hoverable' : '', - className - ].filter(Boolean).join(' '); - - return ( -
- {(title || subtitle) && ( -
- {title && ( -

- {title} -

- )} - {subtitle && ( -

- {subtitle} -

- )} -
- )} - {children} -
- ); -}; - -export default Card; \ No newline at end of file diff --git a/src/components/shared/Input.tsx b/src/components/shared/Input.tsx deleted file mode 100644 index 3e96293..0000000 --- a/src/components/shared/Input.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React, { useId } from 'react'; -import '../../styles/SharedComponents.css'; - -export interface InputProps extends React.InputHTMLAttributes { - label?: string; - error?: string; - hint?: string; - leftIcon?: React.ReactNode; - rightIcon?: React.ReactNode; - variant?: 'default' | 'ghost' | 'accent'; - fullWidth?: boolean; -} - -const Input: React.FC = ({ - label, - error, - hint, - leftIcon, - rightIcon, - variant = 'default', - fullWidth = true, - className = '', - ...props -}) => { - const inputId = useId(); - - const inputClasses = [ - 'shared-input', - `shared-input-${variant}`, - leftIcon ? 'shared-input-with-left-icon' : '', - rightIcon ? 'shared-input-with-right-icon' : '', - error ? 'shared-input-error' : '', - className - ].filter(Boolean).join(' '); - - const containerClasses = fullWidth ? 'shared-input-container' : ''; - - return ( -
- {label && ( - - )} - -
- {leftIcon && ( -
- {leftIcon} -
- )} - - - - {rightIcon && ( -
- {rightIcon} -
- )} -
- - {error && ( -

{error}

- )} - - {hint && !error && ( -

{hint}

- )} -
- ); -}; - -export default Input; \ No newline at end of file diff --git a/src/components/shared/index.ts b/src/components/shared/index.ts index c3087ca..904b2eb 100644 --- a/src/components/shared/index.ts +++ b/src/components/shared/index.ts @@ -1,9 +1,7 @@ // Shared UI Components -export { default as Input } from './Input'; -export { default as Card } from './Card'; export { default as LoadingSpinner } from './LoadingSpinner'; export { default as ErrorDisplay } from './ErrorDisplay'; -export { shortenAddress, shortenHash } from './AddressDisplay'; +export { shortenAddress } from './AddressDisplay'; // Contract Badges export { @@ -14,16 +12,6 @@ export { ContractBadges, } from './ContractBadges'; -// Re-export shadcn components for backwards compatibility -export { Button } from '../ui/button'; -export { Badge } from '../ui/badge'; - // Export types -export type { ButtonProps } from '../ui/button'; -export type { InputProps } from './Input'; -export type { CardProps } from './Card'; export type { LoadingSpinnerProps } from './LoadingSpinner'; -export type { ErrorDisplayProps } from './ErrorDisplay'; - -// Badge types from shadcn -export type { VariantProps as BadgeVariantProps } from 'class-variance-authority'; \ No newline at end of file +export type { ErrorDisplayProps } from './ErrorDisplay'; \ No newline at end of file diff --git a/src/components/signature-database/ToolsTab.tsx b/src/components/signature-database/ToolsTab.tsx index 0ccffbf..fcaddb6 100644 --- a/src/components/signature-database/ToolsTab.tsx +++ b/src/components/signature-database/ToolsTab.tsx @@ -24,7 +24,7 @@ import { } from "../ui/input-group"; import type { ToolSubTab } from "./types"; -const SmartDecoder = React.lazy(() => import("../SmartDecoder")); +const SmartDecoder = React.lazy(() => import("../smart-decoder/SmartDecoder")); const CalldataEncoder = React.lazy(() => import("../CalldataEncoder")); const HashToolkit = React.lazy(() => import("../HashToolkit")); diff --git a/src/components/signature-database/types.ts b/src/components/signature-database/types.ts index 30d9e89..cd04539 100644 --- a/src/components/signature-database/types.ts +++ b/src/components/signature-database/types.ts @@ -41,18 +41,6 @@ export type ParsedContracts = Record; // ---- Constants ---- -export const SIGNATURE_TAB_OPTIONS: Array<{ - value: TabType; - title: string; - helper: string; -}> = [ - { value: "lookup", title: "Lookup", helper: "By Hash" }, - { value: "search", title: "Search", helper: "By Name" }, - { value: "tools", title: "Tools", helper: "Utilities" }, - { value: "custom", title: "Custom", helper: "Add Signatures" }, - { value: "cache", title: "Cache", helper: "Saved Results" }, -]; - export const SIGNATURE_TABS: TabType[] = [ "lookup", "search", diff --git a/src/components/simple-grid/GridLayout.tsx b/src/components/simple-grid/GridLayout.tsx index 2f600a6..3f06fd5 100644 --- a/src/components/simple-grid/GridLayout.tsx +++ b/src/components/simple-grid/GridLayout.tsx @@ -7,7 +7,7 @@ import React from "react"; import { ethers } from "ethers"; import { Button } from "../ui/button"; -import { UIIcons } from "../icons/IconMap"; +import { ArrowClockwise } from "@phosphor-icons/react"; import { InlineFacetLoader } from "../InlineFacetLoader"; import { abbreviateFacet } from "./utils"; import { useGridContext } from "./GridContext"; @@ -322,7 +322,7 @@ export default function GridLayout(): React.ReactElement { color: "#60a5fa", }} > - + {abbreviateFacet(currentFacetDetail.address)}
)} diff --git a/src/components/simple-grid/SimpleGridMain.tsx b/src/components/simple-grid/SimpleGridMain.tsx index 83d8232..a6651da 100644 --- a/src/components/simple-grid/SimpleGridMain.tsx +++ b/src/components/simple-grid/SimpleGridMain.tsx @@ -25,7 +25,6 @@ import { useSimulation } from "../../contexts/SimulationContext"; import { sanitizeAbiEntries } from "./utils"; import "../../styles/SharedComponents.css"; -import "../../styles/SimulatorWorkbench.css"; import "../../styles/SimpleGridUI.css"; import { GridProvider } from "./GridContext"; diff --git a/src/components/simple-grid/hooks/useFunctionState.ts b/src/components/simple-grid/hooks/useFunctionState.ts index 3bf5fee..a5dc66f 100644 --- a/src/components/simple-grid/hooks/useFunctionState.ts +++ b/src/components/simple-grid/hooks/useFunctionState.ts @@ -82,7 +82,7 @@ export function useFunctionState(deps: UseFunctionStateDeps) { // ---------- all / filtered functions ---------- const allReadFunctions = useMemo(() => { - let allReads = [...readFunctions]; + const allReads = [...readFunctions]; if (isDiamond) { diamondFacets.forEach((facet) => { if (Array.isArray(facet.abi)) { @@ -99,7 +99,7 @@ export function useFunctionState(deps: UseFunctionStateDeps) { }, [readFunctions, isDiamond, diamondFacets]); const allWriteFunctions = useMemo(() => { - let allWrites = [...writeFunctions]; + const allWrites = [...writeFunctions]; if (isDiamond) { diamondFacets.forEach((facet) => { if (Array.isArray(facet.abi)) { diff --git a/src/components/simple-grid/tokenDetection.ts b/src/components/simple-grid/tokenDetection.ts index 5faff85..75cd04d 100644 --- a/src/components/simple-grid/tokenDetection.ts +++ b/src/components/simple-grid/tokenDetection.ts @@ -81,7 +81,7 @@ try { ); // Enhanced detection specifically for Diamond contracts - let enhancedDetection = { ...tokenDetection }; + const enhancedDetection = { ...tokenDetection }; // If Diamond detected but no token type, try additional detection methods if (tokenDetection.isDiamond && tokenDetection.type === "unknown") { diff --git a/src/components/simple-grid/tokenDetection/universal.ts b/src/components/simple-grid/tokenDetection/universal.ts index d6f9346..d552c22 100644 --- a/src/components/simple-grid/tokenDetection/universal.ts +++ b/src/components/simple-grid/tokenDetection/universal.ts @@ -124,7 +124,7 @@ export async function detectTokenTypeUniversal( let confidence = 0; let detectionMethod = "none"; let isDiamond = false; - let tokenInfo: any = {}; + const tokenInfo: any = {}; let error: string | undefined; try { diff --git a/src/components/simulation-results/formatters.ts b/src/components/simulation-results/formatters.ts index 0982b05..b5c2da0 100644 --- a/src/components/simulation-results/formatters.ts +++ b/src/components/simulation-results/formatters.ts @@ -1,13 +1,4 @@ import { OPCODE_MNEMONICS } from "./constants"; -import { shortenAddress, shortenHash } from '../shared/AddressDisplay'; - -export const formatLongAddress = (value?: string | null) => { - if (!value) return "0x0"; - if (value === "0x0000000000000000000000000000000000000000") { - return "Zero Address (0x0000\u20260000)"; - } - return `${shortenAddress(value)} (${shortenHash(value, 10, 4)})`; -}; export const getOpcodeName = (opcode?: number | null) => { if (typeof opcode !== "number") return "OP"; @@ -144,27 +135,9 @@ export const formatTxType = (type?: number | null) => { } }; -export const getOpcodeToneClass = (name?: string) => { - if (!name) return ""; - if (name.startsWith("SLOAD") || name.startsWith("SSTORE")) return "sim-opcode-badge--storage"; - if (name.startsWith("STOP")) return "sim-opcode-badge--stop"; - if (name.startsWith("JUMP") || name.startsWith("CALL")) return "sim-opcode-badge--flow"; - return ""; -}; - export const parseGasSafe = (value: string | number | null | undefined): number => { if (!value) return 0; const num = typeof value === 'string' ? parseInt(value, 10) : value; const MAX_REASONABLE_GAS = 100_000_000; return (Number.isFinite(num) && num > 0 && num < MAX_REASONABLE_GAS) ? num : 0; }; - -/** Format contract name with address */ -export const formatContractDisplay = (address?: string, name?: string) => { - if (!address) return "—"; - const short = shortenAddress(address); - if (name && name !== address) { - return `${name}(${short})`; - } - return short; -}; diff --git a/src/components/smart-decoder/SmartDecoder.tsx b/src/components/smart-decoder/SmartDecoder.tsx index eb971e8..50f547d 100644 --- a/src/components/smart-decoder/SmartDecoder.tsx +++ b/src/components/smart-decoder/SmartDecoder.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect, useRef, useMemo, useCallback } from 'react'; -import { animate } from 'animejs'; import { CheckCircle, Sparkle, @@ -116,11 +115,8 @@ const SmartDecoder: React.FC = () => { const fileInputRef = useRef(null); const fallbackSectionRef = useRef(null); const abiContractInputRef = useRef(null); - const abiSourceSectionRef = useRef(null); const lookupAbortRef = useRef(null); const abiCacheRef = useRef>(new Map()); - const [showAbiSourceSection, setShowAbiSourceSection] = useState(false); - const prevDecodedResultRef = useRef(null); const cancelActiveLookup = useCallback(() => { if (lookupAbortRef.current) { @@ -140,19 +136,6 @@ const SmartDecoder: React.FC = () => { return () => cancelActiveLookup(); }, [cancelActiveLookup]); - useEffect(() => { - if (decodedResult && !prevDecodedResultRef.current && showFallbackOptions && abiSourceSectionRef.current) { - setShowAbiSourceSection(true); - animate(abiSourceSectionRef.current, { - translateY: [-20, 0], - opacity: [0, 1], - duration: 400, - ease: 'outCubic' - }); - } - prevDecodedResultRef.current = decodedResult; - }, [decodedResult, showFallbackOptions]); - const addDecodingStep = useCallback((step: string) => { setDecodingSteps(prev => [...prev, step]); }, []); diff --git a/src/components/smart-decoder/useDecodeHandlers.ts b/src/components/smart-decoder/useDecodeHandlers.ts index bcdcd5d..065f99e 100644 --- a/src/components/smart-decoder/useDecodeHandlers.ts +++ b/src/components/smart-decoder/useDecodeHandlers.ts @@ -224,7 +224,7 @@ export function useDecodeHandlers(deps: DecodeHandlersDeps) { const result = await prefetched[currentSourceIndex]; if (result.status === "fulfilled" && Array.isArray(result.result?.abi)) { - let abi = result.result.abi; + const abi = result.result.abi; const resolvedChainId = result.result.chainId || chainIdForLookup; const resolvedChain = resolvedChainId ? getChainById(parseInt(resolvedChainId, 10)) : null; setCurrentSearchProgress(prev => [...prev, `Found verified contract on ${source.name}!`]); diff --git a/src/components/smart-decoder/utils.ts b/src/components/smart-decoder/utils.ts index 4cde356..cd61378 100644 --- a/src/components/smart-decoder/utils.ts +++ b/src/components/smart-decoder/utils.ts @@ -3,7 +3,6 @@ import { getCachedSignatures, getCustomSignatures, } from '../../utils/signatureDatabase'; -import type { AbiSourceType } from './types'; import { shortenAddress } from '../shared/AddressDisplay'; export { shortenAddress }; @@ -34,88 +33,6 @@ export const sanitizeDecodedValue = (value: any): any => { return value; }; -export const formatParameterValue = ( - value: any, - paramType?: string, - options?: { full?: boolean } -): string => { - const full = options?.full ?? false; - if (value === null || value === undefined) return 'null'; - - if (Array.isArray(value)) { - if (full) { - try { - return JSON.stringify(value); - } catch { - return `[${value.map(v => formatParameterValue(v, undefined, { full: true })).join(', ')}]`; - } - } - - const hasComplexChildren = value.some( - (item) => - Array.isArray(item) || - (item && typeof item === 'object' && !item._isBigNumber && !(item instanceof Uint8Array)) - ); - - if (!full && (paramType?.includes('tuple') || hasComplexChildren)) { - let preview = ''; - if (value.length > 0 && Array.isArray(value[0])) { - const firstStruct = value[0]; - if (firstStruct.length >= 3) { - preview = ` (e.g., {${firstStruct[0]}, ${firstStruct[1]}, [${firstStruct[2]?.length || 0} items]})`; - } else { - preview = ` (e.g., {${firstStruct.slice(0, 2).join(', ')}${firstStruct.length > 2 ? ', ...' : ''}})`; - } - } - return `Struct Array[${value.length} items]${preview} - Switch to JSON View for full details`; - } - - if (value.length <= 3) { - return `[${value.map(v => formatParameterValue(v)).join(', ')}]`; - } else { - return `[${value.slice(0, 2).map(v => formatParameterValue(v)).join(', ')}, ... +${value.length - 2} more]`; - } - } - - if (value && typeof value === 'object') { - if (full) { - try { - return JSON.stringify(value); - } catch { - return String(value); - } - } - } - - const str = String(value); - - if (str.match(/^0x[a-fA-F0-9]{40}$/)) { - return str; - } - - if (str.match(/^\d+$/) && str.length > 10) { - const num = BigInt(str); - const formatted = num.toLocaleString(); - - const timestamp = Number(str); - if (timestamp > 946684800 && timestamp < 4102444800) { - const date = new Date(timestamp * 1000); - return `${formatted} (${date.toISOString().split('T')[0]})`; - } - - return formatted; - } - - if (str.startsWith('0x') && str.length > 42 && str.match(/^0x[a-fA-F0-9]+$/)) { - if (full) { - return str; - } - return `${str.slice(0, 10)}...${str.slice(-8)} (${(str.length - 2) / 2} bytes)`; - } - - return str; -}; - export const getParameterType = (value: any): string => { if (value === null || value === undefined) return 'unknown'; @@ -166,42 +83,6 @@ export const getParameterType = (value: any): string => { return 'string'; }; -export const inferValueType = (value: any): string => { - if (value === null || value === undefined) return 'null'; - if (Array.isArray(value)) return `tuple(${value.length})`; - if (value && typeof value === 'object') { - if (value._isBigNumber) return 'uint'; - return 'object'; - } - if (typeof value === 'boolean') return 'bool'; - if (typeof value === 'number') return Number.isInteger(value) ? 'int' : 'float'; - if (typeof value === 'string') { - if (/^0x[a-fA-F0-9]+$/.test(value)) { - const byteLength = value.length > 2 ? (value.length - 2) / 2 : 0; - return byteLength ? `bytes${byteLength}` : 'bytes'; - } - return 'string'; - } - return typeof value; -}; - -export const getAbiSourceLabel = (abiSource: AbiSourceType, decodedResult: any): string => { - if (!abiSource) { - return decodedResult ? 'Signature lookup / heuristic' : '—'; - } - - const labels: Record, string> = { - sourcify: 'Sourcify (verified ABI)', - blockscout: 'Blockscout (verified ABI)', - etherscan: 'Etherscan (verified ABI)', - manual: 'Manual ABI', - signatures: 'Signature database', - heuristic: 'Heuristic analysis' - }; - - return labels[abiSource] ?? abiSource; -}; - export const extractFunctionSelector = (calldataHex: string): string | null => { try { if (!calldataHex.startsWith('0x')) { diff --git a/src/components/transaction-builder/SimulationReplayResults.tsx b/src/components/transaction-builder/SimulationReplayResults.tsx deleted file mode 100644 index 5de4f01..0000000 --- a/src/components/transaction-builder/SimulationReplayResults.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import React, { useMemo } from "react"; -import { - CheckCircleIcon, - AlertTriangleIcon, -} from "../icons/IconLibrary"; -import { - extractSimulationArtifacts, - flattenCallTreeEntries, - getCallNodeError, - type SimulationCallNode, -} from "../../utils/simulationArtifacts"; -import type { SimulationResult } from "../../types/transaction"; -import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "../ui/table"; -import { EMPTY_CALL_TREE } from "./types"; -import { shortenAddress } from "../shared/AddressDisplay"; - -const renderCallTreeNodes = (nodes: SimulationCallNode[]): React.ReactNode => { - if (!nodes || nodes.length === 0) { - return null; - } - - return ( -
    - {nodes.map((node) => ( -
  • -
    - {node.functionName || node.label || "Call"} -
    -
    - {shortenAddress(node.from)} → {shortenAddress(node.to)} - {node.gasUsed ? · gas {node.gasUsed} : null} - {node.error ? ( - - {" "} - · {node.error} - - ) : null} -
    - {node.children && node.children.length > 0 - ? renderCallTreeNodes(node.children) - : null} -
  • - ))} -
- ); -}; - -export const SimulationReplayResults: React.FC<{ result: SimulationResult }> = ({ result }) => { - const artifacts = useMemo(() => extractSimulationArtifacts(result), [result]); - const callTree = artifacts.callTree ?? EMPTY_CALL_TREE; - const flattened = useMemo( - () => flattenCallTreeEntries(callTree).slice(0, 32), - [callTree] - ); - const warnings = result.warnings ?? []; - const statusColor = result.success ? "#34d399" : "#fb7185"; - const statusIcon = result.success ? ( - - ) : ( - - ); - - return ( -
-
- {statusIcon} -
- {result.success ? "Execution completed" : "Execution failed"} -
- Mode: {result.mode?.toUpperCase() ?? "N/A"} -
-
-
- -
- Gas Used - {result.gasUsed ?? "\u2014"} - Suggested Gas - {result.gasLimitSuggested ?? "\u2014"} - Revert Reason - {result.revertReason ?? result.error ?? "\u2014"} - Warnings - - {warnings.length === 0 ? ( - "\u2014" - ) : ( -
    - {warnings.map((warning, index) => ( -
  • {warning}
  • - ))} -
- )} -
-
- -
-

Call Trace

- {callTree.length === 0 ? ( -

No call trace available.

- ) : ( - <> - {renderCallTreeNodes(callTree)} - {flattened.length > 0 ? ( -
- View flat call list - - - - Function - From → To - Gas - Note - - - - {flattened.map((entry) => ( - - - {entry.functionName || entry.label || "Call"} - - - {shortenAddress(entry.from)} → {shortenAddress(entry.to)} - - - {entry.gasUsed ?? "\u2014"} - - - {getCallNodeError(entry) ?? "\u2014"} - - - ))} - -
-
- ) : null} - - )} -
- -
-

Events

- {artifacts.events && artifacts.events.length > 0 ? ( -
    - {artifacts.events.slice(0, 10).map((event, index) => ( -
  • - {event.name || "Event"}{" "} - - ({shortenAddress(event.address)}) - - {event.decoded ? ( -
    - Decoded -
    -                      {JSON.stringify(event.decoded, null, 2)}
    -                    
    -
    - ) : null} -
  • - ))} - {artifacts.events.length > 10 ? ( -
  • - +{artifacts.events.length - 10} additional events -
  • - ) : null} -
- ) : ( -

No events emitted.

- )} -
- -
-

Storage Diffs

- {artifacts.storageDiffs && artifacts.storageDiffs.length > 0 ? ( - - - - Address - Slot - Before - After - - - - {artifacts.storageDiffs.slice(0, 8).map((diff, index) => ( - - {shortenAddress(diff.address)} - {diff.slot ?? diff.key ?? "\u2014"} - {diff.before ?? "\u2014"} - {diff.after ?? diff.value ?? "\u2014"} - - ))} - -
- ) : ( -

No storage changes detected.

- )} -
- -
-

Raw Payload

- {artifacts.rawPayload ? ( -
- View JSON -
-              {artifacts.rawPayload}
-            
-
- ) : ( -

Payload unavailable.

- )} -
-
- ); -}; diff --git a/src/components/transaction-builder/types.ts b/src/components/transaction-builder/types.ts index 3a89116..34a1260 100644 --- a/src/components/transaction-builder/types.ts +++ b/src/components/transaction-builder/types.ts @@ -2,7 +2,6 @@ import React from "react"; import { EXTENDED_NETWORKS, type ExtendedChain } from "../shared/NetworkSelector"; import { SUPPORTED_CHAINS } from "../../utils/chains"; import type { Chain } from "../../types"; -import type { SimulationCallNode } from "../../utils/simulationArtifacts"; // ---- View mode type ---- export type SimulationViewMode = "builder" | "replay"; @@ -95,8 +94,6 @@ export const replaySectionStyle: React.CSSProperties = { }; // ---- Utility functions ---- -export const EMPTY_CALL_TREE: SimulationCallNode[] = []; - export const defaultReplayNetwork = EXTENDED_NETWORKS.find((network) => network.id === 1) ?? EXTENDED_NETWORKS[0]; diff --git a/src/config/networkConfig.ts b/src/config/networkConfig.ts index 117654d..56d6385 100644 --- a/src/config/networkConfig.ts +++ b/src/config/networkConfig.ts @@ -63,10 +63,6 @@ const CONFIG_VERSION = 3; const DEFAULT_SOURCE_PRIORITY: AbiSourceType[] = ['etherscan', 'sourcify', 'blockscout']; const LEGACY_SOURCE_PRIORITY: AbiSourceType[] = ['sourcify', 'etherscan', 'blockscout']; -// Old storage keys for migration -const OLD_RPC_SETTINGS_KEY = 'web3-toolkit:user-rpc-settings'; -const OLD_UNIVERSAL_API_KEYS_KEY = 'web3-toolkit-universal-api-keys'; - // Fields that count as secrets and are stored outside the public config blob. const SECRET_FIELDS = [ 'alchemyApiKey', @@ -332,78 +328,12 @@ const INFURA_ENDPOINTS: Record string> = { const PUBLIC_RPC_FALLBACKS: Record = PUBLIC_RPC_MAP; -interface OldRpcSettings { - mode?: RpcProviderMode; - alchemyKey?: string; - infuraKey?: string; - genericUrl?: string; - etherscanKey?: string; -} - -interface OldUniversalApiKeys { - ETHERSCAN?: string; - BLOCKSCOUT?: string; -} - -function migrateFromOldSettings(): NetworkConfig | null { - if (typeof window === 'undefined') return null; - - const oldRpcRaw = localStorage.getItem(OLD_RPC_SETTINGS_KEY); - const oldApiKeysRaw = localStorage.getItem(OLD_UNIVERSAL_API_KEYS_KEY); - - if (!oldRpcRaw && !oldApiKeysRaw) return null; - - let oldRpc: OldRpcSettings = {}; - let oldApiKeys: OldUniversalApiKeys = {}; - - try { - if (oldRpcRaw) oldRpc = JSON.parse(oldRpcRaw); - } catch { - // ignore parse errors - } - - try { - if (oldApiKeysRaw) oldApiKeys = JSON.parse(oldApiKeysRaw); - } catch { - // ignore parse errors - } - - // Merge old settings into new format - const migrated: NetworkConfig = { - ...DEFAULT_CONFIG, - rpcMode: oldRpc.mode ?? 'DEFAULT', - alchemyApiKey: oldRpc.alchemyKey?.trim() || undefined, - infuraProjectId: oldRpc.infuraKey?.trim() || undefined, - customRpcUrl: oldRpc.genericUrl?.trim() || undefined, - etherscanApiKey: oldRpc.etherscanKey?.trim() || oldApiKeys.ETHERSCAN?.trim() || undefined, - etherscanKeyMode: - oldRpc.etherscanKey?.trim() || oldApiKeys.ETHERSCAN?.trim() - ? 'personal' - : 'default', - rememberPersonalEtherscanKey: false, - blockscoutApiKey: oldApiKeys.BLOCKSCOUT?.trim() || undefined, - }; - - // Save migrated config: non-sensitive config in localStorage, secrets in mode-specific storage - writeSecrets(extractSecrets(migrated), migrated); - localStorage.setItem(STORAGE_KEY, JSON.stringify(stripSecrets(migrated))); - - // Clean up old keys - localStorage.removeItem(OLD_RPC_SETTINGS_KEY); - localStorage.removeItem(OLD_UNIVERSAL_API_KEYS_KEY); - - return migrated; -} - function readConfig(): NetworkConfig { if (typeof window === 'undefined') return { ...DEFAULT_CONFIG }; const raw = localStorage.getItem(STORAGE_KEY); if (!raw) { - // Try migrating from old settings - const migrated = migrateFromOldSettings(); - if (migrated) return migrated; // Even with no config blob, persisted secrets may exist const secrets = readSecrets(); return { @@ -701,16 +631,6 @@ export const networkConfigManager = { return !!(config.infuraProjectId?.trim() && INFURA_ENDPOINTS[chainId]); }, - /** - * Get supported chain IDs for a provider - */ - getSupportedChains(provider: 'alchemy' | 'infura'): number[] { - if (provider === 'alchemy') { - return Object.keys(ALCHEMY_ENDPOINTS).map(Number); - } - return Object.keys(INFURA_ENDPOINTS).map(Number); - }, - /** * Clear all settings and reset to defaults */ diff --git a/src/contexts/SimulationContext.tsx b/src/contexts/SimulationContext.tsx index 9a02a69..57f2c70 100644 --- a/src/contexts/SimulationContext.tsx +++ b/src/contexts/SimulationContext.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useContext, useState, useCallback, useEffect, useMemo } from "react"; +import React, { createContext, useContext, useState, useCallback, useMemo } from "react"; import type { SimulationResult } from "../types/transaction"; import type { TraceContract } from "../utils/traceAddressCollector"; import type { DecodedTraceRow } from "../utils/traceDecoder"; @@ -116,8 +116,6 @@ const SimulationContext = createContext( undefined ); -const STORAGE_KEY = "web3-toolkit:simulation-state"; - export const SimulationProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { @@ -130,17 +128,6 @@ export const SimulationProvider: React.FC<{ children: React.ReactNode }> = ({ // Decoded trace metadata - persisted separately to survive page refresh const [decodedTraceMeta, setDecodedTraceMetaState] = useState(null); - // Clear old localStorage data on mount to free space - useEffect(() => { - if (typeof window !== "undefined") { - try { - localStorage.removeItem(STORAGE_KEY); - } catch { - // Ignore errors - } - } - }, []); - const setSimulation = useCallback((result: SimulationResult, contractCtx?: SimulationContractContext, options?: SetSimulationOptions) => { let nextResult = result; if (result?.rawTrace && typeof result.rawTrace === 'object') { diff --git a/src/contexts/debug/structStorageDecoding.ts b/src/contexts/debug/structStorageDecoding.ts index abae322..99eb063 100644 --- a/src/contexts/debug/structStorageDecoding.ts +++ b/src/contexts/debug/structStorageDecoding.ts @@ -441,7 +441,7 @@ export async function fillUnreadFieldsFromStorage( slotValue = slotCache.get(slotKey)!; debugLog(`[fillUnreadFieldsFromStorage] Using cached slot value for 0x${slotKey}`); } else { - let slotValueHex = await debugBridgeService.getStorage(sessionId, snapshotId, absoluteSlot); + const slotValueHex = await debugBridgeService.getStorage(sessionId, snapshotId, absoluteSlot); if (!slotValueHex) { debugLog(`[fillUnreadFieldsFromStorage] No value returned for slot 0x${slotKey}`); continue; diff --git a/src/services/DebugBridgeService.ts b/src/services/DebugBridgeService.ts index 6efb0dc..e05a604 100644 --- a/src/services/DebugBridgeService.ts +++ b/src/services/DebugBridgeService.ts @@ -57,15 +57,6 @@ type StorageTouchedResult = Record; }>>; -type StorageProofResult = { - storageProof: Array<{ key: string; value: string; proof: string[] }>; -}; - -type StorageRangeAtResult = { - storage: Record; - nextKey: string | null; -}; - type SerializedBreakpoint = | { loc: { @@ -714,34 +705,6 @@ class DebugBridgeService { } } - /** Read storage directly from blockchain RPC (bypasses EDB snapshots). */ - async getStorageFromRpc( - rpcUrl: string, address: string, slot: string | bigint, blockTag: string | number = 'latest', - ): Promise { - try { - const slotHex = typeof slot === 'bigint' - ? '0x' + slot.toString(16).padStart(64, '0') - : slot.startsWith('0x') ? slot : '0x' + slot; - const blockHex = typeof blockTag === 'number' ? '0x' + blockTag.toString(16) : blockTag; - const response = await fetch(rpcUrl, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ jsonrpc: '2.0', method: 'eth_getStorageAt', params: [address, slotHex, blockHex], id: 1 }), - signal: AbortSignal.timeout(30_000), - }); - if (!response.ok) return null; - const data = await response.json(); - if (data.error) return null; - const result = data.result as string; - if (!result) return null; - let hex = result.startsWith('0x') ? result.slice(2) : result; - hex = hex.padStart(64, '0'); - return '0x' + hex; - } catch { - return null; - } - } - /** * Get breakpoint hits */ @@ -796,50 +759,6 @@ class DebugBridgeService { return response.json(); } - /** Generic RPC call to any Ethereum JSON-RPC endpoint. */ - async callRpcMethod(rpcUrl: string, method: string, params: unknown[] = []): Promise { - const response = await fetch(rpcUrl, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ jsonrpc: '2.0', method, params, id: 1 }), - signal: AbortSignal.timeout(30_000), - }); - if (!response.ok) throw new Error(`RPC request failed: ${response.statusText}`); - const data = await response.json(); - if (data.error) throw new Error(data.error.message || JSON.stringify(data.error)); - return data.result; - } - - /** Get storage proof via eth_getProof for selected storage keys. */ - async getStorageProofFromRpc( - rpcUrl: string, address: string, storageKeys: string[], blockTag: string | number = 'latest', - ): Promise { - try { - const blockHex = typeof blockTag === 'number' ? '0x' + blockTag.toString(16) : blockTag; - const result = await this.callRpcMethod(rpcUrl, 'eth_getProof', [address, storageKeys, blockHex]); - return result as StorageProofResult; - } catch (err) { - console.error('[getStorageProofFromRpc] Error:', err); - return null; - } - } - - /** Page through storage via debug_storageRangeAt (Geth-compatible nodes only). */ - async getStorageRangeAtFromRpc( - rpcUrl: string, blockHash: string, txIndex: number, - address: string, keyStart: string, maxResult: number, - ): Promise { - try { - const result = await this.callRpcMethod(rpcUrl, 'debug_storageRangeAt', [ - blockHash, txIndex, address, keyStart, maxResult, - ]); - return result as StorageRangeAtResult; - } catch (err) { - console.error('[getStorageRangeAtFromRpc] Error:', err); - return null; - } - } - /** * Get source code for a contract address */ @@ -891,18 +810,6 @@ class DebugBridgeService { } } - /** - * Get snapshot count for a session - */ - async getSnapshotCount(sessionId: string): Promise { - try { - const result = await this.rpcCall(sessionId, 'edb_getSnapshotCount', []); - return (result as number) || 0; - } catch { - return 0; - } - } - // =========================================================================== // Async Debug Preparation // =========================================================================== diff --git a/src/styles/CompactArrayStyles.css b/src/styles/CompactArrayStyles.css index 21acb3c..1ef9bc3 100644 --- a/src/styles/CompactArrayStyles.css +++ b/src/styles/CompactArrayStyles.css @@ -44,124 +44,11 @@ margin-left: auto; } -.compact-array-remove.inline-action-icon { - background: rgba(239, 68, 68, 0.12); - color: #f87171; -} - -.compact-array-remove.inline-action-icon:hover, -.compact-array-remove.inline-action-icon:focus-visible, -.compact-array-remove.inline-action-icon.is-active { - background: rgba(239, 68, 68, 0.24); - color: #fecaca; -} - /* Compact Icon Buttons */ -.compact-icon-btn { - width: 28px; - height: 28px; - padding: 0; - display: flex; - align-items: center; - justify-content: center; - border: 1px solid #444; - border-radius: 6px; - background: rgba(255, 255, 255, 0.08); - color: #ccc; - cursor: pointer; - transition: all 0.2s ease; - position: relative; -} /* Symbol icon styling */ -.compact-icon-btn { - font-size: 15px; - line-height: 1; - font-weight: bold; - font-family: monospace; -} - -.compact-icon-btn:hover { - transform: translateY(-1px); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); -} - -.compact-icon-btn.add-btn { - border-color: #28a745; - color: #28a745; -} - -.compact-icon-btn.add-btn:hover { - background: rgba(40, 167, 69, 0.2); - border-color: #28a745; - color: #fff; -} - -.compact-icon-btn.remove-last-btn { - border-color: #ffc107; - color: #ffc107; -} - -.compact-icon-btn.remove-last-btn:hover { - background: rgba(255, 193, 7, 0.2); - border-color: #ffc107; - color: #fff; -} - -.compact-icon-btn.clear-all-btn { - border-color: #dc3545; - color: #dc3545; -} - -.compact-icon-btn.clear-all-btn:hover { - background: rgba(220, 53, 69, 0.2); - border-color: #dc3545; - color: #fff; -} - -.compact-icon-btn.shuffle-btn { - border-color: #6f42c1; - color: #6f42c1; -} - -.compact-icon-btn.shuffle-btn:hover { - background: rgba(111, 66, 193, 0.2); - border-color: #6f42c1; - color: #fff; -} /* Tooltip styling (using native tooltips) */ -.compact-icon-btn:hover::after { - content: attr(title); - position: absolute; - bottom: 100%; - left: 50%; - transform: translateX(-50%); - background: rgba(0, 0, 0, 0.9); - color: #fff; - padding: 4px 8px; - border-radius: 4px; - font-size: 12px; - white-space: nowrap; - z-index: 1000; - margin-bottom: 4px; - opacity: 0; - animation: tooltipFadeIn 0.2s ease-out 0.5s forwards; -} - -.compact-icon-btn:hover::before { - content: ""; - position: absolute; - bottom: 100%; - left: 50%; - transform: translateX(-50%); - border: 4px solid transparent; - border-top-color: rgba(0, 0, 0, 0.9); - z-index: 1000; - margin-bottom: -4px; - opacity: 0; - animation: tooltipFadeIn 0.2s ease-out 0.5s forwards; -} @keyframes tooltipFadeIn { from { @@ -174,144 +61,9 @@ } } -.compact-inputs-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); - gap: 8px; - max-height: 200px; - overflow-y: auto; - padding: 8px; - background: rgba(0, 0, 0, 0.2); - border-radius: 6px; - border: 1px solid #333; -} - -.compact-input-item { - display: flex; - align-items: center; - gap: 6px; - padding: 6px; - background: rgba(255, 255, 255, 0.03); - border-radius: 4px; - border: 1px solid #444; -} - -.compact-input-label { - font-size: 12px; - color: #888; - font-weight: 500; - min-width: 24px; - text-align: center; -} - -.compact-input { - flex: 1; - padding: 4px 6px; - font-size: 13px; - background: rgba(255, 255, 255, 0.05); - border: 1px solid #555; - border-radius: 3px; - color: #fff; - min-width: 0; -} - -.compact-input:focus { - outline: none; - border-color: #007bff; - box-shadow: 0 0 0 1px rgba(0, 123, 255, 0.2); -} - -.compact-input.error { - border-color: #dc3545; - box-shadow: 0 0 0 1px rgba(220, 53, 69, 0.2); -} - -.compact-remove-item-btn { - width: 18px; - height: 18px; - padding: 0; - background: rgba(220, 53, 69, 0.1); - border: 1px solid rgba(220, 53, 69, 0.3); - border-radius: 3px; - color: #dc3545; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.2s ease; - flex-shrink: 0; -} - -.compact-remove-item-btn { - font-size: 13px; - line-height: 1; - font-weight: bold; - font-family: monospace; -} - -.compact-remove-item-btn:hover { - background: rgba(220, 53, 69, 0.3); - border-color: #dc3545; - color: #fff; - transform: scale(1.1); -} - -.compact-error { - position: absolute; - top: 100%; - left: 0; - right: 0; - font-size: 11px; - color: #dc3545; - background: rgba(220, 53, 69, 0.1); - padding: 2px 4px; - border-radius: 2px; - z-index: 10; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.compact-input-item { - position: relative; -} - /* Nested Array Styles */ -.nested-array-row { - margin-bottom: 16px; -} - -.nested-array-container { - margin-top: 8px; -} - -.nested-sub-array { - margin: 8px 0; - padding: 8px; - background: rgba(255, 255, 255, 0.02); - border: 1px solid #444; - border-radius: 6px; -} - -.sub-array-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 8px; - padding-bottom: 6px; - border-bottom: 1px solid #555; -} - -.sub-array-label { - font-size: 13px; - color: #ccc; - font-weight: 500; -} /* Animation for smooth transitions */ -.compact-input-item { - animation: slideIn 0.2s ease-out; -} @keyframes slideIn { from { @@ -326,9 +78,6 @@ /* Responsive adjustments */ @media (max-width: 767px) { - .compact-inputs-grid { - grid-template-columns: 1fr; - } .array-preview-content { flex-direction: column; diff --git a/src/styles/ContractComponents.css b/src/styles/ContractComponents.css deleted file mode 100644 index 1574903..0000000 --- a/src/styles/ContractComponents.css +++ /dev/null @@ -1,2 +0,0 @@ -/* Contract Component Styles - Cyberpunk Theme */ -/* All legacy classes removed — component now uses Tailwind exclusively */ diff --git a/src/styles/ExecutionStackTrace.css b/src/styles/ExecutionStackTrace.css index 70c8cad..036a63f 100644 --- a/src/styles/ExecutionStackTrace.css +++ b/src/styles/ExecutionStackTrace.css @@ -264,19 +264,10 @@ } /* For string values */ -.exec-io-value:has(> .exec-io-string) { - color: #10b981; -} /* For numeric values */ -.exec-io-value:has(> .exec-io-number) { - color: #f59e0b; -} /* For address values */ -.exec-io-value:has(> .exec-io-address) { - color: #d4d4d4; -} /* Function signature styling */ .exec-io-function-name { @@ -330,11 +321,6 @@ border-radius: 10px; } -.exec-trace-header { - padding: 0 0 12px 0; - border-bottom: none; -} - /* ============================================ TOOLBAR ============================================ */ @@ -620,9 +606,6 @@ } /* In virtualized mode, enforce fixed height */ -.exec-trace-row--virtualized { - height: 22px; -} .exec-trace-row::before { content: ""; @@ -664,19 +647,6 @@ } /* Step number - hidden by default, used for reference */ -.exec-trace-row__step { - display: none; -} - -.exec-trace-row--current .exec-trace-row__step { - color: #4a5fff; - font-weight: 700; -} - -.exec-trace-row--error .exec-trace-row__step { - color: #ef4444; - font-weight: 700; -} /* Content - layout with fixed + flexible columns */ .exec-trace-row__content { @@ -732,10 +702,6 @@ /* Depth indent - Column 3 (variable width based on depth) */ /* Comes BEFORE chevron */ -.exec-trace-depth-indent { - flex-shrink: 0; - margin-right: 0; -} /* Chevron - Column 4 (fixed width) */ /* Details wrapper - Column 5 (flexible content area) */ @@ -820,20 +786,8 @@ } /* Rails overlay - positioned behind rows */ -.exec-rails-overlay { - position: absolute; - top: 0; - pointer-events: none; /* Don't block clicks on rows */ - z-index: 2; /* Above row backgrounds but below sticky columns (z-index: 3) */ -} /* Individual continuous rail - a single vertical line spanning multiple rows */ -.exec-continuous-rail { - position: absolute; - width: 1px; - background: rgba(100, 116, 139, 0.8); /* More visible gray */ - border-radius: 1px; -} /* Spacer in content flow - reserves space for depth indentation */ .exec-trace-depth-spacer { @@ -843,13 +797,6 @@ position: relative; } -.exec-trace-entry-indicator { - color: #f59e0b; - font-weight: 600; - font-size: 13px; - margin-right: 4px; -} - .exec-trace-sender { color: #60a5fa; font-size: 12px; @@ -904,12 +851,6 @@ white-space: nowrap; } -.exec-trace-selector { - color: #6b7280; - font-size: 12px; - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; -} - /* Function args display - show full values */ .exec-trace-args { color: #e5e7eb; @@ -938,25 +879,6 @@ padding: 0; } -.exec-trace-contract { - color: #d4d4d4; -} - -.exec-trace-data { - color: #9a9aac; - font-size: 13px; -} - -.exec-trace-pc { - color: #6a6a7a; - font-size: 12px; -} - -.exec-trace-slot { - color: #f6f6fb; - font-size: 13px; -} - /* ============================================ BADGES - Fixed-width ============================================ */ @@ -984,17 +906,8 @@ } /* Destination indicator for JUMP•D */ -.opcode-dest-indicator { - color: #22c55e; - font-weight: 700; - margin-left: 1px; -} /* Storage operation badge styling - solid backgrounds for sticky columns */ -.exec-trace-opcode-badge.storage-op { - background: #2c1f3f; - color: #a855f7; -} /* Opcode coloring - BRIGHT distinct colors for visibility */ @@ -1122,115 +1035,26 @@ ============================================ */ /* Address values (0x...) */ -.exec-data-address { - color: #d4d4d4; - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; -} /* Numeric values */ -.exec-data-number { - color: #a78bfa; - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; -} /* Boolean values */ -.exec-data-bool-true { - color: #10b981; - font-weight: 600; -} - -.exec-data-bool-false { - color: #ef4444; - font-weight: 600; -} /* Bytes/hex data */ -.exec-data-bytes { - color: #9ca3af; - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; -} /* String values */ -.exec-data-string { - color: #34d399; -} /* Storage slot keys */ -.exec-storage-slot { - color: #8b5cf6; - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; -} /* Storage values */ -.exec-storage-value { - color: #f59e0b; - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; -} /* Storage writes: before -> after */ -.exec-storage-before { - color: #ef4444; - text-decoration: line-through; - opacity: 0.7; -} - -.exec-storage-after { - color: #10b981; -} /* Function parameters */ -.exec-param-name { - color: #60a5fa; - font-style: italic; -} - -.exec-param-value { - color: #e5e7eb; -} /* Error messages */ -.exec-error-msg { - color: #ef4444; - background: rgba(239, 68, 68, 0.1); - padding: 2px 6px; - border-radius: 3px; -} /* Gas values */ -.exec-gas-value { - color: #fbbf24; - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; -} -.exec-trace-storage-details { - font-family: "JetBrains Mono", "SF Mono", Monaco, monospace; - font-size: 12px; - color: #d4d4d4; - margin-left: 4px; - flex: 1; - white-space: nowrap; -} - -.exec-trace-event-badge { - background: rgba(34, 211, 238, 0.15); - color: #d4d4d4; - padding: 2px 8px; - border-radius: 4px; - font-size: 12px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.3px; -} - -.exec-trace-storage-badge { - background: rgba(168, 85, 247, 0.15); - color: #a855f7; - padding: 2px 8px; - border-radius: 4px; - font-size: 12px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.3px; -} .exec-trace-event-name { color: #f6f6fb; @@ -1374,11 +1198,6 @@ .exec-trace-row { flex-wrap: wrap; } - - .exec-trace-row__step { - min-width: 50px; - padding-right: 12px; - } } /* ============================================ @@ -1429,9 +1248,6 @@ } /* Equals sign */ -.exec-trace-arg-equals { - color: #6b7280; -} /* Argument value - purple/violet for values */ .exec-trace-arg-value { @@ -1440,17 +1256,8 @@ } /* Separator between args */ -.exec-trace-arg-separator { - color: #6b7280; -} /* Truncated indicator */ -.exec-trace-truncated { - color: #f97316; - font-size: 11px; - font-style: italic; - margin-left: 4px; -} /* Raw log data when not decoded - show full values */ .exec-trace-log-raw { diff --git a/src/styles/SharedComponents.css b/src/styles/SharedComponents.css index 8feb549..16d0fdb 100644 --- a/src/styles/SharedComponents.css +++ b/src/styles/SharedComponents.css @@ -161,118 +161,6 @@ } /* Transaction Builder mode toggle */ -.interaction-mode-toggle { - display: inline-flex; - border: 1px solid var(--border-secondary); - border-radius: var(--radius-full); - overflow: hidden; - margin-bottom: var(--space-3); -} - -.interaction-mode-toggle button { - background: transparent; - color: var(--text-secondary); - border: none; - padding: var(--space-2) var(--space-4); - font-size: var(--text-sm); - cursor: pointer; - transition: background var(--transition-fast), color var(--transition-fast); -} - -.interaction-mode-toggle button:hover { - background: var(--bg-secondary); - color: var(--text-primary); -} - -.interaction-mode-toggle button.active { - background: var(--accent-primary-20); - color: var(--text-primary); -} - -.mode-description { - margin: 0 0 var(--space-4); - color: var(--text-muted); - font-size: var(--text-sm); -} - -.simulation-mode-config { - display: flex; - flex-direction: column; - gap: var(--space-2); - padding: var(--space-3); - border: 1px dashed var(--border-secondary); - border-radius: var(--radius-lg); - background: var(--bg-secondary); - margin-bottom: var(--space-4); -} - -.simulation-mode-config label { - display: flex; - align-items: center; - gap: var(--space-2); - font-size: var(--text-sm); - color: var(--text-secondary); -} - -.simulation-mode-config input[type="radio"] { - accent-color: var(--accent-primary); -} - -.onchain-hash-input { - width: 100%; - border: 1px solid var(--border-secondary); - border-radius: var(--radius-md); - padding: var(--space-2) var(--space-3); - font-family: var(--font-mono); - background: var(--bg-card); - color: var(--text-primary); -} - -.simulation-warnings { - margin-top: var(--space-3); - padding: var(--space-3); - border: 1px solid rgba(250, 204, 21, 0.35); - border-radius: var(--radius-md); - background: rgba(250, 204, 21, 0.08); -} - -.simulation-warnings h4 { - margin-bottom: var(--space-2); - font-size: var(--text-sm); - color: var(--text-primary); -} - -.simulation-warnings ul { - margin: 0; - padding-left: var(--space-4); - color: var(--text-secondary); - font-size: var(--text-sm); -} - -.simulation-error { - margin-top: var(--space-2); - color: var(--error); - font-size: var(--text-sm); -} - -.simulation-revert { - margin-top: var(--space-2); - font-size: var(--text-sm); - color: var(--text-secondary); -} - -.simulation-trace { - margin-top: var(--space-2); - font-size: var(--text-sm); - color: var(--text-secondary); -} - -.simulation-actions { - display: flex; - flex-wrap: wrap; - gap: var(--space-3); - align-items: center; -} .simulation-summary-grid { display: grid; @@ -281,125 +169,6 @@ margin-bottom: var(--space-3); } -.simulation-label { - display: block; - font-size: var(--text-xs); - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--text-muted); - margin-bottom: var(--space-1); -} - -.simulation-raw-trace { - margin-top: var(--space-3); -} - -.simulation-raw-trace summary { - cursor: pointer; - font-size: var(--text-sm); - color: var(--accent-primary); - margin-bottom: var(--space-2); -} - -.simulation-raw-trace pre { - max-height: 320px; - overflow: auto; - background: var(--bg-card); - border: 1px solid var(--border-secondary); - border-radius: var(--radius-md); - padding: var(--space-3); - font-size: var(--text-xs); -} - -.segmented-option-heading { - display: inline-flex; - align-items: center; - gap: var(--space-2); -} - -.builder-header { - margin-bottom: var(--space-4); -} - -.builder-header__top { - display: flex; - align-items: center; - justify-content: space-between; - gap: var(--space-3); -} - -.simulation-wallet-trigger .wallet-inline-wrapper { - margin: 0; -} - -.simulation-wallet-trigger .wallet-icon-inline { - width: 36px; - height: 36px; -} - -.saved-contracts-grid { - display: grid; - gap: var(--space-2); - margin-top: var(--space-3); - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); -} - -.saved-contracts-grid .glass-button { - width: 100%; - justify-content: flex-start; -} - -.saved-contract-content { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: var(--space-1); -} - -.saved-contract-name { - font-weight: var(--font-weight-medium); - font-size: var(--text-sm); -} - -.saved-contract-meta { - display: flex; - flex-wrap: wrap; - gap: var(--space-2); - font-size: var(--text-xs); - color: var(--text-muted); -} - -.saved-contract-meta--subline { - opacity: 0.85; -} - -.saved-contract-meta--subline span { - display: flex; - align-items: center; - gap: var(--space-1); -} - -.empty-state { - padding: var(--space-3); - border: 1px dashed var(--border-secondary); - border-radius: var(--radius-md); - color: var(--text-muted); - font-size: var(--text-sm); -} - -.function-argument-panel { - margin-top: var(--space-4); - display: flex; - flex-direction: column; - gap: var(--space-3); -} - -.builder-header h2 { - font-size: var(--text-2xl); - font-weight: var(--font-weight-semibold); - margin-bottom: var(--space-2); -} - .simulation-helper-card { display: flex; gap: var(--space-3); @@ -425,239 +194,12 @@ margin: 0; } -.simulation-shell { - display: flex; - flex-direction: column; - gap: var(--space-4); - border: 1px solid rgba(148, 163, 184, 0.25); - border-radius: var(--radius-xl); - background: rgba(15, 23, 42, 0.65); - padding: var(--space-4); - box-shadow: 0 12px 24px rgba(2, 6, 23, 0.45); -} - -.simulation-shell__summary { - display: flex; - flex-direction: column; - gap: var(--space-3); -} - -.simulation-status-badge { - display: inline-flex; - align-items: center; - gap: var(--space-2); - padding: 0.35rem 0.75rem; - border-radius: var(--radius-full); - font-size: 0.8125rem; - font-weight: var(--font-weight-semibold); - letter-spacing: 0.04em; - text-transform: uppercase; - background: rgba(59, 130, 246, 0.12); - color: #bfdbfe; -} - -.simulation-status-badge--success { - background: rgba(22, 163, 74, 0.18); - color: #bbf7d0; -} - -.simulation-status-badge--error { - background: rgba(239, 68, 68, 0.18); - color: #fecaca; -} - -.simulation-status-dot { - width: 10px; - height: 10px; - border-radius: 50%; - background: currentColor; -} - -.simulation-metrics-grid { - display: grid; - gap: var(--space-3); - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); -} - -.simulation-metric { - color: #e2e8f0; - font-family: var(--font-mono); - font-size: 0.9625rem; -} - -.simulation-chip-row { - display: flex; - flex-wrap: wrap; - gap: var(--space-2); -} - -.simulation-chip { - display: inline-flex; - align-items: center; - gap: var(--space-1); - border-radius: var(--radius-full); - padding: 0.2rem 0.6rem; - font-size: 0.7625rem; - text-transform: uppercase; - letter-spacing: 0.06em; - background: rgba(148, 163, 184, 0.18); - color: rgba(226, 232, 240, 0.9); -} - -.simulation-chip--warning { - background: rgba(250, 204, 21, 0.15); - color: #facc15; -} - -.simulation-chip--info { - background: rgba(59, 130, 246, 0.15); - color: #93c5fd; -} - -.simulation-status-alert { - display: flex; - gap: var(--space-2); - align-items: center; - padding: var(--space-3); - border-radius: var(--radius-lg); - border: 1px solid rgba(248, 113, 113, 0.35); - background: rgba(248, 113, 113, 0.12); - color: #fecaca; - font-size: var(--text-sm); -} - -.simulation-status-alert--muted { - border-color: rgba(148, 163, 184, 0.25); - background: rgba(148, 163, 184, 0.12); - color: rgba(226, 232, 240, 0.85); -} - -.simulation-shell__panels { - display: grid; - gap: var(--space-3); - grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); -} - -.simulation-panel { - display: flex; - flex-direction: column; - gap: var(--space-2); - padding: var(--space-3); - border-radius: var(--radius-lg); - border: 1px solid rgba(148, 163, 184, 0.2); - background: rgba(15, 23, 42, 0.55); - min-height: 140px; -} - -.simulation-panel--raw { - grid-column: 1 / -1; -} - -.simulation-panel__header { - display: flex; - align-items: center; - justify-content: space-between; - font-weight: var(--font-weight-semibold); - color: #e2e8f0; -} - -.simulation-panel__description, -.simulation-panel__placeholder, .simulation-panel__hint { font-size: var(--text-sm); color: rgba(203, 213, 225, 0.85); margin: 0; } -.simulation-panel__placeholder { - font-style: italic; -} - -.simulation-panel__pre { - max-height: 320px; - overflow: auto; - padding: var(--space-3); - border-radius: var(--radius-md); - border: 1px solid rgba(71, 85, 105, 0.35); - background: rgba(15, 23, 42, 0.85); - font-size: 0.8125rem; - font-family: var(--font-mono); -} - -.simulation-changes-list { - list-style: none; - margin: 0; - padding: 0; - display: grid; - gap: var(--space-2); -} - -.simulation-changes-list li { - display: grid; - gap: var(--space-2); - grid-template-columns: 0.9fr 1fr 1.2fr; - align-items: center; - font-size: 0.8625rem; - color: #e2e8f0; -} - -.simulation-change-amount { - font-family: var(--font-mono); - color: #bfdbfe; -} - -.simulation-change-asset { - font-weight: var(--font-weight-medium); -} - -.simulation-change-address { - font-family: var(--font-mono); - font-size: 0.8125rem; - color: rgba(148, 163, 184, 0.8); -} - -.simulation-storage-list { - list-style: none; - margin: var(--space-3) 0 0; - padding: 0; - display: grid; - gap: var(--space-2); -} - -.simulation-storage-list li { - display: grid; - gap: var(--space-2); - grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); - align-items: flex-start; - background: rgba(15, 23, 42, 0.45); - border: 1px solid rgba(148, 163, 184, 0.18); - border-radius: var(--radius-md); - padding: var(--space-2); -} - -.simulation-storage-address { - font-weight: var(--font-weight-medium); - color: #e2e8f0; - font-family: var(--font-mono); - font-size: 0.8125rem; - word-break: break-all; -} - -.simulation-storage-slot { - font-size: 0.8125rem; - color: rgba(148, 163, 184, 0.85); - font-family: var(--font-mono); -} - -.simulation-storage-values { - grid-column: 1 / -1; - display: flex; - gap: var(--space-4); - flex-wrap: wrap; - font-size: 0.8125rem; - color: rgba(203, 213, 225, 0.85); -} - .simulation-call-tree { list-style: none; margin: 0; @@ -697,71 +239,6 @@ margin-left: var(--space-2); } -.simulation-events-list { - list-style: none; - margin: 0; - padding: 0; - display: grid; - gap: var(--space-2); -} - -.simulation-events-list li { - background: rgba(15, 23, 42, 0.45); - border: 1px solid rgba(148, 163, 184, 0.18); - border-radius: var(--radius-md); - padding: var(--space-2); - display: grid; - gap: var(--space-1); -} - -.simulation-event-name { - font-weight: var(--font-weight-medium); - color: #e1e7ff; - font-size: 0.9125rem; -} - -.simulation-event-meta { - display: flex; - flex-wrap: wrap; - gap: var(--space-2); - font-size: 0.8125rem; - color: rgba(203, 213, 225, 0.75); -} - -.simulation-event-signature { - font-family: var(--font-mono); - color: rgba(59, 130, 246, 0.95); -} - -.simulation-panel__raw-return { - display: flex; - flex-direction: column; - gap: var(--space-1); - margin-bottom: var(--space-2); -} - -.simulation-panel__pre--inline { - display: inline-block; - max-width: 100%; - white-space: pre-wrap; - word-break: break-all; - margin: 0; - padding: 0.35rem 0.5rem; -} - -.simulation-status-hint { - display: flex; - align-items: center; - gap: var(--space-2); - margin-top: var(--space-3); - color: var(--text-muted); - font-size: var(--text-sm); -} - -.simulation-status-hint svg { - flex-shrink: 0; -} - /* Copyable Result */ .copyable-result { position: relative; @@ -879,64 +356,6 @@ content: none !important; } -.inline-action-icon { - background: transparent !important; - box-shadow: none !important; - border: none; - padding: 0; - cursor: pointer; -} - -.inline-action-icon.is-active { - background: transparent !important; - box-shadow: none !important; - - background: transparent !important; - box-shadow: none !important; - color: #f8fafc; -} - -.copy-feedback-text { - font-size: var(--text-xs); - color: var(--text-muted); - min-height: 18px; - transition: color var(--transition-fast); -} - -.copy-feedback-text.is-success { - color: #4ade80; -} - -.copy-feedback-text.is-error { - color: #fca5a5; -} - -.copyable-result-copy-btn { - display: inline-flex; - align-items: center; - gap: var(--space-1); - padding: 4px 10px; - border-radius: var(--radius-md); - border: 1px solid rgba(148, 163, 184, 0.35); - background: rgba(148, 163, 184, 0.15); - color: var(--text-secondary); - cursor: pointer; - font-size: var(--text-xs); - transition: all var(--transition-fast); -} - -.copyable-result-copy-btn:hover { - background: rgba(59, 130, 246, 0.18); - border-color: rgba(59, 130, 246, 0.4); - color: var(--text-primary); -} - -.copyable-result-copy-btn.copied { - background: rgba(34, 197, 94, 0.2); - border-color: rgba(34, 197, 94, 0.4); - color: #22c55e; -} - .copyable-result-content { white-space: pre-wrap; word-break: break-word; @@ -963,80 +382,6 @@ } /* Copyable key/value rows */ -.copyable-kv { - background: rgba(15, 23, 42, 0.6); - border: 1px solid rgba(148, 163, 184, 0.2); - border-radius: var(--radius-md); - padding: var(--space-3); - margin-bottom: var(--space-2); -} - -.copyable-kv:last-of-type { - margin-bottom: 0; -} - -.copyable-kv-header { - display: flex; - align-items: center; - justify-content: space-between; - gap: var(--space-3); - margin-bottom: var(--space-2); - color: var(--text-secondary); - font-size: var(--text-sm); -} - -.copyable-kv-label { - font-weight: var(--font-weight-medium); -} - -.copyable-kv-meta { - display: flex; - align-items: center; - gap: var(--space-2); -} - -.copyable-kv-type { - color: var(--text-tertiary); - font-size: var(--text-xs); -} - -.copyable-kv-copy { - display: inline-flex; - align-items: center; - gap: var(--space-1); - padding: 3px 8px; - border-radius: var(--radius-sm); - border: 1px solid rgba(148, 163, 184, 0.25); - background: rgba(148, 163, 184, 0.15); - color: var(--text-secondary); - cursor: pointer; - font-size: var(--text-xs); - transition: all var(--transition-fast); -} - -.copyable-kv-copy:hover { - background: rgba(59, 130, 246, 0.18); - border-color: rgba(59, 130, 246, 0.4); - color: var(--text-primary); -} - -.copyable-kv-copy.copied { - background: rgba(34, 197, 94, 0.22); - border-color: rgba(34, 197, 94, 0.45); - color: #22c55e; -} - -.copyable-kv-value { - font-family: var(--font-mono); - font-size: var(--text-sm); - color: var(--text-primary); - white-space: pre-wrap; - word-break: break-word; -} - -.contract-parameter { - width: 100%; -} .shared-card-padding-none { padding: 0; @@ -1071,65 +416,6 @@ } /* Badge Component Styles */ -.shared-badge { - display: inline-flex; - align-items: center; - font-weight: var(--font-weight-medium); - border: 1px solid; - border-radius: var(--radius-full); - transition: all var(--transition-normal); -} - -.shared-badge-sm { - padding: calc(var(--space-1) / 2) var(--space-2); - font-size: var(--text-xs); -} - -.shared-badge-md { - padding: var(--space-1) var(--space-3); - font-size: var(--text-sm); -} - -.shared-badge-lg { - padding: calc(var(--space-3) / 2) var(--space-4); - font-size: var(--text-base); -} - -.shared-badge-default { - background: var(--bg-tertiary); - color: var(--text-secondary); - border-color: var(--border-primary); -} - -.shared-badge-success { - background: rgba(57, 255, 20, 0.2); - color: var(--success); - border-color: rgba(57, 255, 20, 0.3); -} - -.shared-badge-warning { - background: rgba(255, 255, 0, 0.2); - color: var(--warning); - border-color: rgba(255, 255, 0, 0.3); -} - -.shared-badge-error { - background: rgba(255, 0, 64, 0.2); - color: var(--error); - border-color: rgba(255, 0, 64, 0.3); -} - -.shared-badge-info { - background: hsl(var(--primary) / 0.2); - color: var(--info); - border-color: hsl(var(--primary) / 0.3); -} - -.shared-badge-accent { - background: var(--accent-primary-20); - color: var(--accent-primary); - border-color: hsl(var(--primary) / 0.3); -} /* Loading Spinner Styles */ .shared-loading-spinner { @@ -1399,70 +685,6 @@ } /* Error Display Styles */ -.shared-error-inline { - display: flex; - align-items: flex-start; - gap: var(--space-2); - color: var(--error); -} - -.shared-error-icon { - width: 1.25rem; - height: 1.25rem; - margin-top: 0.125rem; - flex-shrink: 0; -} - -.shared-error-content { - flex: 1; -} - -.shared-error-title { - font-size: var(--text-sm); - font-weight: var(--font-weight-medium); -} - -.shared-error-message { - font-size: var(--text-sm); - color: rgba(255, 0, 64, 0.8); - margin-top: var(--space-1); -} - -.shared-error-banner { - background: rgba(255, 0, 64, 0.1); - border: 1px solid rgba(255, 0, 64, 0.3); - border-radius: var(--radius-lg); - padding: var(--space-4); -} - -.shared-error-banner-content { - display: flex; - align-items: center; - gap: var(--space-3); -} - -.shared-error-banner-icon { - width: 1.25rem; - height: 1.25rem; - color: var(--error); - flex-shrink: 0; -} - -.shared-error-banner-text { - flex: 1; -} - -.shared-error-banner-title { - font-size: var(--text-sm); - font-weight: var(--font-weight-medium); - color: var(--error); -} - -.shared-error-banner-message { - font-size: var(--text-sm); - color: rgba(255, 0, 64, 0.8); - margin-top: var(--space-1); -} @keyframes spin { from { diff --git a/src/styles/SimpleGridUI.css b/src/styles/SimpleGridUI.css index 743a955..8809a57 100644 --- a/src/styles/SimpleGridUI.css +++ b/src/styles/SimpleGridUI.css @@ -1,283 +1,8 @@ /* SimpleGridUI Specific Styles */ -.simple-grid-ui { - min-height: 100vh; - background: #0a0a0a; - color: #fff; - padding: 20px; -} - -.simple-grid-header { - text-align: center; - margin-bottom: 40px; -} - -.simple-grid-title { - font-size: 33px; - font-weight: bold; - color: hsl(var(--foreground)); - margin-bottom: 8px; -} - -.simple-grid-subtitle { - color: #888; - font-size: 17px; -} - -.simple-grid-main { - display: grid; - grid-template-columns: minmax(980px, 2fr) minmax(320px, 0.65fr); - gap: 36px; - max-width: 2040px; - margin: 0 auto; -} - -@media (max-width: 1535px) { - .simple-grid-main { - grid-template-columns: minmax(880px, 1.8fr) minmax(300px, 0.75fr); - gap: 28px; - max-width: 1840px; - } -} - -@media (max-width: 1279px) { - .simple-grid-main { - grid-template-columns: minmax(760px, 1.55fr) minmax(280px, 0.85fr); - gap: 24px; - max-width: 1500px; - } -} - -@media (max-width: 1023px) { - .simple-grid-main { - grid-template-columns: 1fr; - max-width: 900px; - } -} - /* Bordered section cards */ -.section-card { - background: transparent; - border: 1px solid hsl(var(--border)); - border-radius: 8px; - padding: 20px; - margin-bottom: 16px; -} - -.section-card-title { - font-size: 17px; - font-weight: 600; - color: hsl(var(--foreground)); - margin-bottom: 16px; - display: flex; - align-items: center; - justify-content: space-between; -} - -.section-card-title .collapse-btn { - background: transparent; - border: none; - color: hsl(var(--muted-foreground)); - cursor: pointer; - padding: 4px; - border-radius: 4px; - transition: background 0.15s ease; -} - -.section-card-title .collapse-btn:hover { - background: hsl(var(--accent)); -} - -.simple-grid-card { - background: transparent; - border: 1px solid hsl(var(--border)); - border-radius: 8px; - padding: 20px; - box-shadow: none; -} - -.simple-grid-section-title { - font-size: 17px; - font-weight: 600; - margin-bottom: 16px; - color: hsl(var(--foreground)); -} - -.selection-card { - border-radius: 8px; - padding: 16px; - margin-bottom: 12px; - cursor: pointer; - transition: all 0.15s ease; - border: 1px solid hsl(var(--border)); - background: transparent; -} - -.selection-card.selected { - background: hsl(var(--primary) / 0.1); - border: 1px solid hsl(var(--primary)); -} - -.selection-card:hover { - border-color: hsl(var(--primary) / 0.5); - background: hsl(var(--accent) / 0.5); -} - -.selection-card.selected:hover { - background: hsl(var(--primary) / 0.15); -} - -.selection-radio { - width: 16px; - height: 16px; - border-radius: 50%; - border: 2px solid #007bff; - display: flex; - align-items: center; - justify-content: center; - background: transparent; -} - -.selection-radio.selected { - background: #007bff; -} - -.selection-radio-dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: #fff; -} - -.selection-content { - display: flex; - align-items: center; - gap: 12px; -} - -.selection-text-primary { - font-weight: 500; -} - -.selection-text-secondary { - font-size: 13px; - color: #888; -} - -.function-search-input { - width: 100%; - padding: 8px 12px; - background: rgba(255, 255, 255, 0.1); - border: 1px solid #333; - border-radius: 6px; - color: #fff; - font-size: 15px; -} - -.function-search-input:focus { - outline: none; - border-color: #007bff; - box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.2); -} - -.function-search-input::placeholder { - color: #666; -} - -.facet-item { - padding: 8px; - margin: 4px 0; - border-radius: 6px; - cursor: pointer; - font-size: 13px; - background: rgba(255, 255, 255, 0.05); - transition: background 0.2s ease; -} - -.facet-item:hover { - background: rgba(255, 255, 255, 0.1); -} - -.facet-item.selected { - background: rgba(0, 123, 255, 0.2); -} - -.facet-name { - font-weight: 500; -} - -.facet-address { - color: #888; - font-size: 11px; -} - -.transaction-params-checkbox { - display: flex; - align-items: center; - gap: 8px; -} - -.transaction-params-checkbox input[type="checkbox"] { - margin: 0; -} - -.transaction-params-checkbox span { - font-size: 15px; -} - -.coming-soon { - font-size: 13px; - color: #888; -} - -.placeholder-content { - text-align: center; - padding: 20px; - color: #888; -} - -.placeholder-icon { - margin-bottom: 12px; - opacity: 0.5; -} - -.placeholder-text { - margin: 0; -} - -.placeholder-subtext { - font-size: 15px; - margin: 8px 0 0 0; -} - -.decoder-section { - max-width: 1400px; - margin: 24px auto 0; -} /* Responsive Design */ -@media (max-width: 767px) { - .simple-grid-main { - grid-template-columns: 1fr; - gap: 16px; - } - - .simple-grid-ui { - padding: 16px; - } - - .simple-grid-card { - padding: 16px; - } - - .simple-grid-title { - font-size: 25px; - } - - .simple-grid-section-title { - font-size: 19px; - } -} /* Animation enhancements */ @keyframes fadeIn { @@ -291,14 +16,6 @@ } } -.simple-grid-card { - animation: fadeIn 0.5s ease-out; -} - -.selection-card { - animation: fadeIn 0.3s ease-out; -} - /* Shimmer animation for loading states */ @keyframes shimmer { 0% { background-position: 200% 0; } @@ -318,36 +35,11 @@ 50% { opacity: 0.5; } } -.loading-pulse { - animation: pulse 2s ease-in-out infinite; -} - /* Loading state improvements */ -.loading-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(39, 5, 5, 0.7); - display: flex; - align-items: center; - justify-content: center; - border-radius: 12px; -} /* Enhanced hover effects - flat design */ -.simple-grid-card:hover { - border-color: hsl(var(--primary) / 0.3); - transition: border-color 0.15s ease; -} /* Better focus states for accessibility — only show on keyboard navigation */ -.function-search-input:focus-visible, -.selection-card:focus-visible { - outline: 2px solid #007bff; - outline-offset: 2px; -} button:focus-visible { outline: 2px solid #007bff; @@ -360,445 +52,42 @@ button:focus-visible { ============================================================================ */ /* Container styles */ -.sgui-container { - color: #fff; - position: relative; -} /* Grid container */ -.sgui-grid-container { - max-width: 1800px; - margin: 0 auto; - padding: 0 20px; -} /* Grid layout */ -.sgui-grid { - display: grid; - grid-template-columns: minmax(420px, 1fr) minmax(420px, 1fr); - gap: 24px; -} - -@media (max-width: 1279px) { - .sgui-grid { - grid-template-columns: 1fr; - } -} /* Contract card */ -.sgui-contract-card { - background: transparent; - border: 1px solid hsl(var(--border)); - border-radius: 12px; - padding: 20px; - min-height: 300px; -} /* Function card */ -.sgui-function-card { - background: transparent; - border: 1px solid hsl(var(--border)); - border-radius: 12px; - padding: 20px; - min-height: 300px; -} /* Card headers */ -.sgui-card-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 16px; -} - -.sgui-card-title { - font-size: 17px; - font-weight: 600; - color: hsl(var(--foreground)); - margin: 0; -} /* Error box */ -.sgui-error-box { - padding: 12px; - background: rgba(220, 38, 38, 0.125); - border: 1px solid #dc2626; - border-radius: 8px; - margin-bottom: 16px; -} - -.sgui-error-content { - display: flex; - align-items: center; - justify-content: space-between; -} - -.sgui-error-message { - display: flex; - align-items: center; - gap: 8px; - color: #dc2626; -} - -.sgui-error-text { - font-size: 15px; -} /* ABI upload modal */ -.sgui-abi-modal { - padding: 16px; - background: #1a1a1a; - border: 1px solid rgba(255, 255, 255, 0.3); - border-radius: 8px; - margin-bottom: 16px; -} - -.sgui-abi-modal-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 12px; -} - -.sgui-abi-modal-title { - font-size: 15px; - font-weight: 600; - color: #fff; - margin: 0; -} - -.sgui-abi-modal-close { - background: none; - border: none; - color: #888; - cursor: pointer; - font-size: 17px; - padding: 2px; -} - -.sgui-abi-textarea { - width: 100%; - min-height: 120px; - padding: 8px; - background: #2a2a2a; - border: 1px solid #555; - border-radius: 6px; - color: #fff; - font-size: 12px; - font-family: monospace; - resize: vertical; -} - -.sgui-abi-textarea-label { - display: block; - font-size: 13px; - color: #ccc; - margin-bottom: 6px; -} /* Contract info card */ -.sgui-contract-info { - position: relative; - padding: 16px; - background: #1a1a1a; - border: 1px solid #333; - border-radius: 12px; - margin-bottom: 16px; -} - -.sgui-contract-info.diamond { - background: #1a1025; - border-color: #7c3aed; -} - -.sgui-contract-info.loading { - opacity: 0.6; - filter: grayscale(0.2); -} - -.sgui-contract-info-content { - display: flex; - align-items: center; - gap: 12px; -} - -.sgui-contract-icon { - width: 48px; - height: 48px; - border-radius: 12px; - background: rgba(255, 255, 255, 0.1); - display: flex; - align-items: center; - justify-content: center; - font-size: 25px; - border: 2px solid rgba(255, 255, 255, 0.2); -} - -.sgui-contract-icon-text { - font-size: 15px; - color: #fff; -} - -.sgui-contract-name { - font-weight: 600; - font-size: 19px; - color: #fff; - margin-bottom: 6px; - display: flex; - align-items: center; - gap: 8px; -} - -.sgui-diamond-badge { - display: inline-flex; - align-items: center; - justify-content: center; - width: 18px; - height: 18px; - border-radius: 50%; - background: rgba(124, 58, 237, 0.15); - border: 1px solid rgba(124, 58, 237, 0.4); - color: #a78bfa; -} /* Function tabs */ -.sgui-function-tabs { - display: flex; - gap: 8px; - margin-bottom: 16px; -} /* Function list */ -.sgui-function-list { - max-height: 400px; - overflow-y: auto; -} - -.sgui-function-item { - padding: 12px; - border: 1px solid hsl(var(--border)); - border-radius: 8px; - margin-bottom: 8px; - cursor: pointer; - transition: all 0.15s ease; - background: transparent; -} - -.sgui-function-item:hover { - border-color: hsl(var(--primary) / 0.5); - background: hsl(var(--accent) / 0.3); -} - -.sgui-function-item.selected { - border-color: hsl(var(--primary)); - background: hsl(var(--primary) / 0.1); -} - -.sgui-function-name { - font-weight: 500; - color: hsl(var(--foreground)); -} - -.sgui-function-params { - font-size: 12px; - color: hsl(var(--muted-foreground)); - font-family: monospace; -} /* Parameter inputs */ -.sgui-param-section { - margin-top: 16px; -} - -.sgui-param-label { - display: block; - font-size: 13px; - font-weight: 500; - color: hsl(var(--foreground)); - margin-bottom: 6px; -} - -.sgui-param-type { - font-size: 11px; - color: hsl(var(--muted-foreground)); - font-family: monospace; - margin-left: 8px; -} /* Simulation section */ -.sgui-simulation-section { - margin-top: 24px; - padding-top: 16px; - border-top: 1px solid hsl(var(--border)); -} - -.sgui-simulation-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 16px; -} - -.sgui-simulation-title { - font-size: 15px; - font-weight: 600; - color: hsl(var(--foreground)); -} /* Result display */ -.sgui-result { - margin-top: 16px; - padding: 16px; - background: hsl(var(--accent) / 0.3); - border: 1px solid hsl(var(--border)); - border-radius: 8px; -} - -.sgui-result-success { - border-color: #22c55e; - background: rgba(34, 197, 94, 0.1); -} - -.sgui-result-error { - border-color: #dc2626; - background: rgba(220, 38, 38, 0.1); -} - -.sgui-result-label { - font-size: 13px; - font-weight: 500; - color: hsl(var(--muted-foreground)); - margin-bottom: 8px; -} - -.sgui-result-value { - font-family: monospace; - font-size: 14px; - color: hsl(var(--foreground)); - word-break: break-all; -} /* Button styles */ -.sgui-btn { - padding: 8px 16px; - border-radius: 8px; - font-weight: 500; - font-size: 14px; - cursor: pointer; - transition: all 0.15s ease; - border: none; -} - -.sgui-btn-primary { - background: hsl(var(--primary)); - color: hsl(var(--primary-foreground)); -} - -.sgui-btn-primary:hover { - opacity: 0.9; -} - -.sgui-btn-secondary { - background: transparent; - border: 1px solid hsl(var(--border)); - color: hsl(var(--foreground)); -} - -.sgui-btn-secondary:hover { - background: hsl(var(--accent)); -} - -.sgui-btn-success { - background: #22c55e; - color: #fff; -} - -.sgui-btn-ghost { - background: #6b7280; - color: #fff; -} /* Loading states */ -.sgui-loading { - display: flex; - align-items: center; - gap: 8px; - color: hsl(var(--muted-foreground)); -} - -.sgui-spinner { - animation: spin 1s linear infinite; -} /* Flex utilities */ -.sgui-flex { - display: flex; -} - -.sgui-flex-col { - display: flex; - flex-direction: column; -} - -.sgui-items-center { - align-items: center; -} - -.sgui-justify-between { - justify-content: space-between; -} - -.sgui-gap-2 { - gap: 8px; -} - -.sgui-gap-3 { - gap: 12px; -} - -.sgui-gap-4 { - gap: 16px; -} /* Margin utilities */ -.sgui-mb-2 { - margin-bottom: 8px; -} - -.sgui-mb-3 { - margin-bottom: 12px; -} - -.sgui-mb-4 { - margin-bottom: 16px; -} - -.sgui-mt-4 { - margin-top: 16px; -} /* Text utilities */ -.sgui-text-sm { - font-size: 13px; -} - -.sgui-text-xs { - font-size: 11px; -} - -.sgui-text-muted { - color: hsl(var(--muted-foreground)); -} - -.sgui-font-mono { - font-family: monospace; -} - -.sgui-truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} /* ── Animated SVG Icons (hover-triggered stroke-draw) ── */ diff --git a/src/styles/SimulationResultsPage.css b/src/styles/SimulationResultsPage.css index 5e237e0..989934a 100644 --- a/src/styles/SimulationResultsPage.css +++ b/src/styles/SimulationResultsPage.css @@ -96,11 +96,6 @@ body:has(.sim-results-page) > #root { BUTTONS (using standard shadcn components) ============================================ */ -.sim-btn-sm { - padding: 6px 12px; - font-size: 0.8125rem; -} - /* ============================================ TRANSACTION SUMMARY SECTION ============================================ */ @@ -188,13 +183,6 @@ body:has(.sim-results-page) > #root { box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.6); } -.sim-summary-truncate { - max-width: 220px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - /* Flattened copy button (inline SVG pattern from codex_rules.md Appendix A) */ .sim-copy-btn { /* Kill all button chrome per Appendix A step 3 */ @@ -382,64 +370,10 @@ body:has(.sim-results-page) > #root { INPUT/OUTPUT SECTION ============================================ */ -.sim-io-section { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); - gap: 16px; - margin-bottom: 12px; -} - -.sim-io-card { - background: transparent; - border: 1px solid var(--sim-border); - border-radius: 6px; - padding: 12px; - overflow: hidden; -} - -.sim-io-card__header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; - font-size: 0.7625rem; - letter-spacing: 0.1em; - text-transform: uppercase; - color: var(--sim-text-muted); -} - -.sim-io-card__content { - background: transparent; - border: none; - border-radius: 0; - padding: 0; - font-family: "JetBrains Mono", "SF Mono", monospace; - font-size: 0.8625rem; - line-height: 1.5; - margin: 0; - color: var(--sim-text); -} - /* ============================================ STACK TRACE SECTION ============================================ */ -.sim-stack-section { - background: transparent; - border: none; - border-radius: 0; - padding: 0; - margin-bottom: 24px; -} - -.sim-stack-section h2 { - margin: 0 0 12px; - font-size: 0.8125rem; - letter-spacing: 0.1em; - text-transform: uppercase; - color: var(--sim-text-muted); -} - .sim-error-banner { background: rgba(239, 68, 68, 0.08); border-left: 2px solid var(--sim-error); @@ -456,594 +390,18 @@ body:has(.sim-results-page) > #root { color: var(--sim-error); } -.sim-stack-tree { - background: transparent; - border: 1px solid var(--sim-border); - border-radius: 4px; - padding: 8px; - margin-bottom: 16px; -} - -.sim-call-tree { - list-style: none; - margin: 0; - padding: 0; -} - -.sim-call-tree__item { - margin: 0; - padding: 0; -} - -.sim-call-tree__row { - display: flex; - gap: 10px; - padding: 10px; - cursor: pointer; - border-radius: 6px; - transition: background 0.2s ease; -} - -.sim-call-tree__row:hover { - background: rgba(160, 105, 255, 0.08); -} - -.sim-call-tree__caret { - flex-shrink: 0; - width: 20px; - color: var(--sim-text-muted, #9a9aac); - font-size: 0.8625rem; -} - -.sim-call-tree__content { - flex: 1; - min-width: 0; -} - -.sim-call-tree__content strong { - display: block; - margin-bottom: 4px; - font-size: 0.9625rem; -} - -.sim-call-tree__meta { - font-size: 0.8125rem; - color: var(--sim-text-muted, #9a9aac); - font-family: "JetBrains Mono", "SF Mono", monospace; -} - -.sim-call-tree__error { - color: var(--sim-error, #ff6c7a); -} - -.sim-call-tree__children { - margin-left: 30px; - border-left: 1px dashed var(--sim-border, #1f2026); - padding-left: 10px; -} - -.sim-stack-actions { - display: none; -} - -.sim-stack-header { - display: flex; - justify-content: space-between; - gap: 16px; - flex-wrap: wrap; - margin-bottom: 12px; -} - -.sim-stack-toolbar { - display: flex; - flex-wrap: wrap; - gap: 14px; - justify-content: space-between; - align-items: center; - margin-bottom: 16px; -} - -.sim-stack-search { - display: flex; - gap: 8px; - align-items: center; -} - -.sim-search-input { - width: 240px; - padding: 8px 12px; - background: #0a0a0f; - border: 1px solid var(--sim-border, #1f2026); - border-radius: 8px; - color: var(--sim-text, #f6f6fb); - font-size: 0.9125rem; -} - -.sim-search-input::placeholder { - color: var(--sim-text-muted, #9a9aac); -} - -.sim-mini-dropdown { - background: rgba(7, 7, 12, 0.9); - border: 1px solid var(--sim-border, #1f2026); - color: var(--sim-text-muted, #9a9aac); - padding: 8px 14px; - border-radius: 8px; - font-size: 0.8625rem; - text-transform: uppercase; - letter-spacing: 0.1em; - cursor: pointer; -} - -.sim-stack-filters { - display: flex; - gap: 8px; - align-items: center; - flex-wrap: wrap; - justify-content: flex-end; - flex: 1; -} - -.simulation-hub__filter { - display: inline-flex; - align-items: center; - gap: 6px; - font-size: 0.8425rem; - letter-spacing: 0.12em; - text-transform: uppercase; - color: var(--sim-text-muted, #9a9aac); -} - -.simulation-hub__filter input { - width: 16px; - height: 16px; - accent-color: #6d64ff; -} - -.simulation-hub__filter span { - color: inherit; -} - -.sim-chip-toggle { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 6px 12px; - border-radius: 999px; - border: 1px solid rgba(125, 123, 255, 0.25); - background: rgba(20, 20, 35, 0.85); - color: rgba(255, 255, 255, 0.8); - font-size: 0.7825rem; - letter-spacing: 0.08em; - text-transform: uppercase; - cursor: pointer; - transition: all 0.15s ease; -} - -.sim-chip-toggle input { - display: none; -} - -.sim-chip-toggle::after { - content: "✓"; - font-size: 0.9125rem; - opacity: 0; - transform: translateY(-1px); - color: #c9cdfd; -} - -.sim-chip-toggle.active { - border-color: rgba(105, 93, 255, 0.8); - background: linear-gradient(135deg, #5a52ff, #825bff); - box-shadow: 0 6px 20px rgba(90, 82, 255, 0.35); -} - -.sim-chip-toggle.active::after { - opacity: 1; -} - -.sim-chip-action { - background: linear-gradient(135deg, #5a52ff, #8c59ff); - border: none; - color: #fff; - padding: 8px 16px; - border-radius: 10px; - font-size: 0.8425rem; - letter-spacing: 0.12em; - text-transform: uppercase; - cursor: pointer; - box-shadow: 0 8px 24px rgba(92, 76, 255, 0.35); -} - -.sim-chip-action:disabled { - opacity: 0.4; - cursor: not-allowed; -} - - -.sim-trace-list { - background: #08080d; - border: 1px solid var(--sim-border, #1f2026); - border-radius: 10px; - padding: 8px; - display: flex; - flex-direction: column; - gap: 8px; -} - -.sim-trace-row { - display: flex; - gap: 16px; - padding: 12px; - border-radius: 10px; - border: 1px solid rgba(255, 255, 255, 0.04); - background: rgba(255, 255, 255, 0.02); - align-items: flex-start; - transition: border 0.2s ease, background 0.2s ease; -} - -.sim-trace-row--call { - background: linear-gradient(90deg, rgba(21, 21, 41, 0.85), rgba(9, 6, 19, 0.85)); - border-color: rgba(129, 91, 255, 0.45); - box-shadow: 0 12px 32px rgba(26, 16, 51, 0.4); -} - -.sim-trace-row--event { - background: rgba(34, 211, 238, 0.05); - border-color: rgba(34, 211, 238, 0.3); -} - -.sim-trace-row--storage { - background: rgba(34, 197, 94, 0.05); - border-color: rgba(34, 197, 94, 0.25); -} - -.sim-trace-row--error { - border-color: rgba(255, 108, 122, 0.6); - box-shadow: 0 0 12px rgba(255, 108, 122, 0.2); -} - -.sim-trace-row--highlight { - border-color: rgba(160, 105, 255, 0.9); - box-shadow: 0 0 20px rgba(160, 105, 255, 0.4); -} - -.sim-trace-opcode { - min-width: 110px; - display: flex; - flex-direction: column; - gap: 6px; - font-size: 0.8125rem; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--sim-text-muted, #9a9aac); -} - -.sim-opcode-badge { - padding: 6px 10px; - border-radius: 8px; - background: rgba(73, 91, 255, 0.15); - border: 1px solid rgba(73, 91, 255, 0.35); - font-size: 0.8125rem; - font-weight: 600; - color: #8ea2ff; -} - -.sim-opcode-call { - background: rgba(96, 165, 250, 0.15); - border-color: rgba(96, 165, 250, 0.35); - color: #93c5fd; -} - -.sim-opcode-event { - background: rgba(34, 211, 238, 0.12); - border-color: rgba(34, 211, 238, 0.35); - color: #67e8f9; -} - -.sim-opcode-storage { - background: rgba(34, 197, 94, 0.15); - border-color: rgba(34, 197, 94, 0.4); - color: #86efac; -} - -.sim-trace-body { - flex: 1; - min-width: 0; - display: flex; - flex-direction: column; - gap: 6px; -} - -.sim-trace-path { - display: flex; - flex-wrap: wrap; - gap: 8px; - align-items: center; - font-family: "JetBrains Mono", "SF Mono", monospace; - font-size: 0.8625rem; -} - -.sim-trace-arrow { - color: var(--sim-text-muted, #9a9aac); -} - -.sim-trace-address { - color: var(--sim-text, #f6f6fb); -} - -.sim-trace-meta { - display: flex; - flex-wrap: wrap; - gap: 8px; - font-size: 0.8125rem; - color: var(--sim-text-muted, #9a9aac); - align-items: center; -} - -.sim-trace-func { - font-weight: 600; - color: var(--sim-text, #f6f6fb); -} - -.sim-trace-pill { - padding: 2px 10px; - border-radius: 999px; - border: 1px solid rgba(255, 255, 255, 0.12); - font-size: 0.7625rem; - letter-spacing: 0.08em; - text-transform: uppercase; -} - -.sim-trace-pill.subtle { - border-color: rgba(255, 255, 255, 0.08); - color: rgba(255, 255, 255, 0.7); -} - -.sim-trace-pill.error { - border-color: rgba(255, 108, 122, 0.7); - color: #ff6c7a; -} - -.sim-trace-code { - font-family: "JetBrains Mono", "SF Mono", monospace; - background: rgba(0, 0, 0, 0.35); - padding: 4px 8px; - border-radius: 6px; - border: 1px solid rgba(255, 255, 255, 0.08); - word-break: break-all; -} - -.sim-trace-storage { - display: flex; - gap: 20px; - flex-wrap: wrap; -} - -.sim-trace-storage span { - display: block; - margin-bottom: 4px; - font-size: 0.7625rem; - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--sim-text-muted, #9a9aac); -} - /* ============================================ DETAILED TRACE SECTION ============================================ */ -.sim-trace-section { - background: var(--sim-surface, #0f1014); - border: 1px solid var(--sim-border, #1f2026); - border-radius: 12px; - padding: 20px; - margin-bottom: 24px; -} - -.sim-trace-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 16px; - flex-wrap: wrap; - gap: 12px; -} - -.sim-trace-header h2 { - margin: 0; - font-size: 0.9125rem; - letter-spacing: 0.2em; - text-transform: uppercase; - color: var(--sim-text-muted, #9a9aac); -} - -.sim-trace-filters { - display: flex; - gap: 12px; - flex-wrap: wrap; -} - -.sim-trace-filter { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 6px 12px; - background: var(--sim-surface-alt, #14141b); - border: 1px solid var(--sim-border, #1f2026); - border-radius: 999px; - font-size: 0.8125rem; - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--sim-text-muted, #9a9aac); - cursor: pointer; - transition: all 0.2s ease; -} - -.sim-trace-filter:hover { - border-color: var(--sim-border-strong, #2b2c34); -} - -.sim-trace-filter input[type="checkbox"] { - margin: 0; -} - -.sim-trace-list { - background: #0a0a0f; - border: 1px solid var(--sim-border, #1f2026); - border-radius: 10px; -} - -.sim-trace-item { - display: grid; - grid-template-columns: 80px 60px 1fr; - gap: 12px; - align-items: center; - padding: 12px 16px; - border-bottom: 1px solid var(--sim-border, #1f2026); -} - -.sim-trace-item:last-child { - border-bottom: none; -} - -.sim-trace-badge { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 4px 8px; - border-radius: 6px; - font-size: 0.7625rem; - letter-spacing: 0.08em; - text-transform: uppercase; - border: 1px solid; - font-weight: 600; -} - -.sim-trace-badge--call { - border-color: rgba(34, 211, 238, 0.5); - color: #d4d4d4; - background: rgba(34, 211, 238, 0.08); -} - -.sim-trace-badge--jump { - border-color: rgba(34, 211, 238, 0.5); - color: #d4d4d4; - background: rgba(34, 211, 238, 0.08); -} - -.sim-trace-badge--sload { - border-color: rgba(236, 72, 153, 0.5); - color: #ec4899; - background: rgba(236, 72, 153, 0.08); -} - -.sim-trace-badge--revert { - border-color: rgba(255, 108, 122, 0.5); - color: var(--sim-error, #ff6c7a); - background: rgba(255, 108, 122, 0.08); -} - -.sim-trace-gas { - font-family: "JetBrains Mono", "SF Mono", monospace; - font-size: 0.8625rem; - color: var(--sim-text-muted, #9a9aac); -} - -.sim-trace-content { - min-width: 0; -} - -.sim-trace-line strong { - font-size: 0.9425rem; -} - -.sim-trace-meta { - font-size: 0.8125rem; - color: var(--sim-text-muted, #9a9aac); - font-family: "JetBrains Mono", "SF Mono", monospace; - margin-top: 2px; -} - /* ============================================ EVENTS & STORAGE ============================================ */ -.sim-events-list, -.sim-storage-list { - display: flex; - flex-direction: column; - gap: 16px; -} - -.sim-event-item, -.sim-storage-item { - padding: 14px; - background: var(--sim-surface-alt, #14141b); - border: 1px solid var(--sim-border, #1f2026); - border-radius: 10px; -} - -.sim-event-item strong, -.sim-storage-item strong { - display: block; - margin-bottom: 6px; - font-size: 0.9625rem; -} - -.sim-event-address { - font-size: 0.8125rem; - color: var(--sim-text-muted, #9a9aac); - font-family: "JetBrains Mono", "SF Mono", monospace; - margin-bottom: 8px; -} - -.sim-event-data { - background: #08080d; - border: 1px solid var(--sim-border, #1f2026); - border-radius: 6px; - padding: 10px; - font-family: "JetBrains Mono", "SF Mono", monospace; - font-size: 0.8125rem; - line-height: 1.5; - margin: 0; -} - -.sim-storage-diff { - display: flex; - flex-direction: column; - gap: 6px; - font-size: 0.8825rem; -} - -.sim-storage-diff small { - display: inline-block; - min-width: 60px; - color: var(--sim-text-muted, #9a9aac); - font-size: 0.7625rem; - letter-spacing: 0.1em; - text-transform: uppercase; -} - -.sim-storage-diff code { - font-family: "JetBrains Mono", "SF Mono", monospace; - background: #08080d; - padding: 2px 6px; - border-radius: 4px; - font-size: 0.8425rem; -} - /* ============================================ EMPTY STATES ============================================ */ -.sim-empty-state { - padding: 40px 20px; - text-align: center; - color: var(--sim-text-muted, #9a9aac); - font-size: 0.9625rem; -} - .sim-results-empty { display: flex; flex-direction: column; @@ -1145,15 +503,6 @@ body:has(.sim-results-page) > #root { .sim-tab-content { padding: 16px; } - - .sim-io-section { - grid-template-columns: 1fr; - } - - .sim-trace-item { - grid-template-columns: 70px 50px 1fr; - gap: 8px; - } } .sim-opcode-badge--storage { background: rgba(34, 197, 94, 0.15); @@ -1172,54 +521,15 @@ body:has(.sim-results-page) > #root { border-color: rgba(14, 165, 233, 0.45); color: #67e8f9; } -.sim-toggle-dropdown { - position: relative; -} /* ============================================ RETURN DATA (multi-line) ============================================ */ -.sim-return-data-container { - flex-direction: column; - align-items: flex-start !important; - gap: 8px; -} - -.sim-return-data { - font-family: "JetBrains Mono", "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace; - font-size: 0.9125rem; - line-height: 1.6; - word-break: break-all; - overflow-wrap: break-word; - white-space: pre-wrap; - max-width: 100%; - color: var(--sim-text); - display: block; -} - /* ============================================ BALANCE CHANGES TABLE (Flat Design) ============================================ */ -.sim-balance-changes { - margin-bottom: 16px; - background: transparent; - border: 1px solid var(--sim-border); - border-radius: 4px; - overflow: hidden; -} - -.sim-balance-changes__header { - padding: 10px 14px; - border-bottom: 1px solid var(--sim-border); - font-size: 13px; - font-weight: 600; - color: var(--sim-text-muted); - text-transform: uppercase; - letter-spacing: 0.8px; -} - .sim-balance-changes__table { width: 100%; border-collapse: collapse; @@ -1279,29 +589,3 @@ body:has(.sim-results-page) > #root { /* ============================================ SECTION HEADERS (Flat Design) ============================================ */ - -.sim-section-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; -} - -.sim-section-title { - margin: 0; - font-size: 0.9125rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - color: var(--sim-text); -} - -.sim-count-badge { - padding: 4px 10px; - background: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.25); - border-radius: 4px; - font-size: 0.8125rem; - font-weight: 600; - color: #d4d4d4; -} diff --git a/src/styles/SimulatorWorkbench.css b/src/styles/SimulatorWorkbench.css deleted file mode 100644 index 9294f66..0000000 --- a/src/styles/SimulatorWorkbench.css +++ /dev/null @@ -1,9 +0,0 @@ -/* - * SimulatorWorkbench.css - * - * All legacy classes removed — duplicate definitions now live in - * SimulationResultsPage.css and StackTracePanel.css. - * - * This file is kept as an empty import target for - * TransactionBuilderWagmi.tsx and SimpleGridMain.tsx. - */ diff --git a/src/styles/StackedOverview.css b/src/styles/StackedOverview.css index 56ea107..d8ade63 100644 --- a/src/styles/StackedOverview.css +++ b/src/styles/StackedOverview.css @@ -18,40 +18,6 @@ color: var(--text-tertiary); } -.stacked-summary-grid { - display: grid; - gap: 16px; - grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); -} - -.stacked-summary-card { - background: rgba(13, 23, 44, 0.82); - border: 1px solid rgba(59, 130, 246, 0.22); - border-radius: 16px; - padding: 16px; - display: grid; - gap: 10px; - box-shadow: 0 14px 32px rgba(15, 23, 42, 0.26); -} - -.stacked-summary-label { - font-size: 14px; - color: rgba(148, 163, 184, 0.8); -} - -.stacked-summary-value { - font-size: 16px; - font-weight: 600; - color: #e2e8f0; - word-break: break-word; -} - -.stacked-chip-row { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - .stacked-chip { display: inline-flex; align-items: center; diff --git a/src/styles/TokenMovementsPanel.css b/src/styles/TokenMovementsPanel.css index 304d43c..48d2ad5 100644 --- a/src/styles/TokenMovementsPanel.css +++ b/src/styles/TokenMovementsPanel.css @@ -282,11 +282,6 @@ font-size: 11px; } -.token-id { - color: #888; - font-size: 10px; -} - /* Token ID cell (for NFTs) */ .token-id-cell { font-family: "Fira Code", "Consolas", monospace; @@ -333,12 +328,6 @@ } /* Empty state */ -.token-movements-empty { - padding: 12px; - text-align: center; - color: #666; - font-size: 12px; -} /* ====================================== Cross-reference highlighting diff --git a/src/styles/design-tokens.css b/src/styles/design-tokens.css index ee72337..77008f6 100644 --- a/src/styles/design-tokens.css +++ b/src/styles/design-tokens.css @@ -17,15 +17,11 @@ /* Accent Colors - Black & White System */ --accent-primary: #ffffff; - --accent-secondary: #e5e5e5; - --accent-muted: #a3a3a3; /* Accent Variants with Transparency */ --accent-primary-10: rgba(255, 255, 255, 0.1); --accent-primary-20: rgba(255, 255, 255, 0.2); --accent-primary-30: rgba(255, 255, 255, 0.3); - --accent-secondary-10: rgba(229, 229, 229, 0.1); - --accent-secondary-20: rgba(229, 229, 229, 0.2); /* Semantic Colors */ --success: #22c55e; @@ -38,56 +34,36 @@ --text-secondary: #a1a1aa; --text-tertiary: #71717a; --text-muted: #52525b; - --text-accent: #d4d4d4; /* Border Colors */ --border-primary: rgba(255, 255, 255, 0.1); --border-secondary: rgba(255, 255, 255, 0.05); - --border-accent: rgba(255, 255, 255, 0.3); - --border-focus: rgba(255, 255, 255, 0.5); - --border-danger: rgba(239, 68, 68, 0.5); - --border-success: rgba(34, 197, 94, 0.5); /* ========== TYPOGRAPHY SYSTEM ========== */ /* Font Families */ - --font-display: 'Inter', system-ui, sans-serif; --font-body: 'Inter', system-ui, sans-serif; --font-mono: 'JetBrains Mono', 'Consolas', 'Monaco', monospace; /* Font Weights */ - --font-weight-light: 300; --font-weight-regular: 400; --font-weight-medium: 500; --font-weight-semibold: 600; - --font-weight-bold: 700; /* Font Sizes - Tailwind defaults */ --text-xs: 0.75rem; --text-sm: 0.875rem; --text-base: 1rem; --text-lg: 1.125rem; - --text-xl: 1.25rem; --text-2xl: 1.5rem; - --text-3xl: 1.875rem; - --text-4xl: 2.25rem; - --text-5xl: 3rem; /* Line Heights */ - --leading-tight: 1.25; --leading-normal: 1.5; - --leading-relaxed: 1.625; - --leading-loose: 2; /* Letter Spacing */ - --tracking-tight: -0.025em; --tracking-normal: 0em; - --tracking-wide: 0.025em; /* ========== SPACING SYSTEM ========== */ - - --space-px: 1px; - --space-0: 0; --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; @@ -95,12 +71,6 @@ --space-5: 1.25rem; --space-6: 1.5rem; --space-8: 2rem; - --space-10: 2.5rem; - --space-12: 3rem; - --space-16: 4rem; - --space-20: 5rem; - --space-24: 6rem; - --space-32: 8rem; /* ========== EFFECTS ========== */ @@ -108,7 +78,6 @@ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3); --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.25); --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.3); - --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.35); /* Border Radius */ --radius-sm: 0.25rem; @@ -120,31 +89,12 @@ /* Transitions */ --transition-fast: 150ms ease; --transition-normal: 200ms ease; - --transition-slow: 300ms ease; /* Animation Durations */ - --duration-fast: 150ms; - --duration-normal: 200ms; - --duration-slow: 300ms; /* ========== Z-INDEX SCALE ========== */ - --z-dropdown: 1000; - --z-sticky: 1020; - --z-fixed: 1030; - --z-modal-backdrop: 1040; - --z-modal: 1050; - --z-popover: 1060; - --z-tooltip: 1070; - --z-toast: 1080; - /* ========== BREAKPOINTS ========== */ - - --breakpoint-sm: 640px; - --breakpoint-md: 768px; - --breakpoint-lg: 1024px; - --breakpoint-xl: 1280px; - --breakpoint-2xl: 1536px; } /* ========== GLOBAL STYLES ========== */ @@ -180,18 +130,9 @@ } /* Opt-in focus outline removal — only for elements with custom focus indicators */ -.focus-custom:focus-visible { - outline: none; -} /* ========== UTILITY CLASSES ========== */ -.bg-glass { - background: var(--bg-glass); - backdrop-filter: blur(8px); - -webkit-backdrop-filter: blur(8px); -} - /* ========== RESPONSIVE UTILITIES ========== */ /* Touch targets for coarse pointer devices (phones, tablets) */ diff --git a/src/types/contractInfo.ts b/src/types/contractInfo.ts index 696612d..450bade 100644 --- a/src/types/contractInfo.ts +++ b/src/types/contractInfo.ts @@ -35,12 +35,3 @@ export interface ContractInfoResult { }>; } -export type ContractExternalFunction = NonNullable< - ContractInfoResult['externalFunctions'] ->[number]; - -export type ContractTokenInfo = NonNullable; - -export type ContractSearchProgress = NonNullable< - ContractInfoResult['searchProgress'] ->[number]; diff --git a/src/types/debug.ts b/src/types/debug.ts index 68e3d75..f1b0fcd 100644 --- a/src/types/debug.ts +++ b/src/types/debug.ts @@ -299,14 +299,6 @@ export interface DiscoveredMappingKey { } -/** Detected RPC capabilities for storage inspection */ -export interface RpcCapabilities { - hasDebugStorageRangeAt: boolean; - hasEthGetProof: boolean; - hasEdbGetStorageLayout: boolean; - checked: boolean; -} - /** Debug call frame */ export interface DebugCallFrame { traceId: number; diff --git a/src/types/transaction.ts b/src/types/transaction.ts index cd301fc..f792645 100644 --- a/src/types/transaction.ts +++ b/src/types/transaction.ts @@ -183,14 +183,3 @@ export interface SimulationContract { fileCount?: number; } -export interface AssetChange { - address: string; - symbol: string; - name: string; - decimals: number; - amount: string; - changeType: 'RECEIVE' | 'SEND' | 'APPROVE'; - rawAmount: string; - usdValue?: string; -} - diff --git a/src/utils/diamondFacetFetcher.ts b/src/utils/diamondFacetFetcher.ts index c117dbe..c8ff481 100644 --- a/src/utils/diamondFacetFetcher.ts +++ b/src/utils/diamondFacetFetcher.ts @@ -195,8 +195,8 @@ async function fetchFromBlockscout( const keyParam = apiKey ? `&apikey=${encodeURIComponent(apiKey)}` : ""; const tokenParam = apiKey ? `?token=${encodeURIComponent(apiKey)}` : ""; const endpoints = [ - `${basePath}/api?module=contract&action=getabi&address=${address}${keyParam}`, - `${basePath}/api/v2/smart-contracts/${address}${tokenParam}`, // note: includes /api/v2 to survive proxy rewrite + `${basePath}?module=contract&action=getabi&address=${address}${keyParam}`, + `${basePath}/v2/smart-contracts/${address}${tokenParam}`, ]; let interimAbi: unknown[] | null = null; @@ -236,8 +236,8 @@ async function fetchFromBlockscout( // If we have ABI from v1 but no name, fetch name via v2 or getsourcecode if (interimAbi && !interimName) { const nameEndpoints = [ - `${basePath}/api?module=contract&action=getsourcecode&address=${address}${keyParam}`, - `${basePath}/api/v2/smart-contracts/${address}${tokenParam}`, + `${basePath}?module=contract&action=getsourcecode&address=${address}${keyParam}`, + `${basePath}/v2/smart-contracts/${address}${tokenParam}`, ]; for (const nurl of nameEndpoints) { try { diff --git a/src/utils/resultFormatter.ts b/src/utils/resultFormatter.ts index fd57d8c..cb098f3 100644 --- a/src/utils/resultFormatter.ts +++ b/src/utils/resultFormatter.ts @@ -57,7 +57,7 @@ export class ContractResultFormatter { if (isCompact) { // Line-per-field format for better readability - let lines: string[] = []; + const lines: string[] = []; // Handle named tuple fields if we have function output info if (functionOutput && functionOutput.components && functionOutput.components.length > 0) { diff --git a/src/utils/traceDecoder/decodeTraceInit.ts b/src/utils/traceDecoder/decodeTraceInit.ts index ca33ab9..228af93 100644 --- a/src/utils/traceDecoder/decodeTraceInit.ts +++ b/src/utils/traceDecoder/decodeTraceInit.ts @@ -476,7 +476,7 @@ export function phaseInit(raw: RawTrace): DecodeTraceContext { const opcodeDetails = snaps.map((s: any) => s.detail?.Opcode).filter(Boolean); // Extract gas_remaining from raw text to preserve BigInt precision - let rawText = (raw as any).__rawText || ""; + const rawText = (raw as any).__rawText || ""; let gasMatches: string[] = []; if (rawText) { const snapshotsMatch = rawText.match(/"snapshots"\s*:\s*\[/); diff --git a/src/utils/traceDecoder/jumpAnalysis.ts b/src/utils/traceDecoder/jumpAnalysis.ts index 2207551..1895798 100644 --- a/src/utils/traceDecoder/jumpAnalysis.ts +++ b/src/utils/traceDecoder/jumpAnalysis.ts @@ -541,7 +541,7 @@ export function buildJumpRows( const candidate = allJumpRows[candidateIndex]; const entrySource = frameEntrySourceByTrace.get(traceId); - let promotedSrcFile = entrySource?.file || candidate.srcSourceFile || null; + const promotedSrcFile = entrySource?.file || candidate.srcSourceFile || null; let promotedSrcLine = entrySource?.line ?? candidate.srcLine ?? null; if (promotedSrcFile && promotedSrcLine !== null) { diff --git a/src/utils/traceDecoder/pcMapper.ts b/src/utils/traceDecoder/pcMapper.ts index 9581be5..e420c50 100644 --- a/src/utils/traceDecoder/pcMapper.ts +++ b/src/utils/traceDecoder/pcMapper.ts @@ -197,7 +197,7 @@ export function buildFullPcLineMap( pc += 1 + pushLen; idx++; } - let last = ["0", "0", "-1", ""]; + const last = ["0", "0", "-1", ""]; const pcMapFull = new Map(); for (const { idx: opIdx, pc } of opList) { const seg = srcMap[opIdx] || ""; diff --git a/src/utils/transaction-simulation/bridgeSimulation.ts b/src/utils/transaction-simulation/bridgeSimulation.ts index 8131a57..dba242c 100644 --- a/src/utils/transaction-simulation/bridgeSimulation.ts +++ b/src/utils/transaction-simulation/bridgeSimulation.ts @@ -508,7 +508,7 @@ export const trySimulatorBridge = async ( } const hasSettings = artifact.settings && !artifact.missingSettings; - let normalizedLibraries: Record> = {}; + const normalizedLibraries: Record> = {}; if ( artifact.settings?.libraries && typeof artifact.settings.libraries === "object" diff --git a/src/utils/universalTokenDetector.ts b/src/utils/universalTokenDetector.ts index df09040..274e54b 100644 --- a/src/utils/universalTokenDetector.ts +++ b/src/utils/universalTokenDetector.ts @@ -27,13 +27,13 @@ export async function detectTokenType( provider: ethers.providers.Provider, address: string ): Promise { - let type: DetectedTokenType = "unknown"; - let method = "none"; + const type: DetectedTokenType = "unknown"; + const method = "none"; let isDiamond = false; let name: string | undefined; let symbol: string | undefined; let decimals: number | undefined; - let confidence = 0; + const confidence = 0; // Step 1: Diamond detection (separate from token detection) try { diff --git a/tsconfig.app.json b/tsconfig.app.json index ad2bf88..9f774cf 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -30,11 +30,5 @@ "noUncheckedSideEffectImports": true }, "include": ["src"], - "exclude": [ - "src/**/*.test.ts", - "src/**/*.test.tsx", - "src/**/*.spec.ts", - "src/**/*.spec.tsx", - "src/**/__tests__/**" - ] + "exclude": ["src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.spec.ts", "src/**/*.spec.tsx", "src/**/__tests__/**"] } diff --git a/vercel.json b/vercel.json index 533b97e..c3c116c 100644 --- a/vercel.json +++ b/vercel.json @@ -22,43 +22,43 @@ }, { "source": "/api/eth-blockscout/:path*", - "destination": "https://eth.blockscout.com/:path*" + "destination": "https://eth.blockscout.com/api/:path*" }, { "source": "/api/blockscout/:path*", - "destination": "https://base.blockscout.com/:path*" + "destination": "https://base.blockscout.com/api/:path*" }, { "source": "/api/polygon-blockscout/:path*", - "destination": "https://polygon.blockscout.com/:path*" + "destination": "https://polygon.blockscout.com/api/:path*" }, { "source": "/api/arbitrum-blockscout/:path*", - "destination": "https://arbitrum.blockscout.com/:path*" + "destination": "https://arbitrum.blockscout.com/api/:path*" }, { "source": "/api/base-sepolia-blockscout/:path*", - "destination": "https://base-sepolia.blockscout.com/:path*" + "destination": "https://base-sepolia.blockscout.com/api/:path*" }, { "source": "/api/lisk-sepolia-blockscout/:path*", - "destination": "https://sepolia-blockscout.lisk.com/:path*" + "destination": "https://sepolia-blockscout.lisk.com/api/:path*" }, { "source": "/api/lisk-blockscout/:path*", - "destination": "https://blockscout.lisk.com/:path*" + "destination": "https://blockscout.lisk.com/api/:path*" }, { "source": "/api/optimism-blockscout/:path*", - "destination": "https://optimism.blockscout.com/:path*" + "destination": "https://optimism.blockscout.com/api/:path*" }, { "source": "/api/sepolia-blockscout/:path*", - "destination": "https://eth-sepolia.blockscout.com/:path*" + "destination": "https://eth-sepolia.blockscout.com/api/:path*" }, { "source": "/api/gnosis-blockscout/:path*", - "destination": "https://gnosis.blockscout.com/:path*" + "destination": "https://gnosis.blockscout.com/api/:path*" }, { "source": "/api/repo/:path*", diff --git a/vite.config.ts b/vite.config.ts index 7339f40..676bd8e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -162,7 +162,7 @@ export default defineConfig(({ mode }) => { "process.env": "{}", }, optimizeDeps: { - include: ["ethers", "buffer"], + include: ["ethers"], }, build: { chunkSizeWarningLimit: 1200, @@ -171,11 +171,6 @@ export default defineConfig(({ mode }) => { manualChunks: { vendor: ["react", "react-dom", "react-router-dom"], wagmi: ["wagmi", "@wagmi/core", "@wagmi/connectors"], - walletconnect: [ - "@walletconnect/ethereum-provider", - "@reown/appkit", - "@reown/appkit-controllers", - ], ethers: ["ethers"], }, }, @@ -183,7 +178,6 @@ export default defineConfig(({ mode }) => { }, resolve: { alias: { - buffer: "buffer", "@": path.resolve(__dirname, "./src"), }, }, From b1438a10702562cd933e94b91a73bc85d1b93d6c Mon Sep 17 00:00:00 2001 From: Timidan Date: Thu, 28 May 2026 13:06:52 +0100 Subject: [PATCH 2/2] docs(env): document actually-implemented VITE_LLM_MODE values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only "off" is special-cased at runtime — "fixture" mode was declared in the type union but never branched on, and no fixture files exist beyond a .gitkeep. Update the example to reflect what works. --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index cdbd1c4..cf61074 100644 --- a/.env.example +++ b/.env.example @@ -25,7 +25,7 @@ VITE_WALLETCONNECT_PROJECT_ID=your-walletconnect-project-id # GEMINI_MODEL — Primary model (default: gemini-2.5-flash-lite) # LLM mode toggle (browser-side) -# VITE_LLM_MODE — Set to "fixture" to use bundled fixtures instead of live LLM (default: live) +# VITE_LLM_MODE — Set to "off" to skip LLM and use rules-based fallback (default: live) # Shared proxy secret (optional — when set, lifi-composer and llm-recommend # proxies require this value in the x-proxy-secret header instead of origin checks).