Skip to content

Conversation

@NeOMakinG
Copy link
Collaborator

Merge branch 'main' into develop
feat: migrate rainbowkit to reown on swap widget plus support btc and solana (#11712)
chore(deps): bump diff from 4.0.2 to 4.0.4 (#11748)
feat: unify trade and buy/sell (#11753)
fix: yield improvements - validator handling, disabled states, UI consistency (#11743)
feat: expand "Multi-chain wallets" section by default (#11746)
feat: add Phantom wallet option to mobile web (#11747)
feat: strk related assets (#11744)
fix: yields polish one (#11742)
feat: regenerate asset data 01/21/2026 (#11755)
feat: make asset search actually finally great (not again) (#11733)
feat: rename Trade/Bridge tab to Swap (#11752)
chore: update microservices endpoints (#11745)
feat: activate starknet and avnu in production (#11709)
feat(yields): mini swapper modal (#11730)
feat: yield improvements following CR (#11729)
feat: regenerate asset data 01/20/2026 (#11739)
feat(public-api): add chains endpoint (#11737)
fix: increase Node memory limit for dev server to prevent OOM (#11720)
perf: improve app performance with Web Worker for IndexedDB and faster selector memoization (#11605)
fix: improve kk connectivity (#11641)
feat: add public swap API server (#11586)

0xApotheosis and others added 22 commits January 20, 2026 11:23
* feat: add public swap API server

Implements a public API for swap quotes and rates that reuses the existing
@shapeshiftoss/swapper package without code duplication.

Endpoints:
- GET /v1/swap/rates - Get rates from all swappers
- POST /v1/swap/quote - Get executable quote with tx data
- GET /v1/assets - List supported assets

Features:
- API key authentication middleware
- Minimal EVM chain adapters for gas fee estimation
- esbuild bundling for single-file deployment
- Docker + Railway deployment configuration
- 55 bps affiliate fee (planned 50/50 split with partners)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): skip postinstall scripts in Docker build

* fix(public-api): use --mode skip-build for yarn install in Docker

- Replace YARN_ENABLE_SCRIPTS=false with --mode skip-build to properly skip
  all lifecycle scripts including postinstall that requires git
- Add tsconfig files copy for TypeScript compilation
- Add build:docker script to unchained-client to skip Java-based code generation
- Use explicit workspace builds instead of yarn workspaces foreach

* fix(public-api): fix TypeScript compilation errors

- Type JSON response in swapperDeps.ts to fix 'data is of type unknown' error
- Add GetTradeRateInput type assertion in rates.ts for chainId compatibility
- Add GetTradeQuoteInputWithWallet type assertion in quote.ts for chainId compatibility

* fix(public-api): add Java to Docker for unchained-client code generation

- Install openjdk17-jre in build stage for OpenAPI generator CLI
- Use full unchained-client build script instead of build:docker

* fix(unchained-client): add shebang and executable permission to post_process.sh

Fixes 'Exec format error' during Docker build.

* fix(public-api): copy node_modules to runner stage

Fixes runtime module not found errors for external dependencies like @cowprotocol/app-data

* feat(public-api): add Scalar docs with auto-expanded sections and prefilled examples

- Add Scalar API reference UI at /docs endpoint
- Configure defaultOpenAllTags to auto-expand all sections on page load
- Prefill test API key (test-api-key-123) in authentication section
- Add OpenAPI example values to all request schemas for prefilled forms
- Set up zod-to-openapi for generating OpenAPI spec from Zod schemas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): downgrade zod-to-openapi to v7 for zod v3 compatibility

zod-to-openapi v8.x requires zod v4 as a peer dependency, causing runtime
errors when used with zod v3.23.8. Downgrade to v7.3.4 which supports zod v3.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* perf(public-api): remove node_modules from production Docker image

esbuild bundles all dependencies into server.cjs, so copying the entire
node_modules directory to the production image was unnecessary and added
significant time to Railway deployments (~2-4 min) and image size (~500MB+).

The only externals are fsevents (macOS-only, not used in Linux containers)
and @cowprotocol/* (not used by public-api routes).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(public-api): add integration overview to API documentation

Add comprehensive description explaining how to integrate the swap API:
- Step-by-step integration flow (assets -> rates -> quote -> execute)
- Authentication requirements
- CAIP-19 asset ID format with examples

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* perf(public-api): add BuildKit optimizations to Docker build

- Add Dockerfile.dockerignore to exclude node_modules (4.5GB), .git (1.4GB),
  and other unnecessary files from build context
- Enable BuildKit with syntax directive for advanced features
- Add cache mount for yarn berry cache to speed up subsequent builds

These optimizations reduce build context transfer time and cache dependencies
between builds, further improving Railway deployment speed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): add required id to BuildKit cache mount

Railway requires cache mounts to have an explicit id parameter.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): remove BuildKit cache mount

Railway's cache mount requires a specific prefix format that's not
documented. Reverting to standard yarn install - the .dockerignore
still provides significant build context reduction.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* perf(public-api): add Railway-compatible BuildKit cache mount

Use Railway's required cache mount ID format: s/<service-id>-<target-path>
This caches yarn's berry cache between builds to speed up dependency installation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: add .playwright-mcp to gitignore

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): bundle cowprotocol packages to fix production rates

The @cowprotocol/* packages were externalized in esbuild which caused
them to be missing at runtime in the Docker production image (which only
copies the bundled server.cjs, not node_modules). This caused the entire
swapper module initialization to fail, making the swappers object
undefined and returning empty rates for all requests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(public-api): use 0x swapper in quote examples

THORChain doesn't support native ETH -> ERC20 swaps on the same chain.
Update the documentation examples to use 0x which reliably supports
ETH -> USDC swaps and returns valid transaction data.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): set page title to ShapeShift API Reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): use valid example addresses in quote schema

The null address (0x000...000) is rejected by swapper APIs like 0x.
Update the OpenAPI examples to use a valid Ethereum address so the
Try It Out feature in the docs actually works.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): resolve consistent-type-imports lint errors

Replace `typeof import()` type annotations with `Awaited<ReturnType<typeof fn>>`
pattern to comply with @typescript-eslint/consistent-type-imports rule.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(public-api): add API info JSON at root endpoint

Returns API name, version, description, and available endpoints when
visiting the root URL instead of a 404 error.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: lint

* fix(public-api): return Promise.resolve() for early return in initAssets

The early return when asset data file is not found was returning undefined,
which violates the Promise<void> return type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): handle decimal values in buyAmountCryptoBaseUnit sort

Some swappers return decimal values in buyAmountCryptoBaseUnit which cannot
be converted to BigInt. Strip decimal portion and wrap in try-catch to
prevent the entire rates endpoint from failing.

Also add error handling for swapper module loading failures.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(utils): use lodash-es for ESM compatibility

The utils package has "type": "module" but was importing from lodash
which doesn't support ESM named exports. This caused runtime errors
when running directly with Node.js ESM (e.g., public-api dev server).

Changed lodash to lodash-es which is the official ESM-compatible version.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(public-api): handle undefined array access in buyAmountCryptoBaseUnit sort

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(swapper): use direct @mysten/sui import in CetusSwapper

Import Transaction from @mysten/sui/transactions directly instead of
reaching into @cetusprotocol/aggregator-sdk's node_modules. Added
@mysten/sui as a direct dependency.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(public-api): add smoke test suite for Railway deployment

Add a non-blocking smoke test suite that can run against the deployed API:

- 6 critical tests: health check, asset endpoints, auth validation
- 2 informative tests: EVM same-chain rates (ETH→USDC), cross-chain rates (ETH→BTC)

Tests are bundled with esbuild and included in the Docker image. They always
exit 0 to avoid blocking deployment - failures are logged but don't prevent
the service from starting.

Run locally: `yarn test:smoke`
Run against prod: `API_URL=https://api.example.com yarn test:smoke`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(railway): move swap-widget config to package level

Remove root-level railway.json which was overriding public-api config.
Each service now has its own railway.toml in its package directory.

* fix(public-api): include all workspace packages in Dockerfile

The yarn.lock is generated for the entire monorepo workspace. When only
a subset of package.json files are copied, yarn install --immutable
fails because the workspace definition (packages/*) doesn't match what's
actually present.

Added swap-widget/package.json to ensure all workspaces are present.

* fix(public-api): add missing assertGetTonChainAdapter to SwapperDeps

* fix(public-api): only set initialized flag after successful asset load

Prevent initAssets from marking initialization complete when asset loading
fails, allowing callers to retry. Now returns rejected promise on error or
missing asset file instead of silently succeeding.

* fix(public-api): return 400 for malformed URL encoding in getAssetById

Wrap decodeURIComponent in try/catch to handle URIError from invalid
percent-encoding sequences, returning a 400 with descriptive error
instead of letting it bubble up as a 500.

* fix(public-api): use isNativeEvmAsset for robust native asset detection

Replace inline `includes('slip44:60')` check with the existing
`isNativeEvmAsset` helper from @shapeshiftoss/swapper for detecting
native EVM assets in approval logic. The previous check only matched
Ethereum; this correctly handles all EVM chains.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(public-api): add missing affiliateBps and networkFeeCryptoBaseUnit to RateResponseSchema

Co-Authored-By: Claude <noreply@anthropic.com>

* chore(public-api): lint fixes

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(public-api): coerce boolean and number query params from strings

Query parameters are always received as strings in Express. The Zod
schemas for rates and quote endpoints expected actual boolean/number
types, causing validation errors when allowMultiHop was passed as
"true" or "false" string from the docs example.

- Create shared booleanFromString utility to preprocess string booleans
- Update rates.ts to use booleanFromString for allowMultiHop
- Update quote.ts to use booleanFromString and z.coerce.number()

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(public-api): use env vars for EVM unchained URLs instead of hardcoded values

Allow staging/multi-tenant environments to override EVM chain endpoints via
environment variables while preserving existing defaults as fallbacks.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(public-api): add CLAUDE.md with LLM instructions

* docs: update quote endpoint example to swap ETH to BTC

Change the sample request in the OpenAPI docs from ETH→USDC to ETH→BTC
using the Relay swapper, with appropriate Bitcoin receive address.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(public-api): implement UTXO chain adapter for BTC sell support

THORChain BTC sell trades were failing because assertGetUtxoChainAdapter
was a stub that threw an error. This implements a minimal UTXO adapter
that provides the required interface for rate requests.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(swapper): handle unsupported chains gracefully in Portals and Chainflip

- Update default THORChain Midgard URL to ninerealms.com for reliability
- Fix Portals swapper to validate chain support before calling EVM adapter
- Fix Chainflip swapper to handle undefined error properties with optional chaining

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(public-api): add strict regex validation to rates request schema

Validate sellAmountCryptoBaseUnit with /^\d+$/ to only accept positive integers
and slippageTolerancePercentageDecimal with /^(?:\d+)(?:\.\d+)?$/ to accept
non-negative decimals, rejecting malformed numeric input at the API boundary.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(public-api): replace unsafe any-cast with typed TradeQuoteError fallback

Use nullish coalescing with TradeQuoteError.UnknownError instead of
casting 'UnknownError' as any for proper type safety.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(public-api): add timeout to fetchGasFees using AbortController

Prevents hanging requests when unchained gas fees endpoint is slow/unresponsive.
Uses 10s timeout consistent with RATE_TIMEOUT_MS in rates route.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…r selector memoization (#11605)

* feat: add performance profiling infrastructure and Firefox optimizations

- Add performance profiler with visual overlay for tracking IndexedDB,
  selectors, and asset search performance across browsers
- Add VITE_FEATURE_PERFORMANCE_PROFILER feature flag (dev-only)
- Add throttle (1000ms) to all 13 redux-persist configs to reduce
  write frequency and main thread blocking
- Move small slices (preferences, localWallet, gridplus, addressBook)
  to localStorage for faster reads vs IndexedDB
- Add createLocalStorageAdapter and createProfiledStorage utilities
- Instrument useAssetSearchWorker to track search latency

Profiling revealed Firefox IndexedDB reads are ~6x slower than Chrome
(9.5s vs 1.5s avg). These changes reduce IndexedDB operations and
improve runtime performance, though Firefox's core IndexedDB read
performance remains a browser limitation.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: move IndexedDB operations to Web Worker

Add Web Worker for IndexedDB operations to prevent main thread blocking,
especially critical for Firefox where IndexedDB reads were ~6x slower.

- Add indexedDB.worker.ts - handles getItem/setItem/removeItem in worker
- Add workerStorage.ts - adapter that communicates with worker via postMessage
- Update reducer.ts to use worker storage instead of direct localforage

Results:
- Firefox: Read time reduced from 9,628ms to 109ms (99% improvement)
- Chrome: Read time reduced from 1,339ms to 2.18ms (99.8% improvement)

The worker moves IndexedDB operations off the main thread, keeping the UI
responsive while data loads in the background.

Co-Authored-By: Claude <noreply@anthropic.com>

* perf: replace lodash/isEqual with fast-deep-equal for selector memoization

Switch from lodash/isEqual to fast-deep-equal for the resultEqualityCheck
in createDeepEqualOutputSelector. fast-deep-equal is 2-7x faster for
JSON-like data comparisons, which improves performance for all 157
selectors using deep equality checks across the codebase.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: add proper initialization handshake to IndexedDB Web Worker

The worker was resolving init() immediately after construction, before
the worker script finished loading and localforage was ready. This caused
a 5-second timeout fallback on every page load.

Now uses a ping/ready handshake to ensure localforage.ready() completes
before processing any storage operations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add localStorage availability check for test environment

The profiledStorage module was throwing ReferenceError in Node.js test
environment where localStorage is not defined. Added guards to safely
return early when localStorage is unavailable.

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: unify skills and commands into .skills/ directory

- Create .skills/ directory with skills/ and commands/ subdirectories
- Move git-commit-push skill to .skills/skills/ (portable across projects)
- Move weekly-summary and test-agent commands to .skills/commands/
- Create symlinks for both OpenCode and Claude Code discovery:
  - .opencode/skill -> ../.skills/skills
  - .opencode/command -> ../.skills/commands
  - .claude/commands -> ../.skills/commands
  - .claude/skills/git-commit-push -> ../../.skills/skills/git-commit-push
- ShapeShift-specific skills remain in .claude/skills/
- OpenCode auto-discovers .claude/skills/ for project-specific skills

* fix: lint

* chore: profiler default disabled

* revert: remove unrelated config changes from feature branch

* fix: memory leak in useAssetSearchWorker, remove unused export, i18n PerformanceProfiler

- Fix unbounded growth of searchStartTimeRef Map by clearing before setting new entry and deleting stale entries when requests are ignored
- Remove unused profiledStorage singleton export from profiledStorage.ts
- Internationalize PerformanceProfiler component with translation keys

* fix: add operation timeout and per-key locking to WorkerStorage

- Add 10s timeout to prevent hanging if worker dies or IndexedDB gets stuck
- Add per-key locking to prevent race conditions on concurrent writes
- Clear timeout when response received to prevent memory leaks

---------

Co-authored-by: Claude <noreply@anthropic.com>
* feat(public-api): add chains endpoints

Add GET /v1/chains and GET /v1/chains/count endpoints to return all
supported blockchain networks with metadata including chain type,
native asset info, and explorer links. Chains are sorted alphabetically
by name.

* chore: lint

* refactor(public-api): use idiomatic TS syntax for Chain type

- Change `icon: string | undefined` to `icon?: string`
- Change `nativeAssetId: string` to `nativeAssetId: AssetId` for stronger typing

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: show specific related assets ungrouped when searching by exact symbol

When searching for related assets with different symbols from the primary
asset (e.g., VBUSDC, AXLUSDC for USDC), these specific assets now appear
directly in search results instead of being hidden inside grouped rows.

- Add isExactSymbolMatch utility for consistent symbol comparison
- Update web worker, selector, and AssetRow to search all assets when
  exact non-primary symbol match is found
- Pass searchString through all AssetList entry points for grouping logic

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: improve asset search to find non-primary assets and preserve market cap order

- Fix search to find non-primary assets like AXLUSDC, VBUSDC by only
  checking if search is prefix of primary symbol (not the reverse)
- Short primary symbols (V, AX, AXL) no longer incorrectly match VBUSDC/AXLUSDC
- Add baseSort to matchSorter to preserve market cap order within same rank tier
- Apply market cap ordering fix to Assets page and ExploreCategory

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: improve asset search deduplication and grouping

- Extract deduplicateAssetsBySymbol and shouldSearchAllAssets to shared utils
- Update deduplication to prefer primary assets over non-primary variants
- Fix grouping condition to only skip grouping when searching for unique
  non-primary symbols (e.g., AXLUSDC) not same-symbol variants
- Add deduplication to selectAssetsBySearchQuery selector
- Add comprehensive tests for the new utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* wip: add isPrimary to SearchableAsset and debug logging

- Add isPrimary field to SearchableAsset type for proper deduplication
- Add debug logging to worker for USDT search issue investigation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: deduplicate assets by relatedAssetKey to prevent duplicate groups

- Add new deduplicateAssets function that uses relatedAssetKey instead of symbol
- This ensures USDT and USDT0 (same family) show as one group, not two
- Exact symbol matches still override primary preference (e.g., "axlusdc" shows AXLUSDC)
- Add relatedAssetKey to SearchableAsset type
- Update worker and common-selectors to use new function
- Add comprehensive tests for the new deduplication logic

Note: USDT still not appearing in "usd" search - separate matchSorter issue

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: prioritize primary assets in search results by market cap

Fixes issue where major stablecoins (USDT, USDC) were getting ranked
lower than obscure tokens when searching "usd" because matchSorter
ranks by match quality and "Tether" doesn't contain "usd" in the name.

The fix adds prioritizePrimaryAssets() which re-sorts matched primary
assets by their original market cap order, ensuring high market cap
tokens always appear before low market cap ones regardless of
matchSorter's name/symbol ranking.

This is a holistic fix that:
- "usd" search: USDT, USDC appear first (by market cap)
- "usdc" search: USDC appears, AXLUSDC deduped
- "usdt" search: USDT appears, USDT0 deduped
- "axlusdc" search: AXLUSDC appears (exact match for non-primary)
- "usdt0" search: USDT0 appears (exact match for non-primary)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: prioritize by symbol match quality, not just market cap

Previous fix prioritized all primary assets by market cap, which caused
LP pools (like "Yearn USDC yVault Pool" with symbol YVUSDC) to appear
before actual stablecoins because LP pools have high TVL.

New approach prioritizes by symbol match quality:
1. Exact symbol match (search "usdc" → USDC)
2. Symbol starts with search (search "usd" → USDC, USDT, USDS)
3. Other matches (name contains search → LP pools)

Within each group, assets maintain market cap order.

Test results:
- "usd" → USDT #2, USDC #3 (after USD exact match), LP pools after
- "usdt" → USDT first
- "usdc" → USDC first
- "axlusdc" → AXLUSDC first (exact non-primary match)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: group on related assets ton usdc usdt

* fix: show grouped dropdown for exact non-primary symbol searches

When searching for exact non-primary symbols like "axlusdc" or "axlusdt",
the assets now correctly display as grouped rows with chain dropdowns.

Previously, the isSearchingForUniqueNonPrimarySymbol check incorrectly
prevented grouping for these searches. The filteredRelatedAssetIds logic
already handles filtering to same-symbol variants for non-primary assets,
making the additional check unnecessary.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add asset search grouping and architecture documentation

Added documentation for agents working on the asset search feature:
- ASSET_GROUPING.md: Explains grouping logic, primary vs non-primary assets
- ASSET_SEARCH_ARCHITECTURE.md: Overall data flow, key files, common modifications

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: clean up asset search deduplication and utils

- Remove unused config.ts
- Simplify deduplicateAssets logic with cleaner grouping
- Add comprehensive tests for deduplication and utils
- Streamline utils.ts symbol matching functions
- Clean up common-selectors.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: improve asset search code quality and documentation

- Restore arrow function syntax and comments in worker
- Rename assets -> allAssets for clarity in worker
- Add MINIMUM_MARKET_CAP_THRESHOLD constant (removes magic number)
- Use existing isExactSymbolMatch in deduplicateAssets
- Fix redundant bnOrZero calls in selector
- Add comment explaining worker vs selector behavior difference
- Fix documentation: remove incorrect Fuse.js references, fix JSDoc examples
- Update ASSET_SEARCH_ARCHITECTURE.md with accurate implementation details

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: use real asset data from generatedAssetData.json in tests

Extract actual assetIds from production data for more realistic test coverage.
Add testData.ts with real USDC, USDT, AXLUSDC, ETH, and BTC assets.
Restore removed "Always filter out NFTs" comment in utils.ts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: fix lint errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: replace matchSorter with searchAssets for consistent name search

Replace matchSorter with the centralized searchAssets utility in:
- Assets.tsx: simplifies filterRowsBySearchTerm callback
- ExploreCategory.tsx: simplifies filteredAssets useMemo

This ensures "Bitcoin" name search works consistently across all
asset search locations (trade widget, explore page, assets page).

Also removes unused searchString prop that was passed through but
never consumed by AssetRow component.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: simplify Assets and ExploreCategory components

- Remove unnecessary isSearching useMemo in Assets.tsx
- Simplify rows dependency by checking searchQuery directly
- Consolidate categoryHook conditions in ExploreCategory.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(assetSearch): cleanup PR and enhance tests with real-world data

- Remove unused searchString prop from AssetSearch, AssetList, AssetResults,
  SearchTermAssetList, and Explore components
- Remove deprecated deduplicateAssetsBySymbol function and its tests
- Extract magic score numbers to named SCORE constants in utils.ts
- Remove debug console.log statements from searchAssets
- Add comprehensive real-world asset test data (BCH, WBTC, USDC.E, USDe, spam tokens)
- Add real-world scenario tests for stablecoin, bitcoin family, ethereum,
  bridged asset, and spam token filtering searches
- Update shouldSearchAllAssets tests to match new test data (LBTC now primary)
- Consolidate duplicate test data definitions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: update asset search architecture and simplify TestAsset type

- Update ASSET_SEARCH_ARCHITECTURE.md with current scoring algorithm:
  - Document PRIMARY_NAME/PRIMARY_SYMBOL score tiers
  - Add spam token filtering section (symbol length + market cap checks)
  - Document multi-level sorting (score → relatedAssetKey → originalIndex)
- Simplify TestAsset type to use Required<SearchableAsset> instead of
  duplicating the type definition

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: rename stablecoinAssets to usdAssets and isExactSymbolMatch to isExactMatch

- Rename stablecoinAssets to usdAssets with descriptive comment
- Simplify isExactSymbolMatch to isExactMatch (params are self-documenting)
- Update docs and all usages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: convert functions to arrow functions and fix docs

- Convert all functions in utils.ts to const arrow functions
- Fix docs: replace "fuzzy search" with "score-based search"
- Remove redundant "fuzzy matches" wording

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: cleanup asset search types and convert to arrow functions

- Convert deduplicateAssets and shouldSearchAllAssets to arrow functions
- Simplify types using Pick<SearchableAsset, ...> instead of separate definitions
- Remove redundant @param JSDoc comments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: NeOMakinG <14963751+NeOMakinG@users.noreply.github.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 22, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@0xApotheosis 0xApotheosis merged commit 63ea69a into main Jan 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants