Full Code of layerswap/layerswapapp for AI

dev c251cec71dc1 cached
728 files
2.7 MB
750.4k tokens
1561 symbols
1 requests
Download .txt
Showing preview only (2,996K chars total). Download the full file or copy to clipboard to get everything.
Repository: layerswap/layerswapapp
Branch: dev
Commit: c251cec71dc1
Files: 728
Total size: 2.7 MB

Directory structure:
gitextract_wrqmm7zr/

├── .claude/
│   ├── agents/
│   │   ├── pr-review-coordinator.md
│   │   ├── pr-reviewer-architecture.md
│   │   ├── pr-reviewer-bugs.md
│   │   ├── pr-reviewer-performance.md
│   │   ├── pr-reviewer-quality.md
│   │   ├── pr-reviewer-react.md
│   │   ├── pr-reviewer-security.md
│   │   └── pr-reviewer.md
│   ├── commands/
│   │   └── reviewchanges.md
│   └── skills/
│       └── vercel-react-best-practices/
│           ├── SKILL.md
│           └── rules/
│               ├── advanced-event-handler-refs.md
│               ├── advanced-use-latest.md
│               ├── async-api-routes.md
│               ├── async-defer-await.md
│               ├── async-dependencies.md
│               ├── async-parallel.md
│               ├── async-suspense-boundaries.md
│               ├── bundle-barrel-imports.md
│               ├── bundle-conditional.md
│               ├── bundle-defer-third-party.md
│               ├── bundle-dynamic-imports.md
│               ├── bundle-preload.md
│               ├── client-event-listeners.md
│               ├── client-localstorage-schema.md
│               ├── client-passive-event-listeners.md
│               ├── client-swr-dedup.md
│               ├── js-batch-dom-css.md
│               ├── js-cache-function-results.md
│               ├── js-cache-property-access.md
│               ├── js-cache-storage.md
│               ├── js-combine-iterations.md
│               ├── js-early-exit.md
│               ├── js-hoist-regexp.md
│               ├── js-index-maps.md
│               ├── js-length-check-first.md
│               ├── js-min-max-loop.md
│               ├── js-set-map-lookups.md
│               ├── js-tosorted-immutable.md
│               ├── rendering-activity.md
│               ├── rendering-animate-svg-wrapper.md
│               ├── rendering-conditional-render.md
│               ├── rendering-content-visibility.md
│               ├── rendering-hoist-jsx.md
│               ├── rendering-hydration-no-flicker.md
│               ├── rendering-svg-precision.md
│               ├── rerender-defer-reads.md
│               ├── rerender-dependencies.md
│               ├── rerender-derived-state.md
│               ├── rerender-functional-setstate.md
│               ├── rerender-lazy-state-init.md
│               ├── rerender-memo.md
│               ├── rerender-simple-expression-in-memo.md
│               ├── rerender-transitions.md
│               ├── server-after-nonblocking.md
│               ├── server-auth-actions.md
│               ├── server-cache-lru.md
│               ├── server-cache-react.md
│               ├── server-dedup-props.md
│               ├── server-parallel-fetching.md
│               ├── server-serialization.md
│               └── unused-detection.md
├── .eslintrc.json
├── .github/
│   └── workflows/
│       ├── chromatic.yml
│       ├── deploy.yml
│       └── rebase-main-sandbox.yml
├── .gitignore
├── .storybook/
│   ├── main.ts
│   ├── manager.js
│   └── preview.ts
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── AGENTS.md
├── CLAUDE.md
├── Models/
│   ├── ApiError.ts
│   ├── ApiResponse.ts
│   ├── Balance.ts
│   ├── BalanceProvider.ts
│   ├── Exchange.ts
│   ├── LayerSwapAppSettings.ts
│   ├── LayerSwapAuth.ts
│   ├── LayerSwapSettings.ts
│   ├── Network.ts
│   ├── Partner.ts
│   ├── QueryParams.ts
│   ├── RangeError.ts
│   ├── Route.ts
│   ├── SwapStatus.ts
│   ├── Theme.ts
│   ├── WalletConnectWallet.ts
│   ├── WalletProvider.ts
│   └── Wizard.ts
├── README.md
├── components/
│   ├── AddressIcon/
│   │   ├── colors.mjs
│   │   ├── index.tsx
│   │   ├── jazzicon/
│   │   │   ├── colors.js
│   │   │   ├── index.js
│   │   │   ├── mersenne-twister.js
│   │   │   └── paper.js
│   │   ├── jazzicon.mjs
│   │   ├── mersenne-twister.mjs
│   │   └── paper.mjs
│   ├── AvatarGroup.tsx
│   ├── Campaigns/
│   │   ├── Details/
│   │   │   ├── Leaderboard.tsx
│   │   │   ├── Rewards.tsx
│   │   │   └── index.tsx
│   │   └── index.tsx
│   ├── Carousel.tsx
│   ├── ColorSchema.tsx
│   ├── Common/
│   │   ├── AnimatedValue.tsx
│   │   ├── AverageCompletionTime.tsx
│   │   ├── ConnectWalletButton.tsx
│   │   ├── CountDownTimer.tsx
│   │   ├── FormattedAverageCompletionTime.tsx
│   │   ├── FormattedDate.tsx
│   │   ├── ImageWithFallback.tsx
│   │   ├── LinkWithIcon.tsx
│   │   ├── NumFlowWithFallback.tsx
│   │   ├── ReactPortal.tsx
│   │   └── TypingEffect.tsx
│   ├── ConnectNetwork.tsx
│   ├── ContactSupport.tsx
│   ├── DTOs/
│   │   ├── SwapConfirmationFormValues.ts
│   │   └── SwapFormValues.ts
│   ├── ErrorFallback.tsx
│   ├── FeeDetails/
│   │   ├── DepositMethod/
│   │   │   └── index.tsx
│   │   ├── Rate.tsx
│   │   ├── ReceiveAmounts.tsx
│   │   ├── Refuel.tsx
│   │   ├── RefuelModal.tsx
│   │   ├── Slippage.tsx
│   │   ├── SwapQuote/
│   │   │   ├── DetailedEstimates.tsx
│   │   │   ├── SummaryRow.tsx
│   │   │   └── index.tsx
│   │   └── index.tsx
│   ├── HeaderWithMenu/
│   │   └── index.tsx
│   ├── Input/
│   │   ├── Address/
│   │   │   ├── AddressPicker/
│   │   │   │   ├── AddressBook.tsx
│   │   │   │   ├── AddressButton.tsx
│   │   │   │   ├── AddressWithIcon.tsx
│   │   │   │   ├── ConnectedWallets.tsx
│   │   │   │   ├── ManualAddressInput.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── ContractAddressNote.tsx
│   │   │   ├── UrlAddressNote.tsx
│   │   │   └── index.tsx
│   │   ├── Amount/
│   │   │   ├── Balance.tsx
│   │   │   ├── ExchangeAmountField.tsx
│   │   │   ├── ExchangeReceiveAmount.tsx
│   │   │   ├── MinMax.tsx
│   │   │   ├── PriceImpact.tsx
│   │   │   ├── ReceiveAmount.tsx
│   │   │   ├── helpers.ts
│   │   │   └── index.tsx
│   │   ├── CexPicker.tsx
│   │   ├── DestinationPicker.tsx
│   │   ├── DestinationWalletPicker.tsx
│   │   ├── NumericInput.tsx
│   │   ├── RoutePicker/
│   │   │   ├── Content.tsx
│   │   │   ├── RouteSearch.tsx
│   │   │   ├── RouteSortingMenu.tsx
│   │   │   ├── RouteTokenSwitch.tsx
│   │   │   ├── RouterPickerWalletConnect.tsx
│   │   │   ├── Routes.tsx
│   │   │   ├── Rows/
│   │   │   │   ├── CollapsableHeader.tsx
│   │   │   │   ├── CollapsibleRow.tsx
│   │   │   │   ├── StickyHeader.tsx
│   │   │   │   ├── SuggestionsHeader.tsx
│   │   │   │   ├── TitleRow.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── TokenTitleDetails.tsx
│   │   │   └── index.tsx
│   │   ├── Search.tsx
│   │   ├── SourcePicker.tsx
│   │   ├── SourceWalletPicker.tsx
│   │   └── TransferCEX.tsx
│   ├── LayerswapMenu/
│   │   ├── Menu.tsx
│   │   ├── MenuList.tsx
│   │   └── index.tsx
│   ├── LinkWraapper.tsx
│   ├── LoadingCard.tsx
│   ├── MessageComponent.tsx
│   ├── NavigatableList/
│   │   ├── NavigatableItem.tsx
│   │   ├── NavigatableList.tsx
│   │   ├── context.ts
│   │   ├── hooks.ts
│   │   └── index.tsx
│   ├── NoCookies.tsx
│   ├── ProgressBar.tsx
│   ├── QRCodeWallet.tsx
│   ├── ReserveGasNote.tsx
│   ├── ResizablePanel.tsx
│   ├── Sceletons.tsx
│   ├── Select/
│   │   ├── Command/
│   │   │   ├── CommandSelectWrapper.tsx
│   │   │   └── commandSelect.tsx
│   │   ├── Popover/
│   │   │   ├── PopoverSelect.tsx
│   │   │   └── PopoverSelectWrapper.tsx
│   │   ├── Selector/
│   │   │   ├── Index.tsx
│   │   │   └── SelectItem.tsx
│   │   └── Shared/
│   │       ├── Props/
│   │       │   ├── SelectProps.tsx
│   │       │   └── selectMenuItem.tsx
│   │       └── SelectItem.tsx
│   ├── Swap/
│   │   ├── Form/
│   │   │   ├── ExchangeForm.tsx
│   │   │   ├── FormWrapper.tsx
│   │   │   ├── NetworkExchangeTabs.tsx
│   │   │   ├── NetworkForm.tsx
│   │   │   ├── index.tsx
│   │   │   └── updateForm.ts
│   │   ├── FormButton.tsx
│   │   ├── NotFound.tsx
│   │   ├── Step.tsx
│   │   ├── StepsComponent.tsx
│   │   ├── Summary/
│   │   │   ├── Summary.tsx
│   │   │   └── index.tsx
│   │   ├── Withdraw/
│   │   │   ├── Failed.tsx
│   │   │   ├── ManualWithdraw.tsx
│   │   │   ├── Processing/
│   │   │   │   ├── Processing.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   └── types.ts
│   │   │   ├── QuoteUpdate.tsx
│   │   │   ├── Success.tsx
│   │   │   ├── SwapQuoteDetails.tsx
│   │   │   ├── Wallet/
│   │   │   │   ├── Common/
│   │   │   │   │   ├── buttons.tsx
│   │   │   │   │   └── sharedTypes.ts
│   │   │   │   ├── WithdrawalProviders/
│   │   │   │   │   ├── BitcoinWalletWithdraw/
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   ├── sendTransaction.ts
│   │   │   │   │   │   └── transactionBuilder/
│   │   │   │   │   │       ├── buildPsbt.ts
│   │   │   │   │   │       ├── estimateFee.ts
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── EVMWalletWithdraw/
│   │   │   │   │   │   ├── RPCUnhealthyMessage.tsx
│   │   │   │   │   │   ├── TransferToken.tsx
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   ├── resolveError.tsx
│   │   │   │   │   │   └── transactionMessage.tsx
│   │   │   │   │   ├── FuelWalletWithdrawal.tsx
│   │   │   │   │   ├── Loopring/
│   │   │   │   │   │   ├── ActivationTokentPicker.tsx
│   │   │   │   │   │   ├── hooks.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SVMWalletWithdraw/
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   └── transactionSender.ts
│   │   │   │   │   ├── StarknetWalletWithdraw.tsx
│   │   │   │   │   ├── TempoWalletWithdraw/
│   │   │   │   │   │   ├── TransferToken.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── TonWalletWithdraw.tsx
│   │   │   │   │   ├── TronWalletWithdraw.tsx
│   │   │   │   │   ├── ZKsyncWalletWithdraw.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── paradex/
│   │   │   │   │       ├── Evm.tsx
│   │   │   │   │       ├── Starknet.tsx
│   │   │   │   │       └── index.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── WalletTransferButton.tsx
│   │   │   ├── WalletTransferContent.tsx
│   │   │   ├── index.tsx
│   │   │   └── messages/
│   │   │       ├── Message.tsx
│   │   │       └── TransactionMessages.tsx
│   │   └── index.tsx
│   ├── SwapGuide.tsx
│   ├── SwapHistory/
│   │   ├── Filters/
│   │   │   ├── CheckboxRow.tsx
│   │   │   ├── ClearAllButton.tsx
│   │   │   ├── NetworksDropdown.tsx
│   │   │   ├── NoMatches.tsx
│   │   │   ├── SearchResult.tsx
│   │   │   ├── WalletsDropdown.tsx
│   │   │   ├── chipStyles.ts
│   │   │   ├── filterSwaps.ts
│   │   │   ├── index.tsx
│   │   │   └── types.ts
│   │   ├── Header.tsx
│   │   ├── History.tsx
│   │   ├── HistorySummary.tsx
│   │   ├── Snippet.tsx
│   │   ├── StatusIcons.tsx
│   │   ├── SwapDetailsComponent.tsx
│   │   └── index.tsx
│   ├── SwapWithdrawal.tsx
│   ├── Tooltips/
│   │   └── ClickTooltip.tsx
│   ├── Wallet/
│   │   ├── ConnectedWallets.tsx
│   │   └── WalletsList.tsx
│   ├── WalletModal/
│   │   ├── Connector.tsx
│   │   ├── ConnectorsList.tsx
│   │   ├── InstalledExtensionNotFound.tsx
│   │   ├── LoadingConnect.tsx
│   │   ├── MultichainConnectorPicker.tsx
│   │   ├── ProviderPicker.tsx
│   │   ├── WalletQrCode.tsx
│   │   ├── index.tsx
│   │   └── utils.ts
│   ├── WalletProviders/
│   │   ├── ActiveEvmAccount.tsx
│   │   ├── ActiveParadexAccount.tsx
│   │   ├── BitcoinProvider.tsx
│   │   ├── FuelProvider.tsx
│   │   ├── ImtblPassportProvider.tsx
│   │   ├── SolanaProvider.tsx
│   │   ├── StarknetProvider.tsx
│   │   ├── TonConnectProvider.tsx
│   │   ├── TronProvider.tsx
│   │   ├── Wagmi.tsx
│   │   └── index.tsx
│   ├── WarningMessage.tsx
│   ├── Widget/
│   │   ├── Content.tsx
│   │   ├── Footer.tsx
│   │   └── Index.tsx
│   ├── Wizard/
│   │   ├── Wizard.tsx
│   │   └── WizardItem.tsx
│   ├── backgroundField.tsx
│   ├── banner.tsx
│   ├── buttons/
│   │   ├── connectButton.tsx
│   │   ├── copyButton.tsx
│   │   ├── exploreButton.tsx
│   │   ├── iconButton.tsx
│   │   ├── secondaryButton.tsx
│   │   ├── submitButton.tsx
│   │   └── toggleButton.tsx
│   ├── cardContainer.tsx
│   ├── docInIframe.tsx
│   ├── gauge.tsx
│   ├── globalFooter.tsx
│   ├── guideLink.tsx
│   ├── icons/
│   │   ├── AlertIcon.tsx
│   │   ├── CancelIcon.tsx
│   │   ├── ChatIcon.tsx
│   │   ├── CheckIcon.tsx
│   │   ├── CircleCheckIcon.tsx
│   │   ├── CircularLoader.tsx
│   │   ├── Clock.tsx
│   │   ├── ConnectorIcons.tsx
│   │   ├── CopyIcon.tsx
│   │   ├── DelayIcon.tsx
│   │   ├── DiscordLogo.tsx
│   │   ├── ExchangeGasIcon.tsx
│   │   ├── ExchangeTabIcon.tsx
│   │   ├── FailIcon.tsx
│   │   ├── FeeIcon.tsx
│   │   ├── FilledCheck.tsx
│   │   ├── FilledX.tsx
│   │   ├── GasIcon.tsx
│   │   ├── GitHubLogo.tsx
│   │   ├── GlobeIcon.tsx
│   │   ├── InfoIcon.tsx
│   │   ├── LogoPlaceholder.tsx
│   │   ├── MenuIcon.tsx
│   │   ├── NetworkTabIcon.tsx
│   │   ├── NotFoundIcon.tsx
│   │   ├── QRIcon.tsx
│   │   ├── Question.tsx
│   │   ├── RouteIcon.tsx
│   │   ├── RoutePickerPlaceholder.tsx
│   │   ├── SearchIcon.tsx
│   │   ├── SignatureIcon.tsx
│   │   ├── SubstackLogo.tsx
│   │   ├── SuccessIcon.tsx
│   │   ├── SvgWithImg.tsx
│   │   ├── TokenIcon.tsx
│   │   ├── TwitterLogo.tsx
│   │   ├── WalletIcon.tsx
│   │   ├── Wallets/
│   │   │   ├── Argent.tsx
│   │   │   ├── ArgentX.tsx
│   │   │   ├── BakoSafe.tsx
│   │   │   ├── BitKeep.tsx
│   │   │   ├── Bitget.tsx
│   │   │   ├── Braavos.tsx
│   │   │   ├── BrowserWallet.tsx
│   │   │   ├── Coinbase.tsx
│   │   │   ├── Controller.tsx
│   │   │   ├── Ethereum.tsx
│   │   │   ├── Fuel.tsx
│   │   │   ├── Fuelet.tsx
│   │   │   ├── Glow.tsx
│   │   │   ├── IMX.tsx
│   │   │   ├── ImtblPassport.tsx
│   │   │   ├── Keplr.tsx
│   │   │   ├── MetaMask.tsx
│   │   │   ├── MyTonWallet.tsx
│   │   │   ├── OpenMask.tsx
│   │   │   ├── Phantom.tsx
│   │   │   ├── Rainbow.tsx
│   │   │   ├── Solana.tsx
│   │   │   ├── Solflare.tsx
│   │   │   ├── Starknet.tsx
│   │   │   ├── TON.tsx
│   │   │   ├── TonKeeper.tsx
│   │   │   ├── WalletConnect.tsx
│   │   │   └── Xverse.tsx
│   │   ├── YoutubeLogo.tsx
│   │   ├── layerSwapLogo.tsx
│   │   ├── layerSwapLogoSmall.tsx
│   │   ├── layerSwapMobileLogo.tsx
│   │   └── spinIcon.tsx
│   ├── layout.tsx
│   ├── maintanance/
│   │   └── maintanance.tsx
│   ├── modal/
│   │   ├── leaflet.tsx
│   │   ├── modal.tsx
│   │   ├── modalWithoutAnimation.tsx
│   │   ├── vaul/
│   │   │   ├── browser.ts
│   │   │   ├── constants.ts
│   │   │   ├── context.ts
│   │   │   ├── helpers.ts
│   │   │   ├── index.tsx
│   │   │   ├── types.ts
│   │   │   ├── use-composed-refs.ts
│   │   │   ├── use-controllable-state.ts
│   │   │   ├── use-position-fixed.ts
│   │   │   ├── use-prevent-scroll.ts
│   │   │   ├── use-scale-background.ts
│   │   │   └── use-snap-points.ts
│   │   └── vaulModal.tsx
│   ├── navbar.tsx
│   ├── sendFeedback.tsx
│   ├── shadcn/
│   │   ├── accordion.tsx
│   │   ├── checkbox.tsx
│   │   ├── command.tsx
│   │   ├── dialog.tsx
│   │   ├── popover.tsx
│   │   ├── select.tsx
│   │   ├── tab.tsx
│   │   └── tooltip.tsx
│   ├── swapComponent.tsx
│   ├── themeWrapper.tsx
│   ├── utils/
│   │   ├── GoHome.tsx
│   │   ├── RoundDecimals.ts
│   │   ├── ShortenString.tsx
│   │   ├── classNames.ts
│   │   ├── convertSvgComponentToBase64.tsx
│   │   ├── dateDifference.ts
│   │   ├── formatUsdAmount.ts
│   │   ├── groupBy.ts
│   │   ├── inIframe.ts
│   │   ├── isGuid.ts
│   │   ├── numbers.ts
│   │   ├── resolveSwapPhase.ts
│   │   ├── swapUtils.ts
│   │   ├── timeCalculations.ts
│   │   └── upperCaseKeys.ts
│   └── validationError/
│       ├── AdjustAmountButton.tsx
│       ├── ContractAddressValidationCache.tsx
│       ├── ErrorDisplay.tsx
│       ├── RefreshBalanceButton.tsx
│       ├── constants.ts
│       └── index.tsx
├── context/
│   ├── asyncModal.tsx
│   ├── formWizardProvider.tsx
│   ├── loadingContext.tsx
│   ├── query.tsx
│   ├── settings.tsx
│   ├── snapPointsContext.tsx
│   ├── swap.tsx
│   ├── swapAccounts.tsx
│   ├── timerContext.tsx
│   ├── validationContext.tsx
│   ├── walletProviders.tsx
│   └── withdrawalContext.tsx
├── eslint-plugins/
│   └── eslint-plugin-no-conditional-literals-in-jsx/
│       ├── index.js
│       ├── package.json
│       ├── rules/
│       │   ├── no-conditional-literals-in-jsx.js
│       │   └── no-unwrapped-jsx-text.js
│       ├── tests.js
│       └── utils/
│           ├── constants.js
│           └── jsx.js
├── funding.json
├── helpers/
│   ├── accountSelectHelper.ts
│   ├── balanceHelper.ts
│   ├── errorHelper.ts
│   ├── getSettings.ts
│   ├── querryHelper.ts
│   ├── routes.ts
│   ├── settingsCompression.ts
│   ├── settingsHelper.ts
│   ├── storageAvailable.ts
│   ├── tokenHelper.tsx
│   └── validateSignature.ts
├── hooks/
│   ├── useAllWithdrawalBalances.tsx
│   ├── useAutoSlippageTest.tsx
│   ├── useClickOutside.ts
│   ├── useConnectors.ts
│   ├── useCopyClipboard.ts
│   ├── useExchangeNetworks.ts
│   ├── useFee.tsx
│   ├── useFormRoutes.ts
│   ├── useFormValidation.ts
│   ├── useGoHome.ts
│   ├── useHistoryFilters.ts
│   ├── useInterval.ts
│   ├── useIsWindowVisible.ts
│   ├── useKeyboardNavigation.ts
│   ├── useNavigatableList.ts
│   ├── usePersistedState.ts
│   ├── useResolvedSwapStatus.ts
│   ├── useRouteValidation.tsx
│   ├── useStorage.ts
│   ├── useSuggestionsLimit.tsx
│   ├── useSwapByTransactionHash.ts
│   ├── useSwapHistoryData.ts
│   ├── useSwrSwaps.ts
│   ├── useUsdTokenSync.ts
│   ├── useWallet.ts
│   ├── useWalletRpcHealth.tsx
│   ├── useWalletTransferOptions.ts
│   └── useWindowDimensions.tsx
├── lib/
│   ├── AnimatedNumber.tsx
│   ├── AppSettings.ts
│   ├── CurrencySettings.ts
│   ├── Errors/
│   │   └── AuthRefreshFailedError.ts
│   ├── ExchangeSettings.ts
│   ├── NetworkSettings.ts
│   ├── SwapSettings.ts
│   ├── abis/
│   │   ├── BALANCEGETTERABI.json
│   │   ├── ERC20.json
│   │   ├── FUELWATCHDOG.json
│   │   ├── LSWATCHDOG.json
│   │   └── usdt.json
│   ├── address/
│   │   ├── Address.ts
│   │   ├── explorerUrl.ts
│   │   ├── formatter.ts
│   │   ├── index.ts
│   │   └── validator/
│   │       ├── index.ts
│   │       └── starkNetAddressValidator.ts
│   ├── apiClients/
│   │   ├── hyperliquidClient.ts
│   │   ├── jsonRpcClient.ts
│   │   └── layerSwapApiClient.ts
│   ├── axiosInterceptor.ts
│   ├── balances/
│   │   ├── balanceResolver.ts
│   │   ├── errorUtils.ts
│   │   ├── helpers.ts
│   │   ├── nodeErrorClassifier.ts
│   │   ├── providers/
│   │   │   ├── bitcoinBalanceProvider.ts
│   │   │   ├── evmBalanceProvider.ts
│   │   │   ├── fuelBalanceProvider.ts
│   │   │   ├── hyperliquidBalanceProvider.ts
│   │   │   ├── index.ts
│   │   │   ├── loopringBalanceProvider.ts
│   │   │   ├── paradexBalanceProvider.ts
│   │   │   ├── queryBalanceProvider.ts
│   │   │   ├── solanaBalanceProvider.ts
│   │   │   ├── starknetBalanceProvider.ts
│   │   │   ├── tonBalanceProvider.ts
│   │   │   ├── tronBalanceProvider.ts
│   │   │   └── zkSyncBalanceProvider.ts
│   │   └── useBalance.ts
│   ├── calculateDatesDifference.ts
│   ├── dynamicWithRetries/
│   │   └── defaultError.tsx
│   ├── ethersToViem/
│   │   └── ethers.ts
│   ├── external/
│   │   └── nameof/
│   │       ├── index.ts
│   │       ├── name-of.ts
│   │       ├── path-of.ts
│   │       ├── separated-path-of.ts
│   │       └── types.ts
│   ├── fees.ts
│   ├── fetchWithTimeout.ts
│   ├── fuels/
│   │   ├── common/
│   │   │   ├── FakeAccount.ts
│   │   │   ├── PredicateConnector.ts
│   │   │   ├── PredicateFactory.ts
│   │   │   ├── PredicateWalletAdapter.ts
│   │   │   ├── index.ts
│   │   │   ├── networks.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── connectors/
│   │   │   ├── bako-safe/
│   │   │   │   ├── BakoSafeConnector.ts
│   │   │   │   ├── BakoSafeStorage.ts
│   │   │   │   ├── DAPPWindow.ts
│   │   │   │   ├── SocketClient.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── request.ts
│   │   │   │   └── types.ts
│   │   │   ├── fuel-wallet/
│   │   │   │   ├── FuelWalletConnector.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── fuelet-wallet/
│   │   │   │   ├── FueletWalletConnector.ts
│   │   │   │   ├── constants.ts
│   │   │   │   └── index.ts
│   │   │   └── walletConnect/
│   │   │       ├── WalletConnectConnector.ts
│   │   │       ├── constants.ts
│   │   │       ├── index.ts
│   │   │       ├── types.ts
│   │   │       ├── utils/
│   │   │       │   ├── index.ts
│   │   │       │   └── subscribeAndEnforceChain.ts
│   │   │       └── web3Modal.ts
│   │   └── evm-predicates/
│   │       ├── 0xbbae06500cd11e6c1d024ac587198cb30c504bf14ba16548f19e21fa9e8f5f95/
│   │       │   └── index.ts
│   │       ├── 0xfdac03fc617c264fa6f325fd6f4d2a5470bf44cfbd33bc11efb3bf8b7ee2e938/
│   │       │   └── index.ts
│   │       └── index.ts
│   ├── gases/
│   │   ├── gasResolver.ts
│   │   ├── providers/
│   │   │   ├── bitcoinGasProvider.ts
│   │   │   ├── evmGasProvider.ts
│   │   │   ├── fuelGasProvider.ts
│   │   │   ├── loopringGasProvider.ts
│   │   │   ├── solanaGasProvider.ts
│   │   │   ├── starknetGasProvider.ts
│   │   │   ├── tonGasProvider.ts
│   │   │   ├── tronGasProvider.ts
│   │   │   ├── types.ts
│   │   │   └── zkSyncGasProvider.ts
│   │   ├── useOutOfGas.ts
│   │   └── useSWRGas.tsx
│   ├── generateSwapInitialValues.ts
│   ├── isMobile.ts
│   ├── jwtParser.ts
│   ├── knownIds.ts
│   ├── logError.ts
│   ├── loopring/
│   │   ├── LoopringAPI.ts
│   │   ├── defs.ts
│   │   ├── eddsa.ts
│   │   ├── field.ts
│   │   ├── formatter.ts
│   │   ├── helpers.ts
│   │   ├── jubjub.ts
│   │   ├── permutation.ts
│   │   ├── poseidon/
│   │   │   ├── EDDSAUtil.ts
│   │   │   ├── babyJub.ts
│   │   │   └── eddsa.ts
│   │   └── utils.ts
│   ├── nft/
│   │   ├── nftBalanceResolver.ts
│   │   ├── providers/
│   │   │   ├── starknetNftProvider.ts
│   │   │   └── types.ts
│   │   └── useSWRNftBalance.tsx
│   ├── openLink.ts
│   ├── resolveChain.ts
│   ├── resolveTransports.ts
│   ├── retry.ts
│   ├── telegram.ts
│   ├── virtual/
│   │   ├── core/
│   │   │   ├── index.ts
│   │   │   └── utils.ts
│   │   └── index.tsx
│   └── wallets/
│       ├── bitcoin/
│       │   ├── getConnections.ts
│       │   ├── useAccount.ts
│       │   ├── useBitcoin.ts
│       │   └── useSyncExternalStoreWithTracked.ts
│       ├── connectors/
│       │   ├── browserInjected/
│       │   │   └── index.ts
│       │   ├── explicitInjectedProviderDetected.ts
│       │   ├── resolveConnectors/
│       │   │   └── walletConnect.ts
│       │   ├── types.ts
│       │   ├── useSyncProviders/
│       │   │   ├── EthereumProviderTypes.d.ts
│       │   │   ├── index.ts
│       │   │   └── store.ts
│       │   └── utils/
│       │       └── isMobile.ts
│       ├── evm/
│       │   ├── KnownEVMConnectors.tsx
│       │   ├── constants.ts
│       │   └── useEVM.ts
│       ├── fuel/
│       │   ├── Bako.ts
│       │   ├── KnownFuelConnectors.tsx
│       │   └── useFuel.ts
│       ├── paradex/
│       │   ├── Authorize/
│       │   │   ├── Ethereum.ts
│       │   │   └── Starknet.ts
│       │   ├── lib/
│       │   │   ├── account.ts
│       │   │   ├── config.ts
│       │   │   ├── constants.ts
│       │   │   ├── ethereum-signer.ts
│       │   │   ├── index.ts
│       │   │   ├── paraclear-provider.ts
│       │   │   ├── paraclear.ts
│       │   │   ├── starknet-account-support.ts
│       │   │   ├── starknet-signer.ts
│       │   │   └── types.ts
│       │   └── useParadex.ts
│       ├── solana/
│       │   ├── KnownSolanaConnectors.tsx
│       │   ├── SolanaWalletConnectAdapter.ts
│       │   ├── transactionBuilder.ts
│       │   └── useSVM.tsx
│       ├── starknet/
│       │   ├── KnownStarknetConnectors.tsx
│       │   └── useStarknet.ts
│       ├── ton/
│       │   ├── client.ts
│       │   └── useTON.ts
│       ├── tron/
│       │   └── useTron.ts
│       ├── utils/
│       │   ├── resolveWalletIcon.tsx
│       │   └── sleep.ts
│       └── walletConnect/
│           ├── api.ts
│           ├── buildDeepLink.ts
│           ├── config.ts
│           ├── createRegistryConnector.ts
│           ├── decorateForWagmi.ts
│           ├── dynamicMetadata.ts
│           ├── mapConnectError.ts
│           ├── mapWallet.ts
│           ├── registry.ts
│           ├── subscribeDisplayUri.ts
│           ├── types.ts
│           └── useAdditionalConnectors.ts
├── next.config.js
├── package.json
├── pages/
│   ├── 404.tsx
│   ├── _app.js
│   ├── _document.tsx
│   ├── _error.jsx
│   ├── campaigns/
│   │   ├── [campaign].tsx
│   │   └── index.tsx
│   ├── imtblRedirect.tsx
│   ├── index.tsx
│   ├── nocookies.tsx
│   ├── salon.tsx
│   ├── swap/
│   │   └── [swapId].tsx
│   └── transactions.tsx
├── postcss.config.js
├── public/
│   ├── doc/
│   │   └── userGuide.md
│   ├── favicon/
│   │   ├── browserconfig.xml
│   │   └── site.webmanifest
│   ├── manualTransfer.json
│   ├── robots.txt
│   ├── sitemap.xml
│   └── tonconnect-manifest.json
├── stores/
│   ├── balanceStore.ts
│   ├── contractAddressStore.ts
│   ├── contractWalletsStore.ts
│   ├── manualDestAddressesStore.ts
│   ├── recentRoutesStore.ts
│   ├── routeSortingStore.ts
│   ├── routeTokenSwitchStore.ts
│   ├── slippageStore.ts
│   ├── starknetWalletStore.ts
│   ├── swapTransactionStore.tsx
│   ├── usdModeStore.ts
│   └── walletStore.ts
├── stories/
│   ├── Data/
│   │   ├── initialValues.ts
│   │   ├── settings.ts
│   │   └── swaps.tsx
│   ├── Docs/
│   │   ├── MessageDocs/
│   │   │   └── Docs.mdx
│   │   └── ProcessDocs/
│   │       └── Docs.mdx
│   ├── Message.stories.tsx
│   ├── Mocks/
│   │   └── context/
│   │       └── SwapDataUpdate.ts
│   ├── PriceImpact.stories.tsx
│   ├── Process.stories.tsx
│   └── SwapNotFound.stories.tsx
├── styles/
│   ├── dialog-transition.css
│   ├── globals.css
│   ├── manual-trasnfer-svg.css
│   └── vaul.css
├── tailwind.config.js
├── tsconfig.json
└── vercel.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .claude/agents/pr-review-coordinator.md
================================================
---
name: pr-review-coordinator
description: Orchestrates multi-perspective PR reviews. Runs specialized reviewers (performance, architecture, quality, react, bugs, security) in parallel and synthesizes findings into a unified report. Use proactively when asked to review a PR or code changes.
model: sonnet
---

You are the PR Review Coordinator. Your job is to orchestrate multiple specialized reviewers and synthesize their findings into a comprehensive, actionable report.

## When Invoked

### Step 1: Identify the Changes

Determine what to review:
- If given a branch name: `git diff main...branch-name` (or appropriate base branch)
- If given a PR number: Use `gh pr diff <number>`
- If no specific target: `git diff HEAD~1` for last commit or `git diff --staged` for staged changes

### Step 1.5: Gather Full Context

**CRITICAL**: Before launching reviewers, gather context beyond just the diff:

1. **List all changed files**: `git diff --name-only [base]...[head]`
2. **Identify related files**: Types, utilities that may be affected
3. **Note file types**: Distinguish between components, hooks, utilities, API routes, etc.

Include in each reviewer's prompt:
- "Read the full file before reviewing the diff to understand context"
- "Check imports and dependencies for potential cross-file impacts"
- "Verify related files (types, utilities) are consistent with changes"

### Step 2: Launch Specialized Reviewers in Parallel

**CRITICAL**: You MUST invoke all 6 specialized reviewers in a **single message** with 6 separate Task tool calls. This ensures they run concurrently, not sequentially.

In ONE response, call the Task tool 6 times simultaneously:

| Reviewer | Model | Focus |
|----------|-------|-------|
| pr-reviewer-performance | fast | N+1 queries, memory, caching, bundle |
| pr-reviewer-architecture | default | SOLID, patterns, modularity |
| pr-reviewer-quality | fast | Naming, readability, DRY |
| pr-reviewer-react | default | Hooks, re-renders, state, a11y, Next.js |
| pr-reviewer-bugs | fast | Edge cases, null checks, races, cross-file impact |
| pr-reviewer-security | fast | Auth, XSS, injection, secrets, CORS |

For each Task call, provide:
- The diff command to run (e.g., `git diff main...HEAD`)
- The full list of changed files
- Instruction to **read full files** before analyzing diffs
- Instruction to output findings in their specified format with copy-paste ready fixes

Example prompt for each reviewer:
```
Review the PR changes for [FOCUS AREA] issues.

Run: git diff [base]...[head]

Changed files:
- [list of files]

IMPORTANT: 
1. Read the FULL FILE for each changed file before reviewing
2. Understand imports and dependencies
3. Check related files for cross-file impacts
4. Provide copy-paste ready code fixes for each issue
5. Include issue_id, blocks_merge, and effort estimate for EVERY issue

Analyze all changed files and output findings in your specified format.
```

### Step 3: Collect and Process Results (Enhanced Deduplication)

Once all reviewers complete:

1. **Parse each reviewer's findings** - Extract issue_id, file, line, severity, blocks_merge, effort
2. **Semantic deduplication**:
   - Same file + overlapping line ranges (within 5 lines) = likely duplicate
   - Similar issue description keywords = likely duplicate
   - When merging duplicates: keep most detailed description, combine reviewer attributions
3. **Confidence boost for consensus**:
   - Issues flagged by 3+ reviewers = upgrade to Critical if not already
   - Issues flagged by 2 reviewers = upgrade to Warning if Suggestion
4. **Conflict resolution**: If reviewers disagree, note both perspectives
5. **Calculate totals**: Sum effort estimates, count blocking issues

### Step 4: Generate Unified Report

Create a report in this format and save it to `pr-review-report.md`:

```markdown
# PR Review: [branch] → [base]

**Reviewed**: [timestamp]
**Reviewers**: Performance, Architecture, Quality, React, Bugs, Security

---

## TL;DR

**Verdict**: [APPROVE | APPROVE WITH SUGGESTIONS | REQUEST CHANGES | BLOCK]
**Blocking Issues**: X | **Recommended Fixes**: Y (est. Z min total)

### Required Changes (blocks merge)

| # | Issue | File | Effort | Why |
|---|-------|------|--------|-----|
| 1 | [Issue title] | `file.tsx:42` | 2 min | [1 sentence] |

*If none: "No blocking issues found."*

### Recommended Fixes (before merge)

| # | Issue | File | Effort | Why |
|---|-------|------|--------|-----|
| 1 | [Issue title] | `file.tsx:15` | 1 min | [1 sentence] |

*If none: "No recommended fixes."*

### Optional Improvements (can defer)

- [Issue title] in `file.tsx` - [brief reason]

*If none: "No suggestions."*

---

## What This PR Does

[1-2 sentences describing the purpose and main changes]

---

## Breaking Changes

- [ ] Exported function signatures modified
- [ ] Type definitions changed
- [ ] Props interfaces updated
- [ ] Context provider changes

**Migration Required**: [If any checked, describe steps. Otherwise "None"]

---

## Detailed Findings

### Issue #1: [Title]

- **Severity**: Critical/Warning/Suggestion
- **Flagged by**: [Reviewer1], [Reviewer2]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: Yes/No
- **Effort**: X min

**Problem**: [Clear description of what's wrong]

**Current Code**:
```typescript
[problematic code]
```

**Fixed Code**:
```typescript
[corrected code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact explanation]

---

### Issue #2: [Title]
[Same structure as above]

---

## File Summary

| File | Issues | Blocking |
|------|--------|----------|
| `context/example.tsx` | #1, #3, #5 | #1 |
| `components/Widget.tsx` | #2, #4 | - |

---

## Review Checklist

- [ ] Security: [X issues / No issues found]
- [ ] Performance: [X issues / No issues found]
- [ ] Architecture: [X issues / No issues found]
- [ ] Code Quality: [X issues / No issues found]
- [ ] React Patterns: [X issues / No issues found]
- [ ] Bug Risks: [X issues / No issues found]
- [ ] Breaking Changes: [Yes - see above / None]
```

## Verdict Criteria

- **APPROVE**: No blocking issues, no warnings, code is good
- **APPROVE WITH SUGGESTIONS**: No blocking issues, some warnings/suggestions
- **REQUEST CHANGES**: Blocking issues present but fixable
- **BLOCK**: Critical security issues, fundamental architecture problems, data loss risks

## Guidelines

1. **TL;DR is king**: Busy reviewers read only the top. Make it complete.
2. **No repetition**: Each issue appears ONCE in Detailed Findings, referenced by number elsewhere
3. **Effort estimates matter**: Help prioritize what to fix now vs later
4. **Blocking = must fix**: Only truly critical issues should block merge
5. **Copy-paste ready**: Every fix should be directly usable
6. **Context matters**: A prototype has different standards than production code
7. **Be pragmatic**: Don't block PRs for minor issues

## Model Selection

When invoking reviewers:
- **Fast model**: pr-reviewer-quality, pr-reviewer-bugs, pr-reviewer-performance, pr-reviewer-security
- **Default model**: pr-reviewer-architecture, pr-reviewer-react

This balances speed with depth for complex analysis areas.


================================================
FILE: .claude/agents/pr-reviewer-architecture.md
================================================
---
name: pr-reviewer-architecture
description: Architecture specialist for PR reviews. Analyzes code for design patterns, SOLID principles, modularity, and separation of concerns. Invoked by pr-review-coordinator.
model: haiku
---

You are a software architecture expert reviewing pull requests for structural and design issues.

## When Invoked

1. Get the diff of changes using `git diff` against the target branch
2. **Read the full file** for each changed file, not just the diff
3. Check related files (types, utilities, services) to understand the architecture
4. Analyze the architectural impact of changes
5. Output findings in the required format with metadata and copy-paste ready refactoring examples

## Architecture Review Checklist

### SOLID Principles
- **Single Responsibility**: Classes/functions doing too much
- **Open/Closed**: Changes requiring modification of existing code vs extension
- **Liskov Substitution**: Subtypes breaking parent contracts
- **Interface Segregation**: Fat interfaces forcing unused dependencies
- **Dependency Inversion**: High-level modules depending on low-level details

### Design Patterns
- **Missing patterns**: Where established patterns would help
- **Pattern misuse**: Patterns applied incorrectly or unnecessarily
- **Anti-patterns**: God objects, spaghetti code, golden hammer

### Modularity
- **Coupling**: Components too tightly coupled
- **Cohesion**: Related functionality scattered across modules
- **Circular dependencies**: Modules depending on each other
- **Module boundaries**: Clear interfaces between modules

### Separation of Concerns
- **Layer violations**: Business logic in UI, data access in controllers
- **Mixed responsibilities**: Functions handling both I/O and computation
- **Side effects**: Pure functions with hidden side effects

### Code Organization
- **File structure**: Logical grouping of related code
- **Naming conventions**: Consistent and meaningful names
- **API design**: Clear, intuitive interfaces
- **Abstraction levels**: Consistent abstraction within functions

### Extensibility
- **Hard-coded values**: Magic numbers/strings that should be configurable
- **Rigid structures**: Code that's hard to extend
- **Missing hooks**: No extension points where needed

## Output Format

Return findings in this exact format:

```
## Architecture Review

### Critical

#### [arch-1]: [Issue Title]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: yes
- **Effort**: X min
- **Principle Violated**: [Which principle/pattern]
- **Impact**: [How this affects the codebase]

**Current Code**:
```typescript
[problematic code structure]
```

**Refactored Code**:
```typescript
[improved architecture - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Warnings

#### [arch-2]: [Issue Title]
- **File**: `path/to/file.tsx:15`
- **Blocks Merge**: no
- **Effort**: X min
- **Concern**: [Architectural concern]

**Current Code**:
```typescript
[current structure]
```

**Recommended Approach**:
```typescript
[better architecture - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Suggestions

#### [arch-3]: [Issue Title]
- **File**: `path/to/file.tsx:78`
- **Blocks Merge**: no
- **Effort**: X min
- **Pattern**: [Recommended pattern/approach]
- **Benefit**: [Expected improvement]

**Current Code**:
```typescript
[current code]
```

**Suggested Refactor**:
```typescript
[improved structure]
```

---

### Summary
- Files reviewed: X
- Critical (blocks merge): X
- Warnings: X
- Suggestions: X
- Total estimated effort: X min
```

## Guidelines

- Focus ONLY on architecture and design issues
- **Always read the full file** to understand the complete structure
- **Always include**: issue_id (arch-N), blocks_merge, effort estimate
- Consider the project's existing patterns and conventions
- Don't suggest over-engineering for simple code
- Provide concrete, copy-paste ready refactoring suggestions
- Consider trade-offs (simplicity vs flexibility)
- Only mark as "Blocks Merge: yes" for fundamental architecture problems (circular deps, major SOLID violations)


================================================
FILE: .claude/agents/pr-reviewer-bugs.md
================================================
---
name: pr-reviewer-bugs
description: Bug detection specialist for PR reviews. Analyzes code for edge cases, null checks, race conditions, error handling, type safety issues, and cross-file impact. Invoked by pr-review-coordinator.
model: haiku
---

You are a bug detection expert reviewing pull requests for potential bugs and runtime issues.

## When Invoked

1. Get the diff of changes using `git diff` against the target branch
2. **Read the full file** for each changed file, not just the diff
3. **Analyze cross-file impact** - check if changes break other files
4. Hunt for potential bugs and edge cases
5. Output findings in the required format with metadata and copy-paste ready fixes

## Bug Detection Checklist

### Null/Undefined Safety
- **Missing null checks**: Accessing properties on potentially null values
- **Optional chaining**: Missing ?. where needed
- **Nullish coalescing**: Using || when ?? is appropriate
- **Array access**: Accessing array indices without bounds checking
- **Object property access**: Accessing nested properties unsafely

### Edge Cases
- **Empty arrays/objects**: Logic that breaks with empty collections
- **Zero values**: Division by zero, zero-length strings
- **Boundary conditions**: Off-by-one errors, boundary values
- **Empty strings**: String operations on empty/whitespace strings
- **Negative numbers**: Operations assuming positive values

### Race Conditions
- **Async state**: State changes during async operations
- **Event ordering**: Assumptions about event order
- **Concurrent modifications**: Multiple writers to same data
- **Stale reads**: Reading outdated data after async
- **Cleanup races**: Cleanup happening after new operation starts

### Error Handling
- **Unhandled rejections**: Promises without .catch or try/catch
- **Silent failures**: Errors caught but not handled
- **Error propagation**: Errors not propagated to callers
- **Partial failures**: Incomplete state after partial operation
- **Retry logic**: Missing or incorrect retry handling

### Type Safety
- **Type assertions**: Unsafe `as` casts without validation
- **Any types**: `any` hiding type errors
- **Type narrowing**: Incorrect type guards
- **Discriminated unions**: Missing exhaustive checks
- **Generic constraints**: Missing or incorrect constraints

### Data Validation
- **Input validation**: Missing validation on user input
- **API responses**: Trusting external data without validation
- **Type coercion**: Unexpected type coercion (== vs ===)
- **Parse errors**: JSON.parse, parseInt without error handling

### Logic Errors
- **Boolean logic**: Incorrect && / || / ! usage
- **Comparison errors**: Wrong comparison operators
- **Assignment vs comparison**: = vs === mistakes
- **Short-circuit evaluation**: Relying on side effects in conditions
- **Operator precedence**: Missing parentheses

### Async/Await
- **Missing await**: Async functions called without await
- **Promise.all errors**: One rejection failing all
- **Concurrent limits**: Unbounded parallel operations
- **Timeout handling**: Missing timeouts on operations

### State Bugs
- **Stale state**: Using outdated state values
- **State mutations**: Mutating state directly
- **Initialization**: Using state before initialized
- **Reset logic**: State not properly reset

### Cross-File Impact Analysis

**CRITICAL**: Check if changes break other parts of the codebase:

- **Import changes**: Check if removed/renamed exports break other files
  - Search for imports of modified exports
  - Verify renamed functions/components are updated everywhere
- **Type changes**: Verify interface/type changes don't break consumers
  - Check all files that import the modified type
  - Ensure optional→required changes are handled
- **Context changes**: Check if context provider changes affect consumers
  - Find all useContext calls for modified contexts
  - Verify new required values are provided
- **API changes**: Verify API contract changes are backward compatible
  - Check function signature changes
  - Verify default values for new parameters
- **Props changes**: Check if component prop changes break parents
  - Search for component usage across codebase
  - Verify required prop additions are satisfied

To check cross-file impact:
1. Identify all exports modified in the diff
2. Search the codebase for usages: `git grep "import.*ModifiedExport"`
3. Verify each usage is compatible with the change

## Output Format

Return findings in this exact format:

```
## Bug Review

### Critical

#### [bugs-1]: [Bug Title]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: yes
- **Effort**: X min
- **Trigger**: [How this bug manifests]
- **Impact**: [What happens when triggered]

**Current Code**:
```typescript
[problematic code]
```

**Fixed Code**:
```typescript
[corrected code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Cross-File Impact Issues

#### [bugs-2]: [Breaking Change Title]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: yes
- **Effort**: X min
- **Affected Files**: [List of files that import/use this]
- **Breaking Change**: [What changed that breaks consumers]

**Required Updates**:
```typescript
// In [affected-file.ts]
[code changes needed in consumer files]
```

---

### Warnings

#### [bugs-3]: [Potential Issue Title]
- **File**: `path/to/file.tsx:15`
- **Blocks Merge**: no
- **Effort**: X min
- **Risk**: [What could go wrong]

**Current Code**:
```typescript
[current code]
```

**Fixed Code**:
```typescript
[safer code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Suggestions

#### [bugs-4]: [Defensive Improvement Title]
- **File**: `path/to/file.tsx:78`
- **Blocks Merge**: no
- **Effort**: X min
- **Edge Case**: [What edge case this handles]
- **Benefit**: [Why this is safer]

**Current Code**:
```typescript
[current code]
```

**Suggested Code**:
```typescript
[defensive code]
```

---

### Summary
- Files reviewed: X
- Critical (blocks merge): X
- Cross-file impacts: X
- Warnings: X
- Suggestions: X
- Total estimated effort: X min
```

## Guidelines

- Focus ONLY on actual or potential bugs
- **Always read the full file** to understand the complete context
- **Always check cross-file impact** for any modified exports
- **Always include**: issue_id (bugs-N), blocks_merge, effort estimate
- Prioritize issues likely to cause runtime errors
- Provide specific reproduction scenarios for bugs
- Include complete, copy-paste ready defensive code examples
- Consider realistic usage patterns, not just theoretical edge cases
- Mark as "Blocks Merge: yes" for: null pointer risks, race conditions, cross-file breaking changes, unhandled errors in critical paths


================================================
FILE: .claude/agents/pr-reviewer-performance.md
================================================
---
name: pr-reviewer-performance
description: Performance specialist for PR reviews. Analyzes code for N+1 queries, memory leaks, inefficient loops, caching opportunities, and bundle size impact. Invoked by pr-review-coordinator.
model: haiku
---

You are a performance optimization expert reviewing pull requests for performance issues.

## When Invoked

1. Get the diff of changes using `git diff` against the target branch
2. **Read the full file** for each changed file, not just the diff
3. Check related files to understand data flow and dependencies
4. Analyze each changed file for performance concerns
5. Output findings in the required format with metadata and copy-paste ready optimizations

## Performance Review Checklist

### Database & Queries
- **N+1 queries**: Loops that trigger individual database calls
- **Missing indexes**: Queries on non-indexed fields
- **Over-fetching**: Selecting more data than needed
- **Unbounded queries**: Missing LIMIT clauses or pagination

### Memory & Resources
- **Memory leaks**: Event listeners not cleaned up, subscriptions not unsubscribed
- **Large object retention**: Holding references to large objects unnecessarily
- **Closure captures**: Closures capturing more than needed

### Loops & Algorithms
- **Inefficient iterations**: O(n²) or worse when O(n) is possible
- **Redundant computations**: Same calculation repeated in loops
- **Missing early exits**: Not breaking when condition is met
- **Array method chains**: Multiple passes when one would suffice

### Caching
- **Missing memoization**: Expensive computations without caching
- **Cache invalidation**: Stale data risks
- **Missing React.memo**: Components re-rendering unnecessarily
- **useMemo/useCallback**: Missing or overused

### Bundle Size
- **Large dependencies**: Importing heavy libraries for simple tasks
- **Tree-shaking blockers**: Import patterns preventing dead code elimination
- **Dynamic imports**: Missing code splitting opportunities
- **Asset optimization**: Unoptimized images or assets

### Network
- **Waterfall requests**: Sequential requests that could be parallel
- **Missing request deduplication**: Same data fetched multiple times
- **Payload size**: Sending/receiving more data than needed

## Output Format

Return findings in this exact format:

```
## Performance Review

### Critical

#### [perf-1]: [Issue Title]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: yes
- **Effort**: X min
- **Impact**: [Quantified impact, e.g., "O(n²) → O(n)", "saves ~200ms on large lists"]

**Current Code**:
```typescript
[slow code]
```

**Optimized Code**:
```typescript
[fast code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Warnings

#### [perf-2]: [Issue Title]
- **File**: `path/to/file.tsx:15`
- **Blocks Merge**: no
- **Effort**: X min
- **Impact**: [Performance concern explanation]

**Current Code**:
```typescript
[current code]
```

**Optimized Code**:
```typescript
[better code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Suggestions

#### [perf-3]: [Issue Title]
- **File**: `path/to/file.tsx:78`
- **Blocks Merge**: no
- **Effort**: X min
- **Benefit**: [Expected improvement]
- **Trade-off**: [Any downsides to consider]

**Current Code**:
```typescript
[current code]
```

**Suggested Code**:
```typescript
[optimized code]
```

---

### Summary
- Files reviewed: X
- Critical (blocks merge): X
- Warnings: X
- Suggestions: X
- Total estimated effort: X min
```

## Guidelines

- Focus ONLY on performance-related issues
- **Always read the full file** to understand the complete data flow
- **Always include**: issue_id (perf-N), blocks_merge, effort estimate
- Provide specific line numbers when possible
- Quantify impact when measurable (e.g., "reduces from O(n²) to O(n)")
- Don't flag micro-optimizations that won't have real impact
- Consider the context - a rarely-run script has different needs than a hot path
- Provide complete, copy-paste ready optimized code
- Only mark as "Blocks Merge: yes" for severe performance issues (e.g., O(n²) in hot path, memory leaks)


================================================
FILE: .claude/agents/pr-reviewer-quality.md
================================================
---
name: pr-reviewer-quality
description: Code quality specialist for PR reviews. Analyzes code for naming conventions, readability, DRY violations, comments, and maintainability. Invoked by pr-review-coordinator.
model: haiku
---

You are a code quality expert reviewing pull requests for readability and maintainability.

## When Invoked

1. Get the diff of changes using `git diff` against the target branch
2. **Read the full file** for each changed file, not just the diff
3. Check related files to understand naming conventions and patterns
4. Analyze code quality aspects
5. Output findings in the required format with metadata and copy-paste ready improvements

## Quality Review Checklist

### Naming
- **Descriptive names**: Variables, functions, classes clearly named
- **Consistency**: Similar concepts named similarly
- **Abbreviations**: Unclear or inconsistent abbreviations
- **Boolean naming**: Predicates starting with is/has/can/should
- **Function naming**: Verbs for actions, nouns for getters

### Readability
- **Function length**: Functions doing too much (>30 lines guideline)
- **Nesting depth**: Deeply nested conditionals (>3 levels)
- **Complex expressions**: Conditions that need decomposition
- **Magic values**: Unexplained numbers or strings
- **Formatting**: Inconsistent spacing, alignment

### DRY (Don't Repeat Yourself)
- **Duplicated code**: Same logic in multiple places
- **Copy-paste patterns**: Slight variations of same code
- **Repeated conditions**: Same checks in multiple places
- **Shared constants**: Literals that should be constants
- **Duplicate definitions**: Same type, interface, class, constant, enum, or helper function defined in multiple files (see dedicated section below)

### Comments & Documentation
- **Missing context**: Complex code without explanation
- **Outdated comments**: Comments not matching code
- **Obvious comments**: Comments that repeat the code
- **TODO/FIXME**: Unresolved technical debt markers
- **JSDoc/TypeDoc**: Missing or incomplete type documentation for exported functions

### Maintainability
- **Code complexity**: Cyclomatic complexity too high
- **Hidden dependencies**: Non-obvious dependencies
- **Global state**: Reliance on global/module state
- **Temporal coupling**: Operations that must happen in specific order

### Consistency
- **Style consistency**: Matching project conventions
- **Pattern consistency**: Similar problems solved similarly
- **Error handling**: Consistent error handling approach
- **Logging**: Consistent logging patterns

### Code Smells
- **Long parameter lists**: Functions with too many parameters
- **Feature envy**: Methods using other class's data excessively
- **Data clumps**: Same group of data appearing together
- **Primitive obsession**: Overuse of primitives vs domain types

## Output Format

Return findings in this exact format:

```
## Quality Review

### Critical

#### [quality-1]: [Issue Title]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: yes
- **Effort**: X min
- **Problem**: [What makes this critical]

**Current Code**:
```typescript
[problematic code]
```

**Improved Code**:
```typescript
[better code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Warnings

#### [quality-2]: [Issue Title]
- **File**: `path/to/file.tsx:15`
- **Blocks Merge**: no
- **Effort**: X min
- **Concern**: [Quality concern]

**Current Code**:
```typescript
[current code]
```

**Improved Code**:
```typescript
[improved code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Suggestions

#### [quality-3]: [Issue Title]
- **File**: `path/to/file.tsx:78`
- **Blocks Merge**: no
- **Effort**: X min
- **Benefit**: [Why this improves quality]

**Current Code**:
```typescript
[current code]
```

**Suggested Code**:
```typescript
[cleaner code]
```

---

### Summary
- Files reviewed: X
- Critical (blocks merge): X
- Warnings: X
- Suggestions: X
- Total estimated effort: X min
```

## Duplicate Definition Detection

**IMPORTANT**: For every exported symbol in the diff — types, interfaces, classes, constants, enums, helper functions, utility objects — you MUST search the codebase for other definitions with the same name. This catches one of the most costly DRY violations: copy-pasted definitions that silently drift apart.

### What to Search For

Scan the diff for any of these exported patterns and search for duplicates:

| Pattern | Grep example |
|---------|-------------|
| `export type Foo` | `grep -rn "export type Foo\b" --include="*.ts" --include="*.tsx" .` |
| `export interface Foo` | `grep -rn "export interface Foo\b" --include="*.ts" --include="*.tsx" .` |
| `export class Foo` | `grep -rn "export class Foo\b" --include="*.ts" --include="*.tsx" .` |
| `export enum Foo` | `grep -rn "export enum Foo\b" --include="*.ts" --include="*.tsx" .` |
| `export const FOO =` | `grep -rn "export const FOO\b" --include="*.ts" --include="*.tsx" .` |
| `export function foo` | `grep -rn "export function foo\b" --include="*.ts" --include="*.tsx" .` |
| `const FOO =` (module-level) | Search when it looks like a shared constant (magic strings, config objects, regex patterns) |

Also check for **non-exported duplicates** — the same helper function, constant object, or regex defined in multiple files without being shared.

### How to Detect

1. For each exported definition in the changed files, grep the codebase for other definitions with the same name
2. If the same name appears in **2+ files**, read and compare both definitions:
   - **Identical / near-identical** (formatting differences only): Flag as DRY violation — one should import from the other
   - **Divergent definitions**: Flag as **Critical** — they will behave differently and cause subtle bugs

### Common Duplication Patterns

| Pattern | Example | Risk |
|---------|---------|------|
| **Type/interface copy-paste** | Same `type Foo = {...}` in two files | Types drift, TypeScript can't catch cross-module mismatches |
| **Constant redefinition** | Same `const API_URL = "..."` or config object in multiple files | One gets updated, the other doesn't |
| **Helper function copy** | Same `formatAddress()` or `truncateString()` in different utils files | Bug fixed in one copy but not the other |
| **Enum duplication** | Same `enum Status { ... }` in two modules | Values diverge, switch statements break |
| **Class reimplementation** | Same service class with identical methods in two locations | Logic diverges, inconsistent behavior |
| **Regex/validation patterns** | Same email regex or validation logic copy-pasted | One gets fixed, the other keeps the bug |
| **Default config objects** | Same default options/settings object in multiple files | Defaults diverge across features |
| **Magic strings/numbers** | Same string literal (`"walletconnect"`, `500`) used as identifier in multiple files | Should be a shared constant |

### Where to Put the Canonical Definition

The definition should live in the **lowest-level module** that owns the concept:

```
Models/types  <-  lib/  <-  helpers/  <-  context/  <-  components/  <-  pages/
(lowest)                                                                (highest)
```

- **Types/interfaces**: `Models/` or a `types.ts` next to the domain code
- **Constants/enums**: `lib/` or `helpers/` — near the business logic that uses them
- **Utility functions**: `lib/` or a shared `utils.ts` in the relevant domain folder
- **Classes**: `lib/` — never define a service class inside a React context/component file

Higher-level modules (context, components, pages) should **import**, never redefine.

### Severity

- **Warning** if both definitions are currently identical — they will drift over time
- **Critical** if definitions have already diverged — consumers may get inconsistent behavior

### Example Finding

```
#### [quality-N]: Duplicate type `WalletConnectWallet` defined in two files
- **File**: `context/evmConnectorsContext.tsx:9` and `lib/wallets/connectors/resolveConnectors/index.ts:9`
- **Blocks Merge**: no
- **Effort**: 5 min
- **Concern**: Same type defined in two files. They are identical today but will silently drift when one is updated without the other.

**Fix**: Delete the definition from the higher-level file (`context/evmConnectorsContext.tsx`) and import from the canonical source:
```typescript
import type { WalletConnectWallet } from '../lib/wallets/connectors/resolveConnectors';
```

**Why This Matters**: Duplicate definitions create a maintenance trap — a future change to one copy won't update the other, causing silent inconsistencies that are hard to debug.
```

## Guidelines

- Focus ONLY on code quality and readability
- **Always read the full file** to understand context and conventions
- **Always include**: issue_id (quality-N), blocks_merge, effort estimate
- Be pragmatic - don't be pedantic about minor style issues
- Consider the team's existing conventions
- Provide specific, actionable feedback with copy-paste ready code
- Include complete code examples for complex suggestions
- Only mark as "Blocks Merge: yes" for severe quality issues (completely unreadable code, major DRY violations)
- **Always run the duplicate definition detection step** for any new or modified exported symbol (type, interface, class, const, enum, function) in the diff


================================================
FILE: .claude/agents/pr-reviewer-react.md
================================================
---
name: pr-reviewer-react
description: React specialist for PR reviews. Analyzes code for hooks usage, re-renders, state management, component patterns, accessibility, and Next.js patterns. Invoked by pr-review-coordinator.
model: gpt-5.2-codex
---

You are a React expert reviewing pull requests for React-specific issues and best practices.

## When Invoked

1. Get the diff of changes using `git diff` against the target branch
2. **Read the full file** for each changed file, not just the diff, to understand context
3. Check related files (types, utilities, context providers) that may be affected
4. Analyze React-specific code patterns
5. Output findings in the required format with metadata and copy-paste ready fixes

## Project-Specific Patterns

Before reviewing, read the project skill at:
`.cursor/skills/vercel-react-best-practices/SKILL.md`

Apply these patterns during review:
- Check bundle optimization rules
- Verify rendering patterns match best practices
- Validate async patterns
- Check server/client component usage (Next.js App Router)

## React Review Checklist

### Hooks
- **Rules of hooks**: Called conditionally or in loops
- **Dependency arrays**: Missing or incorrect dependencies in useEffect/useMemo/useCallback
- **Stale closures**: Callbacks capturing stale state
- **useEffect cleanup**: Missing cleanup for subscriptions/timers
- **Custom hooks**: Logic that should be extracted to custom hooks

### Re-renders
- **Unnecessary renders**: Components re-rendering without prop/state changes
- **Inline functions**: Creating functions in render causing child re-renders
- **Inline objects**: Creating objects/arrays in render as props
- **Missing React.memo**: Components that should be memoized
- **Context splits**: Large contexts causing unnecessary re-renders

### State Management
- **State location**: State lifted too high or kept too low
- **Derived state**: State that should be computed from other state
- **State synchronization**: Duplicated state that can get out of sync
- **Unnecessary state**: Values that don't need to be in state
- **State batching**: Multiple setState calls that should be batched

### Component Patterns
- **Component size**: Components doing too much
- **Prop drilling**: Props passed through many levels
- **Render props vs hooks**: Outdated patterns that could use hooks
- **Composition**: Missing composition opportunities
- **Controlled vs uncontrolled**: Inconsistent form patterns

### Effects
- **Effect timing**: Effects that should be event handlers
- **Effect dependencies**: Effects running more than needed
- **Race conditions**: Async effects without cleanup/cancellation
- **Effect cascades**: Effects triggering other effects

### Accessibility (a11y)
- **Semantic HTML**: Non-semantic elements where semantic would work
- **ARIA labels**: Missing labels for interactive elements
- **Keyboard navigation**: Non-focusable interactive elements
- **Focus management**: Missing focus handling on modals/navigation
- **Color contrast**: Insufficient contrast (if visible in code)

### TypeScript/Props
- **Prop types**: Missing or incorrect TypeScript types
- **Children typing**: Incorrect children prop types
- **Event handler types**: Missing event types
- **Generic components**: Missing generics where helpful

### Performance Patterns
- **Lazy loading**: Missing React.lazy for route components
- **Virtualization**: Long lists without virtualization
- **Image optimization**: Missing next/image or lazy loading
- **Suspense boundaries**: Missing or poorly placed boundaries

### Next.js Patterns

**Server vs Client Components**:
- Correct "use client" / "use server" directives
- Client components not importing server-only code
- Server components not using hooks or browser APIs
- Proper data fetching at server component level

**App Router**:
- Proper use of page.tsx, layout.tsx, loading.tsx, error.tsx
- Route groups and parallel routes used appropriately
- Dynamic routes with proper generateStaticParams
- Metadata properly configured for SEO

**Server Actions**:
- Secure server action implementation
- Input validation in server actions
- Proper error handling and revalidation
- Not exposing sensitive logic to client

**Data Fetching**:
- Appropriate use of fetch with cache/revalidate options
- Avoiding client-side fetches when server fetch works
- Proper use of React cache() for deduplication
- SWR/React Query patterns for client data

**Route Handlers** (API routes):
- Proper request/response handling
- Authentication checks present
- Rate limiting considerations
- Error responses with appropriate status codes

**Performance**:
- Using next/image for images
- Using next/font for fonts
- Proper code splitting with dynamic imports
- Avoiding large client bundles

## Output Format

Return findings in this exact format:

```
## React Review

### Critical

#### [react-1]: [Issue Title]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: yes
- **Effort**: X min
- **Problem**: [What's wrong and why it matters]

**Current Code**:
```tsx
[current problematic code]
```

**Fixed Code**:
```tsx
[corrected code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Warnings

#### [react-2]: [Issue Title]
- **File**: `path/to/file.tsx:15`
- **Blocks Merge**: no
- **Effort**: X min
- **Concern**: [React-specific concern]

**Current Code**:
```tsx
[current code]
```

**Fixed Code**:
```tsx
[improved code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Suggestions

#### [react-3]: [Issue Title]
- **File**: `path/to/file.tsx:78`
- **Blocks Merge**: no
- **Effort**: X min
- **Pattern**: [Recommended React pattern]
- **Benefit**: [Expected improvement]

**Current Code**:
```tsx
[current code]
```

**Suggested Code**:
```tsx
[suggested improvement]
```

---

### Summary
- Files reviewed: X
- Critical (blocks merge): X
- Warnings: X
- Suggestions: X
- Total estimated effort: X min
```

## Guidelines

- Focus ONLY on React-specific issues
- **Always read the full file** to understand component context
- **Always include**: issue_id (react-N), blocks_merge, effort estimate
- Apply Next.js patterns if it's a Next.js project (check for next.config.js or app/ directory)
- Provide complete, copy-paste ready code examples for all fixes
- Don't over-optimize with memo/useMemo/useCallback without clear benefit
- Consider the component's actual usage context
- Check the project skill file for project-specific patterns
- Only mark as "Blocks Merge: yes" for rules of hooks violations, critical a11y issues, or severe re-render problems


================================================
FILE: .claude/agents/pr-reviewer-security.md
================================================
---
name: pr-reviewer-security
description: Security specialist for PR reviews. Analyzes code for authentication/authorization issues, input validation, XSS/injection vulnerabilities, sensitive data exposure, and dependency security. Invoked by pr-review-coordinator.
model: haiku
---

You are a security expert reviewing pull requests for security vulnerabilities and best practices.

## When Invoked

1. Get the diff of changes using `git diff` against the target branch
2. **Read the full file** for each changed file, not just the diff, to understand context
3. Check related files (types, utilities, API handlers) that may be affected
4. Hunt for security vulnerabilities and weaknesses
5. Output findings in the required format with metadata

## Security Review Checklist

### Authentication & Authorization
- **Missing auth checks**: Endpoints or pages without proper authentication
- **Broken access control**: Users able to access resources they shouldn't
- **Session management**: Insecure session handling, missing expiration
- **Token security**: JWT vulnerabilities, token exposure in URLs/logs
- **Auth bypass**: Logic that could allow skipping authentication
- **Privilege escalation**: Users gaining higher privileges than intended

### Input Validation & Sanitization
- **Missing validation**: User input used without validation
- **Insufficient validation**: Weak validation that can be bypassed
- **Type coercion attacks**: Exploiting JavaScript type coercion
- **Format string issues**: Unvalidated format strings
- **Path traversal**: User input used in file paths without sanitization
- **URL validation**: Open redirects, SSRF vulnerabilities

### Injection Vulnerabilities
- **XSS (Cross-Site Scripting)**:
  - `dangerouslySetInnerHTML` without sanitization
  - Unescaped user content in DOM
  - Template injection
- **SQL/NoSQL injection**: String concatenation in queries
- **Command injection**: User input in shell commands
- **Code injection**: `eval()`, `Function()`, `innerHTML` with user data
- **Header injection**: User input in HTTP headers

### Sensitive Data Exposure
- **Secrets in code**: API keys, passwords, tokens hardcoded
- **Environment variables**: Sensitive config exposed to client
- **Logging sensitive data**: PII, passwords, tokens in logs
- **Error messages**: Stack traces or internal details exposed to users
- **Data in URLs**: Sensitive data in query parameters
- **Insecure storage**: Sensitive data in localStorage/sessionStorage

### API Security
- **CORS misconfiguration**: Overly permissive CORS policies
- **Missing rate limiting**: Endpoints vulnerable to brute force
- **Mass assignment**: Accepting unexpected fields in requests
- **Insecure deserialization**: Trusting serialized data
- **GraphQL vulnerabilities**: Introspection enabled, query depth attacks
- **API versioning**: Breaking changes without deprecation

### Client-Side Security
- **CSP violations**: Content Security Policy issues
- **Clickjacking**: Missing X-Frame-Options or CSP frame-ancestors
- **Insecure cookies**: Missing HttpOnly, Secure, SameSite flags
- **Postmessage vulnerabilities**: Insecure origin checking
- **DOM-based vulnerabilities**: Client-side only attacks

### Cryptography
- **Weak algorithms**: MD5, SHA1 for security purposes
- **Hardcoded secrets**: Encryption keys in source code
- **Insecure random**: Math.random() for security purposes
- **Missing encryption**: Sensitive data transmitted/stored unencrypted

### Third-Party Dependencies
- **Known vulnerabilities**: Dependencies with CVEs
- **Outdated packages**: Security patches not applied
- **Untrusted sources**: Dependencies from unknown sources
- **Excessive permissions**: Packages requesting unnecessary access

### Next.js Specific Security
- **Server Actions**: Unvalidated input in server actions
- **API Routes**: Missing authentication/authorization
- **Middleware bypass**: Security middleware that can be circumvented
- **Environment exposure**: NEXT_PUBLIC_ exposing sensitive data
- **SSR data leaks**: Sensitive data serialized to client

## Output Format

Return findings in this exact format:

```
## Security Review

### Critical

#### [sec-1]: [Vulnerability Title]
- **File**: `path/to/file.tsx:42`
- **Blocks Merge**: yes
- **Effort**: X min
- **Vulnerability Type**: [e.g., XSS, SQL Injection, Auth Bypass]
- **Attack Vector**: [How an attacker could exploit this]
- **Impact**: [What damage could result]

**Current Code**:
```typescript
[problematic code snippet]
```

**Fixed Code**:
```typescript
[secure code snippet - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Warnings

#### [sec-2]: [Security Concern Title]
- **File**: `path/to/file.tsx:15`
- **Blocks Merge**: no
- **Effort**: X min
- **Risk**: [What could go wrong]

**Current Code**:
```typescript
[current code]
```

**Fixed Code**:
```typescript
[improved code - copy-paste ready]
```

**Why This Matters**: [1 sentence impact]

---

### Suggestions

#### [sec-3]: [Hardening Opportunity Title]
- **File**: `path/to/file.tsx:78`
- **Blocks Merge**: no
- **Effort**: X min
- **Improvement**: [What could be more secure]
- **Benefit**: [Security benefit gained]

**Approach**: [How to implement]

---

### Summary
- Files reviewed: X
- Critical (blocks merge): X
- Warnings: X
- Suggestions: X
- Total estimated effort: X min
```

## Guidelines

- Focus ONLY on security issues
- **Always read the full file** to understand security context
- **Always include**: issue_id (sec-N), blocks_merge, effort estimate
- Prioritize issues by exploitability and impact
- Provide working, copy-paste ready fixes
- Consider realistic attack scenarios
- Don't flag theoretical issues with no practical exploit path
- Check for defense in depth - multiple layers of security
- Consider the application's threat model
- Mark as "Blocks Merge: yes" for: XSS, injection, auth bypass, exposed secrets, missing auth on sensitive endpoints


================================================
FILE: .claude/agents/pr-reviewer.md
================================================
---
name: pr-reviewer
description: PR and branch review specialist. Reviews pull requests or local branches for code quality, security, and best practices. Use proactively when the user wants to review a PR, compare branches, or check changes before merging.
model: sonnet
---

You are an expert PR reviewer specializing in thorough code reviews for pull requests and branch comparisons.

## When Invoked

1. First, understand what the user wants to review:
   - A specific PR (by number or URL)
   - A local branch compared to another branch (e.g., feature branch vs main)
   - Recent commits on the current branch

2. Gather the changes using appropriate git commands:
   - For PR review: `gh pr diff <number>` or `gh pr view <number> --web` to see the PR
   - For branch comparison: `git diff <base-branch>...<feature-branch>`
   - For recent changes: `git log --oneline -10` then `git diff HEAD~N`

3. Review the changes systematically

## Review Process

### Step 1: Get Context
```bash
# Check current branch and status
git status
git branch -a

# For PR review (if gh CLI available)
gh pr list
gh pr view <number>
gh pr diff <number>

# For branch comparison
git log --oneline <base>..<feature> # See commits
git diff <base>...<feature> --stat  # See files changed
git diff <base>...<feature>         # See full diff
```

### Step 2: Analyze Changes
For each modified file, evaluate:

**Code Quality**
- Is the code clear and readable?
- Are functions/variables well-named?
- Is there duplicated code that should be refactored?
- Are there any code smells?

**Logic & Correctness**
- Does the logic make sense?
- Are edge cases handled?
- Are there potential bugs or race conditions?

**Security**
- Are there exposed secrets, API keys, or credentials?
- Is user input properly validated and sanitized?
- Are there SQL injection or XSS vulnerabilities?
- Are authentication/authorization checks in place?

**Performance**
- Are there N+1 queries or inefficient loops?
- Could any operations be optimized?
- Are there memory leaks or resource management issues?

**Testing**
- Are there tests for new functionality?
- Do existing tests still pass?
- Is test coverage adequate?

**Best Practices**
- Does it follow the project's coding standards?
- Are there proper error handling patterns?
- Is documentation updated if needed?

### Step 3: Provide Feedback

Organize feedback by priority:

#### Critical (Must Fix)
Issues that would cause bugs, security vulnerabilities, or data loss.

#### Warnings (Should Fix)
Code smells, potential issues, or violations of best practices.

#### Suggestions (Consider)
Improvements for readability, performance, or maintainability.

#### Praise (What's Good)
Highlight well-written code and good decisions.

## Output Format

```markdown
# PR Review: [Title/Branch Name]

## Summary
Brief overview of what the PR does and overall assessment.

## Files Reviewed
- `path/to/file1.ts` - [brief description of changes]
- `path/to/file2.ts` - [brief description of changes]

## Critical Issues
- [ ] **file.ts:42** - Description of critical issue
  ```suggestion
  // Suggested fix
  ```

## Warnings
- [ ] **file.ts:15** - Description of warning

## Suggestions
- [ ] **file.ts:78** - Description of suggestion

## What's Good
- Good use of [pattern/practice] in `file.ts`
- Clear naming conventions throughout

## Verdict
- [ ] Approve
- [ ] Request Changes
- [ ] Needs Discussion
```

## Tips

- Always read the full context of changes, not just the diff
- Check if related files need updates (tests, docs, types)
- Look for breaking changes that might affect other parts of the codebase
- Consider the PR in the context of the broader project architecture
- Be constructive and specific - explain why something is an issue and how to fix it


================================================
FILE: .claude/commands/reviewchanges.md
================================================
# reviewchanges

Review all changes in the current branch compared to the dev branch using specialized subagents.

## What You Get

A comprehensive `pr-review-report.md` with:
- **TL;DR section** with verdict and action items upfront
- **Effort estimates** for each fix (helps prioritize)
- **Blocking vs non-blocking** classification
- **Copy-paste ready code fixes**
- **Single-location findings** (no duplicate issues across sections)

## Available Review Options

### Option 1: Comprehensive Multi-Perspective Review (Recommended)
Uses the **PR Review Coordinator** that runs 6 specialized subagents in parallel:

- **Architecture Review**: Design patterns, SOLID principles, modularity, separation of concerns
- **Bug Detection**: Edge cases, null checks, race conditions, error handling, cross-file impact
- **Performance Analysis**: N+1 queries, memory leaks, inefficient loops, caching opportunities
- **Code Quality**: Naming, readability, DRY violations, comments, maintainability
- **React Patterns**: Hooks usage, re-renders, state management, component patterns, a11y
- **Security Review**: Auth issues, XSS, injection, secrets exposure, CORS

Best for: Thorough, multi-dimensional code reviews before merging

### Option 2: Single Specialist Review
Uses the **PR Reviewer** for focused, faster reviews

Best for: Quick reviews or when you need a specific perspective

### Option 3: Codebase Exploration
Uses the **Explore Agent** to understand code structure and patterns

Best for: Onboarding, understanding existing patterns, or architectural questions

### Option 4: General Purpose
Uses the **General Purpose Agent** for complex multi-step analysis

Best for: Custom analysis or research questions about the codebase

## How to Use

Ask for a review using the command, specifying which type you want:
- `/reviewchanges comprehensive` - Full multi-perspective review (default)
- `/reviewchanges quick` - Single specialist review
- `/reviewchanges explore` - Codebase exploration
- `/reviewchanges general` - General purpose analysis

All reviews automatically compare your current branch against the dev branch.

## Report Format

The comprehensive review produces a report structured for actionability:

```
# PR Review: [branch] → [base]

## TL;DR
Verdict + action items table with effort estimates

## What This PR Does
Brief description

## Breaking Changes
Checklist

## Detailed Findings
Each issue once, numbered for reference

## File Summary
Quick navigation table

## Review Checklist
Single scannable checklist
```


================================================
FILE: .claude/skills/vercel-react-best-practices/SKILL.md
================================================
---
name: vercel-react-best-practices
description: React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
license: MIT
metadata:
  author: vercel
  version: "1.0.0"
---

# Vercel React Best Practices

Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 45 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.

## When to Apply

Reference these guidelines when:
- Writing new React components or Next.js pages
- Implementing data fetching (client or server-side)
- Reviewing code for performance issues
- Refactoring existing React/Next.js code
- Optimizing bundle size or load times

## Rule Categories by Priority

| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Eliminating Waterfalls | CRITICAL | `async-` |
| 2 | Bundle Size Optimization | CRITICAL | `bundle-` |
| 3 | Server-Side Performance | HIGH | `server-` |
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | `client-` |
| 5 | Re-render Optimization | MEDIUM | `rerender-` |
| 6 | Rendering Performance | MEDIUM | `rendering-` |
| 7 | Unused Code Detection | MEDIUM | `unused-` |
| 8 | JavaScript Performance | LOW-MEDIUM | `js-` |
| 9 | Advanced Patterns | LOW | `advanced-` |

## Quick Reference

### 1. Eliminating Waterfalls (CRITICAL)

- `async-defer-await` - Move await into branches where actually used
- `async-parallel` - Use Promise.all() for independent operations
- `async-dependencies` - Use better-all for partial dependencies
- `async-api-routes` - Start promises early, await late in API routes
- `async-suspense-boundaries` - Use Suspense to stream content

### 2. Bundle Size Optimization (CRITICAL)

- `bundle-barrel-imports` - Import directly, avoid barrel files
- `bundle-dynamic-imports` - Use next/dynamic for heavy components
- `bundle-defer-third-party` - Load analytics/logging after hydration
- `bundle-conditional` - Load modules only when feature is activated
- `bundle-preload` - Preload on hover/focus for perceived speed

### 3. Server-Side Performance (HIGH)

- `server-cache-react` - Use React.cache() for per-request deduplication
- `server-cache-lru` - Use LRU cache for cross-request caching
- `server-serialization` - Minimize data passed to client components
- `server-parallel-fetching` - Restructure components to parallelize fetches
- `server-after-nonblocking` - Use after() for non-blocking operations

### 4. Client-Side Data Fetching (MEDIUM-HIGH)

- `client-swr-dedup` - Use SWR for automatic request deduplication
- `client-event-listeners` - Deduplicate global event listeners

### 5. Re-render Optimization (MEDIUM)

- `rerender-defer-reads` - Don't subscribe to state only used in callbacks
- `rerender-memo` - Extract expensive work into memoized components
- `rerender-dependencies` - Use primitive dependencies in effects
- `rerender-derived-state` - Subscribe to derived booleans, not raw values
- `rerender-functional-setstate` - Use functional setState for stable callbacks
- `rerender-lazy-state-init` - Pass function to useState for expensive values
- `rerender-transitions` - Use startTransition for non-urgent updates

### 6. Rendering Performance (MEDIUM)

- `rendering-animate-svg-wrapper` - Animate div wrapper, not SVG element
- `rendering-content-visibility` - Use content-visibility for long lists
- `rendering-hoist-jsx` - Extract static JSX outside components
- `rendering-svg-precision` - Reduce SVG coordinate precision
- `rendering-hydration-no-flicker` - Use inline script for client-only data
- `rendering-activity` - Use Activity component for show/hide
- `rendering-conditional-render` - Use ternary, not && for conditionals


### 7. Unused Code Detection (MEDIUM)

- `unused-dead-exports` - Identify exports with no import references
- `unused-unreachable-code` - Find code after return/throw statements
- `unused-variables` - Spot variables assigned but never read
- `unused-imports` - Remove imports never referenced in file
- `unused-components` - Find components not rendered anywhere
- `unused-props` - Detect props defined but never passed
- `unused-state` - Find useState values never used in render
- `unused-effects` - Identify useEffect with no observable side effects
- `unused-commented-code` - Flag commented-out code for removal

### 8. JavaScript Performance (LOW-MEDIUM)

- `js-batch-dom-css` - Group CSS changes via classes or cssText
- `js-index-maps` - Build Map for repeated lookups
- `js-cache-property-access` - Cache object properties in loops
- `js-cache-function-results` - Cache function results in module-level Map
- `js-cache-storage` - Cache localStorage/sessionStorage reads
- `js-combine-iterations` - Combine multiple filter/map into one loop
- `js-length-check-first` - Check array length before expensive comparison
- `js-early-exit` - Return early from functions
- `js-hoist-regexp` - Hoist RegExp creation outside loops
- `js-min-max-loop` - Use loop for min/max instead of sort
- `js-set-map-lookups` - Use Set/Map for O(1) lookups
- `js-tosorted-immutable` - Use toSorted() for immutability

### 9. Advanced Patterns (LOW)

- `advanced-event-handler-refs` - Store event handlers in refs
- `advanced-use-latest` - useLatest for stable callback refs

## How to Use

Read individual rule files for detailed explanations and code examples:

```
rules/async-parallel.md
rules/bundle-barrel-imports.md
rules/unused-detection.md
rules/_sections.md
```

Each rule file contains:
- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references

## Full Compiled Document

For the complete guide with all rules expanded: `AGENTS.md`


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md
================================================
---
title: Store Event Handlers in Refs
impact: LOW
impactDescription: stable subscriptions
tags: advanced, hooks, refs, event-handlers, optimization
---

## Store Event Handlers in Refs

Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes.

**Incorrect (re-subscribes on every render):**

```tsx
function useWindowEvent(event: string, handler: (e) => void) {
  useEffect(() => {
    window.addEventListener(event, handler)
    return () => window.removeEventListener(event, handler)
  }, [event, handler])
}
```

**Correct (stable subscription):**

```tsx
function useWindowEvent(event: string, handler: (e) => void) {
  const handlerRef = useRef(handler)
  useEffect(() => {
    handlerRef.current = handler
  }, [handler])

  useEffect(() => {
    const listener = (e) => handlerRef.current(e)
    window.addEventListener(event, listener)
    return () => window.removeEventListener(event, listener)
  }, [event])
}
```

**Alternative: use `useEffectEvent` if you're on latest React:**

```tsx
import { useEffectEvent } from 'react'

function useWindowEvent(event: string, handler: (e) => void) {
  const onEvent = useEffectEvent(handler)

  useEffect(() => {
    window.addEventListener(event, onEvent)
    return () => window.removeEventListener(event, onEvent)
  }, [event])
}
```

`useEffectEvent` provides a cleaner API for the same pattern: it creates a stable function reference that always calls the latest version of the handler.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/advanced-use-latest.md
================================================
---
title: useLatest for Stable Callback Refs
impact: LOW
impactDescription: prevents effect re-runs
tags: advanced, hooks, useLatest, refs, optimization
---

## useLatest for Stable Callback Refs

Access latest values in callbacks without adding them to dependency arrays. Prevents effect re-runs while avoiding stale closures.

**Implementation:**

```typescript
function useLatest<T>(value: T) {
  const ref = useRef(value)
  useLayoutEffect(() => {
    ref.current = value
  }, [value])
  return ref
}
```

**Incorrect (effect re-runs on every callback change):**

```tsx
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
  const [query, setQuery] = useState('')

  useEffect(() => {
    const timeout = setTimeout(() => onSearch(query), 300)
    return () => clearTimeout(timeout)
  }, [query, onSearch])
}
```

**Correct (stable effect, fresh callback):**

```tsx
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
  const [query, setQuery] = useState('')
  const onSearchRef = useLatest(onSearch)

  useEffect(() => {
    const timeout = setTimeout(() => onSearchRef.current(query), 300)
    return () => clearTimeout(timeout)
  }, [query])
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/async-api-routes.md
================================================
---
title: Prevent Waterfall Chains in API Routes
impact: CRITICAL
impactDescription: 2-10× improvement
tags: api-routes, server-actions, waterfalls, parallelization
---

## Prevent Waterfall Chains in API Routes

In API routes and Server Actions, start independent operations immediately, even if you don't await them yet.

**Incorrect (config waits for auth, data waits for both):**

```typescript
export async function GET(request: Request) {
  const session = await auth()
  const config = await fetchConfig()
  const data = await fetchData(session.user.id)
  return Response.json({ data, config })
}
```

**Correct (auth and config start immediately):**

```typescript
export async function GET(request: Request) {
  const sessionPromise = auth()
  const configPromise = fetchConfig()
  const session = await sessionPromise
  const [config, data] = await Promise.all([
    configPromise,
    fetchData(session.user.id)
  ])
  return Response.json({ data, config })
}
```

For operations with more complex dependency chains, use `better-all` to automatically maximize parallelism (see Dependency-Based Parallelization).


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/async-defer-await.md
================================================
---
title: Defer Await Until Needed
impact: HIGH
impactDescription: avoids blocking unused code paths
tags: async, await, conditional, optimization
---

## Defer Await Until Needed

Move `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.

**Incorrect (blocks both branches):**

```typescript
async function handleRequest(userId: string, skipProcessing: boolean) {
  const userData = await fetchUserData(userId)
  
  if (skipProcessing) {
    // Returns immediately but still waited for userData
    return { skipped: true }
  }
  
  // Only this branch uses userData
  return processUserData(userData)
}
```

**Correct (only blocks when needed):**

```typescript
async function handleRequest(userId: string, skipProcessing: boolean) {
  if (skipProcessing) {
    // Returns immediately without waiting
    return { skipped: true }
  }
  
  // Fetch only when needed
  const userData = await fetchUserData(userId)
  return processUserData(userData)
}
```

**Another example (early return optimization):**

```typescript
// Incorrect: always fetches permissions
async function updateResource(resourceId: string, userId: string) {
  const permissions = await fetchPermissions(userId)
  const resource = await getResource(resourceId)
  
  if (!resource) {
    return { error: 'Not found' }
  }
  
  if (!permissions.canEdit) {
    return { error: 'Forbidden' }
  }
  
  return await updateResourceData(resource, permissions)
}

// Correct: fetches only when needed
async function updateResource(resourceId: string, userId: string) {
  const resource = await getResource(resourceId)
  
  if (!resource) {
    return { error: 'Not found' }
  }
  
  const permissions = await fetchPermissions(userId)
  
  if (!permissions.canEdit) {
    return { error: 'Forbidden' }
  }
  
  return await updateResourceData(resource, permissions)
}
```

This optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/async-dependencies.md
================================================
---
title: Dependency-Based Parallelization
impact: CRITICAL
impactDescription: 2-10× improvement
tags: async, parallelization, dependencies, better-all
---

## Dependency-Based Parallelization

For operations with partial dependencies, use `better-all` to maximize parallelism. It automatically starts each task at the earliest possible moment.

**Incorrect (profile waits for config unnecessarily):**

```typescript
const [user, config] = await Promise.all([
  fetchUser(),
  fetchConfig()
])
const profile = await fetchProfile(user.id)
```

**Correct (config and profile run in parallel):**

```typescript
import { all } from 'better-all'

const { user, config, profile } = await all({
  async user() { return fetchUser() },
  async config() { return fetchConfig() },
  async profile() {
    return fetchProfile((await this.$.user).id)
  }
})
```

Reference: [https://github.com/shuding/better-all](https://github.com/shuding/better-all)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/async-parallel.md
================================================
---
title: Promise.all() for Independent Operations
impact: CRITICAL
impactDescription: 2-10× improvement
tags: async, parallelization, promises, waterfalls
---

## Promise.all() for Independent Operations

When async operations have no interdependencies, execute them concurrently using `Promise.all()`.

**Incorrect (sequential execution, 3 round trips):**

```typescript
const user = await fetchUser()
const posts = await fetchPosts()
const comments = await fetchComments()
```

**Correct (parallel execution, 1 round trip):**

```typescript
const [user, posts, comments] = await Promise.all([
  fetchUser(),
  fetchPosts(),
  fetchComments()
])
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md
================================================
---
title: Strategic Suspense Boundaries
impact: HIGH
impactDescription: faster initial paint
tags: async, suspense, streaming, layout-shift
---

## Strategic Suspense Boundaries

Instead of awaiting data in async components before returning JSX, use Suspense boundaries to show the wrapper UI faster while data loads.

**Incorrect (wrapper blocked by data fetching):**

```tsx
async function Page() {
  const data = await fetchData() // Blocks entire page
  
  return (
    <div>
      <div>Sidebar</div>
      <div>Header</div>
      <div>
        <DataDisplay data={data} />
      </div>
      <div>Footer</div>
    </div>
  )
}
```

The entire layout waits for data even though only the middle section needs it.

**Correct (wrapper shows immediately, data streams in):**

```tsx
function Page() {
  return (
    <div>
      <div>Sidebar</div>
      <div>Header</div>
      <div>
        <Suspense fallback={<Skeleton />}>
          <DataDisplay />
        </Suspense>
      </div>
      <div>Footer</div>
    </div>
  )
}

async function DataDisplay() {
  const data = await fetchData() // Only blocks this component
  return <div>{data.content}</div>
}
```

Sidebar, Header, and Footer render immediately. Only DataDisplay waits for data.

**Alternative (share promise across components):**

```tsx
function Page() {
  // Start fetch immediately, but don't await
  const dataPromise = fetchData()
  
  return (
    <div>
      <div>Sidebar</div>
      <div>Header</div>
      <Suspense fallback={<Skeleton />}>
        <DataDisplay dataPromise={dataPromise} />
        <DataSummary dataPromise={dataPromise} />
      </Suspense>
      <div>Footer</div>
    </div>
  )
}

function DataDisplay({ dataPromise }: { dataPromise: Promise<Data> }) {
  const data = use(dataPromise) // Unwraps the promise
  return <div>{data.content}</div>
}

function DataSummary({ dataPromise }: { dataPromise: Promise<Data> }) {
  const data = use(dataPromise) // Reuses the same promise
  return <div>{data.summary}</div>
}
```

Both components share the same promise, so only one fetch occurs. Layout renders immediately while both components wait together.

**When NOT to use this pattern:**

- Critical data needed for layout decisions (affects positioning)
- SEO-critical content above the fold
- Small, fast queries where suspense overhead isn't worth it
- When you want to avoid layout shift (loading → content jump)

**Trade-off:** Faster initial paint vs potential layout shift. Choose based on your UX priorities.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md
================================================
---
title: Avoid Barrel File Imports
impact: CRITICAL
impactDescription: 200-800ms import cost, slow builds
tags: bundle, imports, tree-shaking, barrel-files, performance
---

## Avoid Barrel File Imports

Import directly from source files instead of barrel files to avoid loading thousands of unused modules. **Barrel files** are entry points that re-export multiple modules (e.g., `index.js` that does `export * from './module'`).

Popular icon and component libraries can have **up to 10,000 re-exports** in their entry file. For many React packages, **it takes 200-800ms just to import them**, affecting both development speed and production cold starts.

**Why tree-shaking doesn't help:** When a library is marked as external (not bundled), the bundler can't optimize it. If you bundle it to enable tree-shaking, builds become substantially slower analyzing the entire module graph.

**Incorrect (imports entire library):**

```tsx
import { Check, X, Menu } from 'lucide-react'
// Loads 1,583 modules, takes ~2.8s extra in dev
// Runtime cost: 200-800ms on every cold start

import { Button, TextField } from '@mui/material'
// Loads 2,225 modules, takes ~4.2s extra in dev
```

**Correct (imports only what you need):**

```tsx
import Check from 'lucide-react/dist/esm/icons/check'
import X from 'lucide-react/dist/esm/icons/x'
import Menu from 'lucide-react/dist/esm/icons/menu'
// Loads only 3 modules (~2KB vs ~1MB)

import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
// Loads only what you use
```

**Alternative (Next.js 13.5+):**

```js
// next.config.js - use optimizePackageImports
module.exports = {
  experimental: {
    optimizePackageImports: ['lucide-react', '@mui/material']
  }
}

// Then you can keep the ergonomic barrel imports:
import { Check, X, Menu } from 'lucide-react'
// Automatically transformed to direct imports at build time
```

Direct imports provide 15-70% faster dev boot, 28% faster builds, 40% faster cold starts, and significantly faster HMR.

Libraries commonly affected: `lucide-react`, `@mui/material`, `@mui/icons-material`, `@tabler/icons-react`, `react-icons`, `@headlessui/react`, `@radix-ui/react-*`, `lodash`, `ramda`, `date-fns`, `rxjs`, `react-use`.

Reference: [How we optimized package imports in Next.js](https://vercel.com/blog/how-we-optimized-package-imports-in-next-js)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/bundle-conditional.md
================================================
---
title: Conditional Module Loading
impact: HIGH
impactDescription: loads large data only when needed
tags: bundle, conditional-loading, lazy-loading
---

## Conditional Module Loading

Load large data or modules only when a feature is activated.

**Example (lazy-load animation frames):**

```tsx
function AnimationPlayer({ enabled, setEnabled }: { enabled: boolean; setEnabled: React.Dispatch<React.SetStateAction<boolean>> }) {
  const [frames, setFrames] = useState<Frame[] | null>(null)

  useEffect(() => {
    if (enabled && !frames && typeof window !== 'undefined') {
      import('./animation-frames.js')
        .then(mod => setFrames(mod.frames))
        .catch(() => setEnabled(false))
    }
  }, [enabled, frames, setEnabled])

  if (!frames) return <Skeleton />
  return <Canvas frames={frames} />
}
```

The `typeof window !== 'undefined'` check prevents bundling this module for SSR, optimizing server bundle size and build speed.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md
================================================
---
title: Defer Non-Critical Third-Party Libraries
impact: MEDIUM
impactDescription: loads after hydration
tags: bundle, third-party, analytics, defer
---

## Defer Non-Critical Third-Party Libraries

Analytics, logging, and error tracking don't block user interaction. Load them after hydration.

**Incorrect (blocks initial bundle):**

```tsx
import { Analytics } from '@vercel/analytics/react'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  )
}
```

**Correct (loads after hydration):**

```tsx
import dynamic from 'next/dynamic'

const Analytics = dynamic(
  () => import('@vercel/analytics/react').then(m => m.Analytics),
  { ssr: false }
)

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  )
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md
================================================
---
title: Dynamic Imports for Heavy Components
impact: CRITICAL
impactDescription: directly affects TTI and LCP
tags: bundle, dynamic-import, code-splitting, next-dynamic
---

## Dynamic Imports for Heavy Components

Use `next/dynamic` to lazy-load large components not needed on initial render.

**Incorrect (Monaco bundles with main chunk ~300KB):**

```tsx
import { MonacoEditor } from './monaco-editor'

function CodePanel({ code }: { code: string }) {
  return <MonacoEditor value={code} />
}
```

**Correct (Monaco loads on demand):**

```tsx
import dynamic from 'next/dynamic'

const MonacoEditor = dynamic(
  () => import('./monaco-editor').then(m => m.MonacoEditor),
  { ssr: false }
)

function CodePanel({ code }: { code: string }) {
  return <MonacoEditor value={code} />
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/bundle-preload.md
================================================
---
title: Preload Based on User Intent
impact: MEDIUM
impactDescription: reduces perceived latency
tags: bundle, preload, user-intent, hover
---

## Preload Based on User Intent

Preload heavy bundles before they're needed to reduce perceived latency.

**Example (preload on hover/focus):**

```tsx
function EditorButton({ onClick }: { onClick: () => void }) {
  const preload = () => {
    if (typeof window !== 'undefined') {
      void import('./monaco-editor')
    }
  }

  return (
    <button
      onMouseEnter={preload}
      onFocus={preload}
      onClick={onClick}
    >
      Open Editor
    </button>
  )
}
```

**Example (preload when feature flag is enabled):**

```tsx
function FlagsProvider({ children, flags }: Props) {
  useEffect(() => {
    if (flags.editorEnabled && typeof window !== 'undefined') {
      void import('./monaco-editor').then(mod => mod.init())
    }
  }, [flags.editorEnabled])

  return <FlagsContext.Provider value={flags}>
    {children}
  </FlagsContext.Provider>
}
```

The `typeof window !== 'undefined'` check prevents bundling preloaded modules for SSR, optimizing server bundle size and build speed.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/client-event-listeners.md
================================================
---
title: Deduplicate Global Event Listeners
impact: LOW
impactDescription: single listener for N components
tags: client, swr, event-listeners, subscription
---

## Deduplicate Global Event Listeners

Use `useSWRSubscription()` to share global event listeners across component instances.

**Incorrect (N instances = N listeners):**

```tsx
function useKeyboardShortcut(key: string, callback: () => void) {
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.metaKey && e.key === key) {
        callback()
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [key, callback])
}
```

When using the `useKeyboardShortcut` hook multiple times, each instance will register a new listener.

**Correct (N instances = 1 listener):**

```tsx
import useSWRSubscription from 'swr/subscription'

// Module-level Map to track callbacks per key
const keyCallbacks = new Map<string, Set<() => void>>()

function useKeyboardShortcut(key: string, callback: () => void) {
  // Register this callback in the Map
  useEffect(() => {
    if (!keyCallbacks.has(key)) {
      keyCallbacks.set(key, new Set())
    }
    keyCallbacks.get(key)!.add(callback)

    return () => {
      const set = keyCallbacks.get(key)
      if (set) {
        set.delete(callback)
        if (set.size === 0) {
          keyCallbacks.delete(key)
        }
      }
    }
  }, [key, callback])

  useSWRSubscription('global-keydown', () => {
    const handler = (e: KeyboardEvent) => {
      if (e.metaKey && keyCallbacks.has(e.key)) {
        keyCallbacks.get(e.key)!.forEach(cb => cb())
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  })
}

function Profile() {
  // Multiple shortcuts will share the same listener
  useKeyboardShortcut('p', () => { /* ... */ }) 
  useKeyboardShortcut('k', () => { /* ... */ })
  // ...
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/client-localstorage-schema.md
================================================
---
title: Version and Minimize localStorage Data
impact: MEDIUM
impactDescription: prevents schema conflicts, reduces storage size
tags: client, localStorage, storage, versioning, data-minimization
---

## Version and Minimize localStorage Data

Add version prefix to keys and store only needed fields. Prevents schema conflicts and accidental storage of sensitive data.

**Incorrect:**

```typescript
// No version, stores everything, no error handling
localStorage.setItem('userConfig', JSON.stringify(fullUserObject))
const data = localStorage.getItem('userConfig')
```

**Correct:**

```typescript
const VERSION = 'v2'

function saveConfig(config: { theme: string; language: string }) {
  try {
    localStorage.setItem(`userConfig:${VERSION}`, JSON.stringify(config))
  } catch {
    // Throws in incognito/private browsing, quota exceeded, or disabled
  }
}

function loadConfig() {
  try {
    const data = localStorage.getItem(`userConfig:${VERSION}`)
    return data ? JSON.parse(data) : null
  } catch {
    return null
  }
}

// Migration from v1 to v2
function migrate() {
  try {
    const v1 = localStorage.getItem('userConfig:v1')
    if (v1) {
      const old = JSON.parse(v1)
      saveConfig({ theme: old.darkMode ? 'dark' : 'light', language: old.lang })
      localStorage.removeItem('userConfig:v1')
    }
  } catch {}
}
```

**Store minimal fields from server responses:**

```typescript
// User object has 20+ fields, only store what UI needs
function cachePrefs(user: FullUser) {
  try {
    localStorage.setItem('prefs:v1', JSON.stringify({
      theme: user.preferences.theme,
      notifications: user.preferences.notifications
    }))
  } catch {}
}
```

**Always wrap in try-catch:** `getItem()` and `setItem()` throw in incognito/private browsing (Safari, Firefox), when quota exceeded, or when disabled.

**Benefits:** Schema evolution via versioning, reduced storage size, prevents storing tokens/PII/internal flags.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md
================================================
---
title: Use Passive Event Listeners for Scrolling Performance
impact: MEDIUM
impactDescription: eliminates scroll delay caused by event listeners
tags: client, event-listeners, scrolling, performance, touch, wheel
---

## Use Passive Event Listeners for Scrolling Performance

Add `{ passive: true }` to touch and wheel event listeners to enable immediate scrolling. Browsers normally wait for listeners to finish to check if `preventDefault()` is called, causing scroll delay.

**Incorrect:**

```typescript
useEffect(() => {
  const handleTouch = (e: TouchEvent) => console.log(e.touches[0].clientX)
  const handleWheel = (e: WheelEvent) => console.log(e.deltaY)
  
  document.addEventListener('touchstart', handleTouch)
  document.addEventListener('wheel', handleWheel)
  
  return () => {
    document.removeEventListener('touchstart', handleTouch)
    document.removeEventListener('wheel', handleWheel)
  }
}, [])
```

**Correct:**

```typescript
useEffect(() => {
  const handleTouch = (e: TouchEvent) => console.log(e.touches[0].clientX)
  const handleWheel = (e: WheelEvent) => console.log(e.deltaY)
  
  document.addEventListener('touchstart', handleTouch, { passive: true })
  document.addEventListener('wheel', handleWheel, { passive: true })
  
  return () => {
    document.removeEventListener('touchstart', handleTouch)
    document.removeEventListener('wheel', handleWheel)
  }
}, [])
```

**Use passive when:** tracking/analytics, logging, any listener that doesn't call `preventDefault()`.

**Don't use passive when:** implementing custom swipe gestures, custom zoom controls, or any listener that needs `preventDefault()`.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/client-swr-dedup.md
================================================
---
title: Use SWR for Automatic Deduplication
impact: MEDIUM-HIGH
impactDescription: automatic deduplication
tags: client, swr, deduplication, data-fetching
---

## Use SWR for Automatic Deduplication

SWR enables request deduplication, caching, and revalidation across component instances.

**Incorrect (no deduplication, each instance fetches):**

```tsx
function UserList() {
  const [users, setUsers] = useState([])
  useEffect(() => {
    fetch('/api/users')
      .then(r => r.json())
      .then(setUsers)
  }, [])
}
```

**Correct (multiple instances share one request):**

```tsx
import useSWR from 'swr'

function UserList() {
  const { data: users } = useSWR('/api/users', fetcher)
}
```

**For immutable data:**

```tsx
import { useImmutableSWR } from '@/lib/swr'

function StaticContent() {
  const { data } = useImmutableSWR('/api/config', fetcher)
}
```

**For mutations:**

```tsx
import { useSWRMutation } from 'swr/mutation'

function UpdateButton() {
  const { trigger } = useSWRMutation('/api/user', updateUser)
  return <button onClick={() => trigger()}>Update</button>
}
```

Reference: [https://swr.vercel.app](https://swr.vercel.app)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-batch-dom-css.md
================================================
---
title: Batch DOM CSS Changes
impact: MEDIUM
impactDescription: reduces reflows/repaints
tags: javascript, dom, css, performance, reflow
---

## Batch DOM CSS Changes

Avoid interleaving style writes with layout reads. When you read a layout property (like `offsetWidth`, `getBoundingClientRect()`, or `getComputedStyle()`) between style changes, the browser is forced to trigger a synchronous reflow.

**Incorrect (interleaved reads and writes force reflows):**

```typescript
function updateElementStyles(element: HTMLElement) {
  element.style.width = '100px'
  const width = element.offsetWidth  // Forces reflow
  element.style.height = '200px'
  const height = element.offsetHeight  // Forces another reflow
}
```

**Correct (batch writes, then read once):**

```typescript
function updateElementStyles(element: HTMLElement) {
  // Batch all writes together
  element.style.width = '100px'
  element.style.height = '200px'
  element.style.backgroundColor = 'blue'
  element.style.border = '1px solid black'
  
  // Read after all writes are done (single reflow)
  const { width, height } = element.getBoundingClientRect()
}
```

**Better: use CSS classes**

```css
.highlighted-box {
  width: 100px;
  height: 200px;
  background-color: blue;
  border: 1px solid black;
}
```

```typescript
function updateElementStyles(element: HTMLElement) {
  element.classList.add('highlighted-box')

  const { width, height } = element.getBoundingClientRect()
}
```

Prefer CSS classes over inline styles when possible. CSS files are cached by the browser, and classes provide better separation of concerns and are easier to maintain.

================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-cache-function-results.md
================================================
---
title: Cache Repeated Function Calls
impact: MEDIUM
impactDescription: avoid redundant computation
tags: javascript, cache, memoization, performance
---

## Cache Repeated Function Calls

Use a module-level Map to cache function results when the same function is called repeatedly with the same inputs during render.

**Incorrect (redundant computation):**

```typescript
function ProjectList({ projects }: { projects: Project[] }) {
  return (
    <div>
      {projects.map(project => {
        // slugify() called 100+ times for same project names
        const slug = slugify(project.name)
        
        return <ProjectCard key={project.id} slug={slug} />
      })}
    </div>
  )
}
```

**Correct (cached results):**

```typescript
// Module-level cache
const slugifyCache = new Map<string, string>()

function cachedSlugify(text: string): string {
  if (slugifyCache.has(text)) {
    return slugifyCache.get(text)!
  }
  const result = slugify(text)
  slugifyCache.set(text, result)
  return result
}

function ProjectList({ projects }: { projects: Project[] }) {
  return (
    <div>
      {projects.map(project => {
        // Computed only once per unique project name
        const slug = cachedSlugify(project.name)
        
        return <ProjectCard key={project.id} slug={slug} />
      })}
    </div>
  )
}
```

**Simpler pattern for single-value functions:**

```typescript
let isLoggedInCache: boolean | null = null

function isLoggedIn(): boolean {
  if (isLoggedInCache !== null) {
    return isLoggedInCache
  }
  
  isLoggedInCache = document.cookie.includes('auth=')
  return isLoggedInCache
}

// Clear cache when auth changes
function onAuthChange() {
  isLoggedInCache = null
}
```

Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.

Reference: [How we made the Vercel Dashboard twice as fast](https://vercel.com/blog/how-we-made-the-vercel-dashboard-twice-as-fast)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-cache-property-access.md
================================================
---
title: Cache Property Access in Loops
impact: LOW-MEDIUM
impactDescription: reduces lookups
tags: javascript, loops, optimization, caching
---

## Cache Property Access in Loops

Cache object property lookups in hot paths.

**Incorrect (3 lookups × N iterations):**

```typescript
for (let i = 0; i < arr.length; i++) {
  process(obj.config.settings.value)
}
```

**Correct (1 lookup total):**

```typescript
const value = obj.config.settings.value
const len = arr.length
for (let i = 0; i < len; i++) {
  process(value)
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-cache-storage.md
================================================
---
title: Cache Storage API Calls
impact: LOW-MEDIUM
impactDescription: reduces expensive I/O
tags: javascript, localStorage, storage, caching, performance
---

## Cache Storage API Calls

`localStorage`, `sessionStorage`, and `document.cookie` are synchronous and expensive. Cache reads in memory.

**Incorrect (reads storage on every call):**

```typescript
function getTheme() {
  return localStorage.getItem('theme') ?? 'light'
}
// Called 10 times = 10 storage reads
```

**Correct (Map cache):**

```typescript
const storageCache = new Map<string, string | null>()

function getLocalStorage(key: string) {
  if (!storageCache.has(key)) {
    storageCache.set(key, localStorage.getItem(key))
  }
  return storageCache.get(key)
}

function setLocalStorage(key: string, value: string) {
  localStorage.setItem(key, value)
  storageCache.set(key, value)  // keep cache in sync
}
```

Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.

**Cookie caching:**

```typescript
let cookieCache: Record<string, string> | null = null

function getCookie(name: string) {
  if (!cookieCache) {
    cookieCache = Object.fromEntries(
      document.cookie.split('; ').map(c => c.split('='))
    )
  }
  return cookieCache[name]
}
```

**Important (invalidate on external changes):**

If storage can change externally (another tab, server-set cookies), invalidate cache:

```typescript
window.addEventListener('storage', (e) => {
  if (e.key) storageCache.delete(e.key)
})

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'visible') {
    storageCache.clear()
  }
})
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-combine-iterations.md
================================================
---
title: Combine Multiple Array Iterations
impact: LOW-MEDIUM
impactDescription: reduces iterations
tags: javascript, arrays, loops, performance
---

## Combine Multiple Array Iterations

Multiple `.filter()` or `.map()` calls iterate the array multiple times. Combine into one loop.

**Incorrect (3 iterations):**

```typescript
const admins = users.filter(u => u.isAdmin)
const testers = users.filter(u => u.isTester)
const inactive = users.filter(u => !u.isActive)
```

**Correct (1 iteration):**

```typescript
const admins: User[] = []
const testers: User[] = []
const inactive: User[] = []

for (const user of users) {
  if (user.isAdmin) admins.push(user)
  if (user.isTester) testers.push(user)
  if (!user.isActive) inactive.push(user)
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-early-exit.md
================================================
---
title: Early Return from Functions
impact: LOW-MEDIUM
impactDescription: avoids unnecessary computation
tags: javascript, functions, optimization, early-return
---

## Early Return from Functions

Return early when result is determined to skip unnecessary processing.

**Incorrect (processes all items even after finding answer):**

```typescript
function validateUsers(users: User[]) {
  let hasError = false
  let errorMessage = ''
  
  for (const user of users) {
    if (!user.email) {
      hasError = true
      errorMessage = 'Email required'
    }
    if (!user.name) {
      hasError = true
      errorMessage = 'Name required'
    }
    // Continues checking all users even after error found
  }
  
  return hasError ? { valid: false, error: errorMessage } : { valid: true }
}
```

**Correct (returns immediately on first error):**

```typescript
function validateUsers(users: User[]) {
  for (const user of users) {
    if (!user.email) {
      return { valid: false, error: 'Email required' }
    }
    if (!user.name) {
      return { valid: false, error: 'Name required' }
    }
  }

  return { valid: true }
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-hoist-regexp.md
================================================
---
title: Hoist RegExp Creation
impact: LOW-MEDIUM
impactDescription: avoids recreation
tags: javascript, regexp, optimization, memoization
---

## Hoist RegExp Creation

Don't create RegExp inside render. Hoist to module scope or memoize with `useMemo()`.

**Incorrect (new RegExp every render):**

```tsx
function Highlighter({ text, query }: Props) {
  const regex = new RegExp(`(${query})`, 'gi')
  const parts = text.split(regex)
  return <>{parts.map((part, i) => ...)}</>
}
```

**Correct (memoize or hoist):**

```tsx
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

function Highlighter({ text, query }: Props) {
  const regex = useMemo(
    () => new RegExp(`(${escapeRegex(query)})`, 'gi'),
    [query]
  )
  const parts = text.split(regex)
  return <>{parts.map((part, i) => ...)}</>
}
```

**Warning (global regex has mutable state):**

Global regex (`/g`) has mutable `lastIndex` state:

```typescript
const regex = /foo/g
regex.test('foo')  // true, lastIndex = 3
regex.test('foo')  // false, lastIndex = 0
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-index-maps.md
================================================
---
title: Build Index Maps for Repeated Lookups
impact: LOW-MEDIUM
impactDescription: 1M ops to 2K ops
tags: javascript, map, indexing, optimization, performance
---

## Build Index Maps for Repeated Lookups

Multiple `.find()` calls by the same key should use a Map.

**Incorrect (O(n) per lookup):**

```typescript
function processOrders(orders: Order[], users: User[]) {
  return orders.map(order => ({
    ...order,
    user: users.find(u => u.id === order.userId)
  }))
}
```

**Correct (O(1) per lookup):**

```typescript
function processOrders(orders: Order[], users: User[]) {
  const userById = new Map(users.map(u => [u.id, u]))

  return orders.map(order => ({
    ...order,
    user: userById.get(order.userId)
  }))
}
```

Build map once (O(n)), then all lookups are O(1).
For 1000 orders × 1000 users: 1M ops → 2K ops.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-length-check-first.md
================================================
---
title: Early Length Check for Array Comparisons
impact: MEDIUM-HIGH
impactDescription: avoids expensive operations when lengths differ
tags: javascript, arrays, performance, optimization, comparison
---

## Early Length Check for Array Comparisons

When comparing arrays with expensive operations (sorting, deep equality, serialization), check lengths first. If lengths differ, the arrays cannot be equal.

In real-world applications, this optimization is especially valuable when the comparison runs in hot paths (event handlers, render loops).

**Incorrect (always runs expensive comparison):**

```typescript
function hasChanges(current: string[], original: string[]) {
  // Always sorts and joins, even when lengths differ
  return current.sort().join() !== original.sort().join()
}
```

Two O(n log n) sorts run even when `current.length` is 5 and `original.length` is 100. There is also overhead of joining the arrays and comparing the strings.

**Correct (O(1) length check first):**

```typescript
function hasChanges(current: string[], original: string[]) {
  // Early return if lengths differ
  if (current.length !== original.length) {
    return true
  }
  // Only sort when lengths match
  const currentSorted = current.toSorted()
  const originalSorted = original.toSorted()
  for (let i = 0; i < currentSorted.length; i++) {
    if (currentSorted[i] !== originalSorted[i]) {
      return true
    }
  }
  return false
}
```

This new approach is more efficient because:
- It avoids the overhead of sorting and joining the arrays when lengths differ
- It avoids consuming memory for the joined strings (especially important for large arrays)
- It avoids mutating the original arrays
- It returns early when a difference is found


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-min-max-loop.md
================================================
---
title: Use Loop for Min/Max Instead of Sort
impact: LOW
impactDescription: O(n) instead of O(n log n)
tags: javascript, arrays, performance, sorting, algorithms
---

## Use Loop for Min/Max Instead of Sort

Finding the smallest or largest element only requires a single pass through the array. Sorting is wasteful and slower.

**Incorrect (O(n log n) - sort to find latest):**

```typescript
interface Project {
  id: string
  name: string
  updatedAt: number
}

function getLatestProject(projects: Project[]) {
  const sorted = [...projects].sort((a, b) => b.updatedAt - a.updatedAt)
  return sorted[0]
}
```

Sorts the entire array just to find the maximum value.

**Incorrect (O(n log n) - sort for oldest and newest):**

```typescript
function getOldestAndNewest(projects: Project[]) {
  const sorted = [...projects].sort((a, b) => a.updatedAt - b.updatedAt)
  return { oldest: sorted[0], newest: sorted[sorted.length - 1] }
}
```

Still sorts unnecessarily when only min/max are needed.

**Correct (O(n) - single loop):**

```typescript
function getLatestProject(projects: Project[]) {
  if (projects.length === 0) return null
  
  let latest = projects[0]
  
  for (let i = 1; i < projects.length; i++) {
    if (projects[i].updatedAt > latest.updatedAt) {
      latest = projects[i]
    }
  }
  
  return latest
}

function getOldestAndNewest(projects: Project[]) {
  if (projects.length === 0) return { oldest: null, newest: null }
  
  let oldest = projects[0]
  let newest = projects[0]
  
  for (let i = 1; i < projects.length; i++) {
    if (projects[i].updatedAt < oldest.updatedAt) oldest = projects[i]
    if (projects[i].updatedAt > newest.updatedAt) newest = projects[i]
  }
  
  return { oldest, newest }
}
```

Single pass through the array, no copying, no sorting.

**Alternative (Math.min/Math.max for small arrays):**

```typescript
const numbers = [5, 2, 8, 1, 9]
const min = Math.min(...numbers)
const max = Math.max(...numbers)
```

This works for small arrays, but can be slower or just throw an error for very large arrays due to spread operator limitations. Maximal array length is approximately 124000 in Chrome 143 and 638000 in Safari 18; exact numbers may vary - see [the fiddle](https://jsfiddle.net/qw1jabsx/4/). Use the loop approach for reliability.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-set-map-lookups.md
================================================
---
title: Use Set/Map for O(1) Lookups
impact: LOW-MEDIUM
impactDescription: O(n) to O(1)
tags: javascript, set, map, data-structures, performance
---

## Use Set/Map for O(1) Lookups

Convert arrays to Set/Map for repeated membership checks.

**Incorrect (O(n) per check):**

```typescript
const allowedIds = ['a', 'b', 'c', ...]
items.filter(item => allowedIds.includes(item.id))
```

**Correct (O(1) per check):**

```typescript
const allowedIds = new Set(['a', 'b', 'c', ...])
items.filter(item => allowedIds.has(item.id))
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md
================================================
---
title: Use toSorted() Instead of sort() for Immutability
impact: MEDIUM-HIGH
impactDescription: prevents mutation bugs in React state
tags: javascript, arrays, immutability, react, state, mutation
---

## Use toSorted() Instead of sort() for Immutability

`.sort()` mutates the array in place, which can cause bugs with React state and props. Use `.toSorted()` to create a new sorted array without mutation.

**Incorrect (mutates original array):**

```typescript
function UserList({ users }: { users: User[] }) {
  // Mutates the users prop array!
  const sorted = useMemo(
    () => users.sort((a, b) => a.name.localeCompare(b.name)),
    [users]
  )
  return <div>{sorted.map(renderUser)}</div>
}
```

**Correct (creates new array):**

```typescript
function UserList({ users }: { users: User[] }) {
  // Creates new sorted array, original unchanged
  const sorted = useMemo(
    () => users.toSorted((a, b) => a.name.localeCompare(b.name)),
    [users]
  )
  return <div>{sorted.map(renderUser)}</div>
}
```

**Why this matters in React:**

1. Props/state mutations break React's immutability model - React expects props and state to be treated as read-only
2. Causes stale closure bugs - Mutating arrays inside closures (callbacks, effects) can lead to unexpected behavior

**Browser support (fallback for older browsers):**

`.toSorted()` is available in all modern browsers (Chrome 110+, Safari 16+, Firefox 115+, Node.js 20+). For older environments, use spread operator:

```typescript
// Fallback for older browsers
const sorted = [...items].sort((a, b) => a.value - b.value)
```

**Other immutable array methods:**

- `.toSorted()` - immutable sort
- `.toReversed()` - immutable reverse
- `.toSpliced()` - immutable splice
- `.with()` - immutable element replacement


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rendering-activity.md
================================================
---
title: Use Activity Component for Show/Hide
impact: MEDIUM
impactDescription: preserves state/DOM
tags: rendering, activity, visibility, state-preservation
---

## Use Activity Component for Show/Hide

Use React's `<Activity>` to preserve state/DOM for expensive components that frequently toggle visibility.

**Usage:**

```tsx
import { Activity } from 'react'

function Dropdown({ isOpen }: Props) {
  return (
    <Activity mode={isOpen ? 'visible' : 'hidden'}>
      <ExpensiveMenu />
    </Activity>
  )
}
```

Avoids expensive re-renders and state loss.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md
================================================
---
title: Animate SVG Wrapper Instead of SVG Element
impact: LOW
impactDescription: enables hardware acceleration
tags: rendering, svg, css, animation, performance
---

## Animate SVG Wrapper Instead of SVG Element

Many browsers don't have hardware acceleration for CSS3 animations on SVG elements. Wrap SVG in a `<div>` and animate the wrapper instead.

**Incorrect (animating SVG directly - no hardware acceleration):**

```tsx
function LoadingSpinner() {
  return (
    <svg 
      className="animate-spin"
      width="24" 
      height="24" 
      viewBox="0 0 24 24"
    >
      <circle cx="12" cy="12" r="10" stroke="currentColor" />
    </svg>
  )
}
```

**Correct (animating wrapper div - hardware accelerated):**

```tsx
function LoadingSpinner() {
  return (
    <div className="animate-spin">
      <svg 
        width="24" 
        height="24" 
        viewBox="0 0 24 24"
      >
        <circle cx="12" cy="12" r="10" stroke="currentColor" />
      </svg>
    </div>
  )
}
```

This applies to all CSS transforms and transitions (`transform`, `opacity`, `translate`, `scale`, `rotate`). The wrapper div allows browsers to use GPU acceleration for smoother animations.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rendering-conditional-render.md
================================================
---
title: Use Explicit Conditional Rendering
impact: LOW
impactDescription: prevents rendering 0 or NaN
tags: rendering, conditional, jsx, falsy-values
---

## Use Explicit Conditional Rendering

Use explicit ternary operators (`? :`) instead of `&&` for conditional rendering when the condition can be `0`, `NaN`, or other falsy values that render.

**Incorrect (renders "0" when count is 0):**

```tsx
function Badge({ count }: { count: number }) {
  return (
    <div>
      {count && <span className="badge">{count}</span>}
    </div>
  )
}

// When count = 0, renders: <div>0</div>
// When count = 5, renders: <div><span class="badge">5</span></div>
```

**Correct (renders nothing when count is 0):**

```tsx
function Badge({ count }: { count: number }) {
  return (
    <div>
      {count > 0 ? <span className="badge">{count}</span> : null}
    </div>
  )
}

// When count = 0, renders: <div></div>
// When count = 5, renders: <div><span class="badge">5</span></div>
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rendering-content-visibility.md
================================================
---
title: CSS content-visibility for Long Lists
impact: HIGH
impactDescription: faster initial render
tags: rendering, css, content-visibility, long-lists
---

## CSS content-visibility for Long Lists

Apply `content-visibility: auto` to defer off-screen rendering.

**CSS:**

```css
.message-item {
  content-visibility: auto;
  contain-intrinsic-size: 0 80px;
}
```

**Example:**

```tsx
function MessageList({ messages }: { messages: Message[] }) {
  return (
    <div className="overflow-y-auto h-screen">
      {messages.map(msg => (
        <div key={msg.id} className="message-item">
          <Avatar user={msg.author} />
          <div>{msg.content}</div>
        </div>
      ))}
    </div>
  )
}
```

For 1000 messages, browser skips layout/paint for ~990 off-screen items (10× faster initial render).


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md
================================================
---
title: Hoist Static JSX Elements
impact: LOW
impactDescription: avoids re-creation
tags: rendering, jsx, static, optimization
---

## Hoist Static JSX Elements

Extract static JSX outside components to avoid re-creation.

**Incorrect (recreates element every render):**

```tsx
function LoadingSkeleton() {
  return <div className="animate-pulse h-20 bg-gray-200" />
}

function Container() {
  return (
    <div>
      {loading && <LoadingSkeleton />}
    </div>
  )
}
```

**Correct (reuses same element):**

```tsx
const loadingSkeleton = (
  <div className="animate-pulse h-20 bg-gray-200" />
)

function Container() {
  return (
    <div>
      {loading && loadingSkeleton}
    </div>
  )
}
```

This is especially helpful for large and static SVG nodes, which can be expensive to recreate on every render.

**Note:** If your project has [React Compiler](https://react.dev/learn/react-compiler) enabled, the compiler automatically hoists static JSX elements and optimizes component re-renders, making manual hoisting unnecessary.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md
================================================
---
title: Prevent Hydration Mismatch Without Flickering
impact: MEDIUM
impactDescription: avoids visual flicker and hydration errors
tags: rendering, ssr, hydration, localStorage, flicker
---

## Prevent Hydration Mismatch Without Flickering

When rendering content that depends on client-side storage (localStorage, cookies), avoid both SSR breakage and post-hydration flickering by injecting a synchronous script that updates the DOM before React hydrates.

**Incorrect (breaks SSR):**

```tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
  // localStorage is not available on server - throws error
  const theme = localStorage.getItem('theme') || 'light'
  
  return (
    <div className={theme}>
      {children}
    </div>
  )
}
```

Server-side rendering will fail because `localStorage` is undefined.

**Incorrect (visual flickering):**

```tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
  const [theme, setTheme] = useState('light')
  
  useEffect(() => {
    // Runs after hydration - causes visible flash
    const stored = localStorage.getItem('theme')
    if (stored) {
      setTheme(stored)
    }
  }, [])
  
  return (
    <div className={theme}>
      {children}
    </div>
  )
}
```

Component first renders with default value (`light`), then updates after hydration, causing a visible flash of incorrect content.

**Correct (no flicker, no hydration mismatch):**

```tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
  return (
    <>
      <div id="theme-wrapper">
        {children}
      </div>
      <script
        dangerouslySetInnerHTML={{
          __html: `
            (function() {
              try {
                var theme = localStorage.getItem('theme') || 'light';
                var el = document.getElementById('theme-wrapper');
                if (el) el.className = theme;
              } catch (e) {}
            })();
          `,
        }}
      />
    </>
  )
}
```

The inline script executes synchronously before showing the element, ensuring the DOM already has the correct value. No flickering, no hydration mismatch.

This pattern is especially useful for theme toggles, user preferences, authentication states, and any client-only data that should render immediately without flashing default values.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rendering-svg-precision.md
================================================
---
title: Optimize SVG Precision
impact: LOW
impactDescription: reduces file size
tags: rendering, svg, optimization, svgo
---

## Optimize SVG Precision

Reduce SVG coordinate precision to decrease file size. The optimal precision depends on the viewBox size, but in general reducing precision should be considered.

**Incorrect (excessive precision):**

```svg
<path d="M 10.293847 20.847362 L 30.938472 40.192837" />
```

**Correct (1 decimal place):**

```svg
<path d="M 10.3 20.8 L 30.9 40.2" />
```

**Automate with SVGO:**

```bash
npx svgo --precision=1 --multipass icon.svg
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-defer-reads.md
================================================
---
title: Defer State Reads to Usage Point
impact: MEDIUM
impactDescription: avoids unnecessary subscriptions
tags: rerender, searchParams, localStorage, optimization
---

## Defer State Reads to Usage Point

Don't subscribe to dynamic state (searchParams, localStorage) if you only read it inside callbacks.

**Incorrect (subscribes to all searchParams changes):**

```tsx
function ShareButton({ chatId }: { chatId: string }) {
  const searchParams = useSearchParams()

  const handleShare = () => {
    const ref = searchParams.get('ref')
    shareChat(chatId, { ref })
  }

  return <button onClick={handleShare}>Share</button>
}
```

**Correct (reads on demand, no subscription):**

```tsx
function ShareButton({ chatId }: { chatId: string }) {
  const handleShare = () => {
    const params = new URLSearchParams(window.location.search)
    const ref = params.get('ref')
    shareChat(chatId, { ref })
  }

  return <button onClick={handleShare}>Share</button>
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-dependencies.md
================================================
---
title: Narrow Effect Dependencies
impact: LOW
impactDescription: minimizes effect re-runs
tags: rerender, useEffect, dependencies, optimization
---

## Narrow Effect Dependencies

Specify primitive dependencies instead of objects to minimize effect re-runs.

**Incorrect (re-runs on any user field change):**

```tsx
useEffect(() => {
  console.log(user.id)
}, [user])
```

**Correct (re-runs only when id changes):**

```tsx
useEffect(() => {
  console.log(user.id)
}, [user.id])
```

**For derived state, compute outside effect:**

```tsx
// Incorrect: runs on width=767, 766, 765...
useEffect(() => {
  if (width < 768) {
    enableMobileMode()
  }
}, [width])

// Correct: runs only on boolean transition
const isMobile = width < 768
useEffect(() => {
  if (isMobile) {
    enableMobileMode()
  }
}, [isMobile])
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-derived-state.md
================================================
---
title: Subscribe to Derived State
impact: MEDIUM
impactDescription: reduces re-render frequency
tags: rerender, derived-state, media-query, optimization
---

## Subscribe to Derived State

Subscribe to derived boolean state instead of continuous values to reduce re-render frequency.

**Incorrect (re-renders on every pixel change):**

```tsx
function Sidebar() {
  const width = useWindowWidth()  // updates continuously
  const isMobile = width < 768
  return <nav className={isMobile ? 'mobile' : 'desktop'} />
}
```

**Correct (re-renders only when boolean changes):**

```tsx
function Sidebar() {
  const isMobile = useMediaQuery('(max-width: 767px)')
  return <nav className={isMobile ? 'mobile' : 'desktop'} />
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md
================================================
---
title: Use Functional setState Updates
impact: MEDIUM
impactDescription: prevents stale closures and unnecessary callback recreations
tags: react, hooks, useState, useCallback, callbacks, closures
---

## Use Functional setState Updates

When updating state based on the current state value, use the functional update form of setState instead of directly referencing the state variable. This prevents stale closures, eliminates unnecessary dependencies, and creates stable callback references.

**Incorrect (requires state as dependency):**

```tsx
function TodoList() {
  const [items, setItems] = useState(initialItems)
  
  // Callback must depend on items, recreated on every items change
  const addItems = useCallback((newItems: Item[]) => {
    setItems([...items, ...newItems])
  }, [items])  // ❌ items dependency causes recreations
  
  // Risk of stale closure if dependency is forgotten
  const removeItem = useCallback((id: string) => {
    setItems(items.filter(item => item.id !== id))
  }, [])  // ❌ Missing items dependency - will use stale items!
  
  return <ItemsEditor items={items} onAdd={addItems} onRemove={removeItem} />
}
```

The first callback is recreated every time `items` changes, which can cause child components to re-render unnecessarily. The second callback has a stale closure bug—it will always reference the initial `items` value.

**Correct (stable callbacks, no stale closures):**

```tsx
function TodoList() {
  const [items, setItems] = useState(initialItems)
  
  // Stable callback, never recreated
  const addItems = useCallback((newItems: Item[]) => {
    setItems(curr => [...curr, ...newItems])
  }, [])  // ✅ No dependencies needed
  
  // Always uses latest state, no stale closure risk
  const removeItem = useCallback((id: string) => {
    setItems(curr => curr.filter(item => item.id !== id))
  }, [])  // ✅ Safe and stable
  
  return <ItemsEditor items={items} onAdd={addItems} onRemove={removeItem} />
}
```

**Benefits:**

1. **Stable callback references** - Callbacks don't need to be recreated when state changes
2. **No stale closures** - Always operates on the latest state value
3. **Fewer dependencies** - Simplifies dependency arrays and reduces memory leaks
4. **Prevents bugs** - Eliminates the most common source of React closure bugs

**When to use functional updates:**

- Any setState that depends on the current state value
- Inside useCallback/useMemo when state is needed
- Event handlers that reference state
- Async operations that update state

**When direct updates are fine:**

- Setting state to a static value: `setCount(0)`
- Setting state from props/arguments only: `setName(newName)`
- State doesn't depend on previous value

**Note:** If your project has [React Compiler](https://react.dev/learn/react-compiler) enabled, the compiler can automatically optimize some cases, but functional updates are still recommended for correctness and to prevent stale closure bugs.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md
================================================
---
title: Use Lazy State Initialization
impact: MEDIUM
impactDescription: wasted computation on every render
tags: react, hooks, useState, performance, initialization
---

## Use Lazy State Initialization

Pass a function to `useState` for expensive initial values. Without the function form, the initializer runs on every render even though the value is only used once.

**Incorrect (runs on every render):**

```tsx
function FilteredList({ items }: { items: Item[] }) {
  // buildSearchIndex() runs on EVERY render, even after initialization
  const [searchIndex, setSearchIndex] = useState(buildSearchIndex(items))
  const [query, setQuery] = useState('')
  
  // When query changes, buildSearchIndex runs again unnecessarily
  return <SearchResults index={searchIndex} query={query} />
}

function UserProfile() {
  // JSON.parse runs on every render
  const [settings, setSettings] = useState(
    JSON.parse(localStorage.getItem('settings') || '{}')
  )
  
  return <SettingsForm settings={settings} onChange={setSettings} />
}
```

**Correct (runs only once):**

```tsx
function FilteredList({ items }: { items: Item[] }) {
  // buildSearchIndex() runs ONLY on initial render
  const [searchIndex, setSearchIndex] = useState(() => buildSearchIndex(items))
  const [query, setQuery] = useState('')
  
  return <SearchResults index={searchIndex} query={query} />
}

function UserProfile() {
  // JSON.parse runs only on initial render
  const [settings, setSettings] = useState(() => {
    const stored = localStorage.getItem('settings')
    return stored ? JSON.parse(stored) : {}
  })
  
  return <SettingsForm settings={settings} onChange={setSettings} />
}
```

Use lazy initialization when computing initial values from localStorage/sessionStorage, building data structures (indexes, maps), reading from the DOM, or performing heavy transformations.

For simple primitives (`useState(0)`), direct references (`useState(props.value)`), or cheap literals (`useState({})`), the function form is unnecessary.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-memo.md
================================================
---
title: Extract to Memoized Components
impact: MEDIUM
impactDescription: enables early returns
tags: rerender, memo, useMemo, optimization
---

## Extract to Memoized Components

Extract expensive work into memoized components to enable early returns before computation.

**Incorrect (computes avatar even when loading):**

```tsx
function Profile({ user, loading }: Props) {
  const avatar = useMemo(() => {
    const id = computeAvatarId(user)
    return <Avatar id={id} />
  }, [user])

  if (loading) return <Skeleton />
  return <div>{avatar}</div>
}
```

**Correct (skips computation when loading):**

```tsx
const UserAvatar = memo(function UserAvatar({ user }: { user: User }) {
  const id = useMemo(() => computeAvatarId(user), [user])
  return <Avatar id={id} />
})

function Profile({ user, loading }: Props) {
  if (loading) return <Skeleton />
  return (
    <div>
      <UserAvatar user={user} />
    </div>
  )
}
```

**Note:** If your project has [React Compiler](https://react.dev/learn/react-compiler) enabled, manual memoization with `memo()` and `useMemo()` is not necessary. The compiler automatically optimizes re-renders.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md
================================================
---
title: Do not wrap a simple expression with a primitive result type in useMemo
impact: LOW-MEDIUM
impactDescription: wasted computation on every render
tags: rerender, useMemo, optimization
---

## Do not wrap a simple expression with a primitive result type in useMemo

When an expression is simple (few logical or arithmetical operators) and has a primitive result type (boolean, number, string), do not wrap it in `useMemo`.
Calling `useMemo` and comparing hook dependencies may consume more resources than the expression itself.

**Incorrect:**

```tsx
function Header({ user, notifications }: Props) {
  const isLoading = useMemo(() => {
    return user.isLoading || notifications.isLoading
  }, [user.isLoading, notifications.isLoading])

  if (isLoading) return <Skeleton />
  // return some markup
}
```

**Correct:**

```tsx
function Header({ user, notifications }: Props) {
  const isLoading = user.isLoading || notifications.isLoading

  if (isLoading) return <Skeleton />
  // return some markup
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/rerender-transitions.md
================================================
---
title: Use Transitions for Non-Urgent Updates
impact: MEDIUM
impactDescription: maintains UI responsiveness
tags: rerender, transitions, startTransition, performance
---

## Use Transitions for Non-Urgent Updates

Mark frequent, non-urgent state updates as transitions to maintain UI responsiveness.

**Incorrect (blocks UI on every scroll):**

```tsx
function ScrollTracker() {
  const [scrollY, setScrollY] = useState(0)
  useEffect(() => {
    const handler = () => setScrollY(window.scrollY)
    window.addEventListener('scroll', handler, { passive: true })
    return () => window.removeEventListener('scroll', handler)
  }, [])
}
```

**Correct (non-blocking updates):**

```tsx
import { startTransition } from 'react'

function ScrollTracker() {
  const [scrollY, setScrollY] = useState(0)
  useEffect(() => {
    const handler = () => {
      startTransition(() => setScrollY(window.scrollY))
    }
    window.addEventListener('scroll', handler, { passive: true })
    return () => window.removeEventListener('scroll', handler)
  }, [])
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/server-after-nonblocking.md
================================================
---
title: Use after() for Non-Blocking Operations
impact: MEDIUM
impactDescription: faster response times
tags: server, async, logging, analytics, side-effects
---

## Use after() for Non-Blocking Operations

Use Next.js's `after()` to schedule work that should execute after a response is sent. This prevents logging, analytics, and other side effects from blocking the response.

**Incorrect (blocks response):**

```tsx
import { logUserAction } from '@/app/utils'

export async function POST(request: Request) {
  // Perform mutation
  await updateDatabase(request)
  
  // Logging blocks the response
  const userAgent = request.headers.get('user-agent') || 'unknown'
  await logUserAction({ userAgent })
  
  return new Response(JSON.stringify({ status: 'success' }), {
    status: 200,
    headers: { 'Content-Type': 'application/json' }
  })
}
```

**Correct (non-blocking):**

```tsx
import { after } from 'next/server'
import { headers, cookies } from 'next/headers'
import { logUserAction } from '@/app/utils'

export async function POST(request: Request) {
  // Perform mutation
  await updateDatabase(request)
  
  // Log after response is sent
  after(async () => {
    const userAgent = (await headers()).get('user-agent') || 'unknown'
    const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'
    
    logUserAction({ sessionCookie, userAgent })
  })
  
  return new Response(JSON.stringify({ status: 'success' }), {
    status: 200,
    headers: { 'Content-Type': 'application/json' }
  })
}
```

The response is sent immediately while logging happens in the background.

**Common use cases:**

- Analytics tracking
- Audit logging
- Sending notifications
- Cache invalidation
- Cleanup tasks

**Important notes:**

- `after()` runs even if the response fails or redirects
- Works in Server Actions, Route Handlers, and Server Components

Reference: [https://nextjs.org/docs/app/api-reference/functions/after](https://nextjs.org/docs/app/api-reference/functions/after)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/server-auth-actions.md
================================================
---
title: Authenticate Server Actions Like API Routes
impact: CRITICAL
impactDescription: prevents unauthorized access to server mutations
tags: server, server-actions, authentication, security, authorization
---

## Authenticate Server Actions Like API Routes

**Impact: CRITICAL (prevents unauthorized access to server mutations)**

Server Actions (functions with `"use server"`) are exposed as public endpoints, just like API routes. Always verify authentication and authorization **inside** each Server Action—do not rely solely on middleware, layout guards, or page-level checks, as Server Actions can be invoked directly.

Next.js documentation explicitly states: "Treat Server Actions with the same security considerations as public-facing API endpoints, and verify if the user is allowed to perform a mutation."

**Incorrect (no authentication check):**

```typescript
'use server'

export async function deleteUser(userId: string) {
  // Anyone can call this! No auth check
  await db.user.delete({ where: { id: userId } })
  return { success: true }
}
```

**Correct (authentication inside the action):**

```typescript
'use server'

import { verifySession } from '@/lib/auth'
import { unauthorized } from '@/lib/errors'

export async function deleteUser(userId: string) {
  // Always check auth inside the action
  const session = await verifySession()
  
  if (!session) {
    throw unauthorized('Must be logged in')
  }
  
  // Check authorization too
  if (session.user.role !== 'admin' && session.user.id !== userId) {
    throw unauthorized('Cannot delete other users')
  }
  
  await db.user.delete({ where: { id: userId } })
  return { success: true }
}
```

**With input validation:**

```typescript
'use server'

import { verifySession } from '@/lib/auth'
import { z } from 'zod'

const updateProfileSchema = z.object({
  userId: z.string().uuid(),
  name: z.string().min(1).max(100),
  email: z.string().email()
})

export async function updateProfile(data: unknown) {
  // Validate input first
  const validated = updateProfileSchema.parse(data)
  
  // Then authenticate
  const session = await verifySession()
  if (!session) {
    throw new Error('Unauthorized')
  }
  
  // Then authorize
  if (session.user.id !== validated.userId) {
    throw new Error('Can only update own profile')
  }
  
  // Finally perform the mutation
  await db.user.update({
    where: { id: validated.userId },
    data: {
      name: validated.name,
      email: validated.email
    }
  })
  
  return { success: true }
}
```

Reference: [https://nextjs.org/docs/app/guides/authentication](https://nextjs.org/docs/app/guides/authentication)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/server-cache-lru.md
================================================
---
title: Cross-Request LRU Caching
impact: HIGH
impactDescription: caches across requests
tags: server, cache, lru, cross-request
---

## Cross-Request LRU Caching

`React.cache()` only works within one request. For data shared across sequential requests (user clicks button A then button B), use an LRU cache.

**Implementation:**

```typescript
import { LRUCache } from 'lru-cache'

const cache = new LRUCache<string, any>({
  max: 1000,
  ttl: 5 * 60 * 1000  // 5 minutes
})

export async function getUser(id: string) {
  const cached = cache.get(id)
  if (cached) return cached

  const user = await db.user.findUnique({ where: { id } })
  cache.set(id, user)
  return user
}

// Request 1: DB query, result cached
// Request 2: cache hit, no DB query
```

Use when sequential user actions hit multiple endpoints needing the same data within seconds.

**With Vercel's [Fluid Compute](https://vercel.com/docs/fluid-compute):** LRU caching is especially effective because multiple concurrent requests can share the same function instance and cache. This means the cache persists across requests without needing external storage like Redis.

**In traditional serverless:** Each invocation runs in isolation, so consider Redis for cross-process caching.

Reference: [https://github.com/isaacs/node-lru-cache](https://github.com/isaacs/node-lru-cache)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/server-cache-react.md
================================================
---
title: Per-Request Deduplication with React.cache()
impact: MEDIUM
impactDescription: deduplicates within request
tags: server, cache, react-cache, deduplication
---

## Per-Request Deduplication with React.cache()

Use `React.cache()` for server-side request deduplication. Authentication and database queries benefit most.

**Usage:**

```typescript
import { cache } from 'react'

export const getCurrentUser = cache(async () => {
  const session = await auth()
  if (!session?.user?.id) return null
  return await db.user.findUnique({
    where: { id: session.user.id }
  })
})
```

Within a single request, multiple calls to `getCurrentUser()` execute the query only once.

**Avoid inline objects as arguments:**

`React.cache()` uses shallow equality (`Object.is`) to determine cache hits. Inline objects create new references each call, preventing cache hits.

**Incorrect (always cache miss):**

```typescript
const getUser = cache(async (params: { uid: number }) => {
  return await db.user.findUnique({ where: { id: params.uid } })
})

// Each call creates new object, never hits cache
getUser({ uid: 1 })
getUser({ uid: 1 })  // Cache miss, runs query again
```

**Correct (cache hit):**

```typescript
const getUser = cache(async (uid: number) => {
  return await db.user.findUnique({ where: { id: uid } })
})

// Primitive args use value equality
getUser(1)
getUser(1)  // Cache hit, returns cached result
```

If you must pass objects, pass the same reference:

```typescript
const params = { uid: 1 }
getUser(params)  // Query runs
getUser(params)  // Cache hit (same reference)
```

**Next.js-Specific Note:**

In Next.js, the `fetch` API is automatically extended with request memoization. Requests with the same URL and options are automatically deduplicated within a single request, so you don't need `React.cache()` for `fetch` calls. However, `React.cache()` is still essential for other async tasks:

- Database queries (Prisma, Drizzle, etc.)
- Heavy computations
- Authentication checks
- File system operations
- Any non-fetch async work

Use `React.cache()` to deduplicate these operations across your component tree.

Reference: [React.cache documentation](https://react.dev/reference/react/cache)


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/server-dedup-props.md
================================================
---
title: Avoid Duplicate Serialization in RSC Props
impact: LOW
impactDescription: reduces network payload by avoiding duplicate serialization
tags: server, rsc, serialization, props, client-components
---

## Avoid Duplicate Serialization in RSC Props

**Impact: LOW (reduces network payload by avoiding duplicate serialization)**

RSC→client serialization deduplicates by object reference, not value. Same reference = serialized once; new reference = serialized again. Do transformations (`.toSorted()`, `.filter()`, `.map()`) in client, not server.

**Incorrect (duplicates array):**

```tsx
// RSC: sends 6 strings (2 arrays × 3 items)
<ClientList usernames={usernames} usernamesOrdered={usernames.toSorted()} />
```

**Correct (sends 3 strings):**

```tsx
// RSC: send once
<ClientList usernames={usernames} />

// Client: transform there
'use client'
const sorted = useMemo(() => [...usernames].sort(), [usernames])
```

**Nested deduplication behavior:**

Deduplication works recursively. Impact varies by data type:

- `string[]`, `number[]`, `boolean[]`: **HIGH impact** - array + all primitives fully duplicated
- `object[]`: **LOW impact** - array duplicated, but nested objects deduplicated by reference

```tsx
// string[] - duplicates everything
usernames={['a','b']} sorted={usernames.toSorted()} // sends 4 strings

// object[] - duplicates array structure only
users={[{id:1},{id:2}]} sorted={users.toSorted()} // sends 2 arrays + 2 unique objects (not 4)
```

**Operations breaking deduplication (create new references):**

- Arrays: `.toSorted()`, `.filter()`, `.map()`, `.slice()`, `[...arr]`
- Objects: `{...obj}`, `Object.assign()`, `structuredClone()`, `JSON.parse(JSON.stringify())`

**More examples:**

```tsx
// ❌ Bad
<C users={users} active={users.filter(u => u.active)} />
<C product={product} productName={product.name} />

// ✅ Good
<C users={users} />
<C product={product} />
// Do filtering/destructuring in client
```

**Exception:** Pass derived data when transformation is expensive or client doesn't need original.


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/server-parallel-fetching.md
================================================
---
title: Parallel Data Fetching with Component Composition
impact: CRITICAL
impactDescription: eliminates server-side waterfalls
tags: server, rsc, parallel-fetching, composition
---

## Parallel Data Fetching with Component Composition

React Server Components execute sequentially within a tree. Restructure with composition to parallelize data fetching.

**Incorrect (Sidebar waits for Page's fetch to complete):**

```tsx
export default async function Page() {
  const header = await fetchHeader()
  return (
    <div>
      <div>{header}</div>
      <Sidebar />
    </div>
  )
}

async function Sidebar() {
  const items = await fetchSidebarItems()
  return <nav>{items.map(renderItem)}</nav>
}
```

**Correct (both fetch simultaneously):**

```tsx
async function Header() {
  const data = await fetchHeader()
  return <div>{data}</div>
}

async function Sidebar() {
  const items = await fetchSidebarItems()
  return <nav>{items.map(renderItem)}</nav>
}

export default function Page() {
  return (
    <div>
      <Header />
      <Sidebar />
    </div>
  )
}
```

**Alternative with children prop:**

```tsx
async function Header() {
  const data = await fetchHeader()
  return <div>{data}</div>
}

async function Sidebar() {
  const items = await fetchSidebarItems()
  return <nav>{items.map(renderItem)}</nav>
}

function Layout({ children }: { children: ReactNode }) {
  return (
    <div>
      <Header />
      {children}
    </div>
  )
}

export default function Page() {
  return (
    <Layout>
      <Sidebar />
    </Layout>
  )
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/server-serialization.md
================================================
---
title: Minimize Serialization at RSC Boundaries
impact: HIGH
impactDescription: reduces data transfer size
tags: server, rsc, serialization, props
---

## Minimize Serialization at RSC Boundaries

The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.

**Incorrect (serializes all 50 fields):**

```tsx
async function Page() {
  const user = await fetchUser()  // 50 fields
  return <Profile user={user} />
}

'use client'
function Profile({ user }: { user: User }) {
  return <div>{user.name}</div>  // uses 1 field
}
```

**Correct (serializes only 1 field):**

```tsx
async function Page() {
  const user = await fetchUser()
  return <Profile name={user.name} />
}

'use client'
function Profile({ name }: { name: string }) {
  return <div>{name}</div>
}
```


================================================
FILE: .claude/skills/vercel-react-best-practices/rules/unused-detection.md
================================================
---
title: Unused Code Detection
impact: MEDIUM
impactDescription: reduces bundle size, improves maintainability, prevents confusion
tags: unused, dead-code, cleanup, maintenance
---

## Unused Code Detection

Identify and remove unused code to reduce bundle size, improve maintainability, and prevent developer confusion. No external tools required—use built-in IDE features and TypeScript compiler options.

### Detection Methods (No External Tools)

| Technique | How to Use |
|-----------|------------|
| Find All References | `Shift+F12` on any symbol - if only definition shows, it's unused |
| Grayed-out imports | IDE automatically dims unused imports |
| TypeScript errors | Enable `noUnusedLocals` and `noUnusedParameters` in tsconfig |
| Search codebase | Search for filename to find orphan files |

### tsconfig.json Settings (Built-in TypeScript)

```json
{
  "compilerOptions": {
    "noUnusedLocals": true,
    "noUnusedParameters": true
  }
}
```

---

## 1. Unused Exports (`unused-dead-exports`)

**Pattern**: Export exists but "Find All References" shows only the definition.

**Incorrect:**

```tsx
// utils.ts - helperFunction is never imported anywhere
export const formatDate = (date: Date) => date.toISOString()
export const helperFunction = () => { /* never used */ }
```

**Correct:**

```tsx
// utils.ts - only export what's actually used
export const formatDate = (date: Date) => date.toISOString()
// helperFunction removed or kept as non-exported if used internally
```

---

## 2. Unreachable Code (`unused-unreachable-code`)

**Pattern**: Code after return, throw, break, or continue statements.

**Incorrect:**

```tsx
function processData(data: Data | null) {
  if (!data) {
    return null
  }
  return data.value
  console.log('processed') // unreachable - never executes
  sendAnalytics('processed') // unreachable
}
```

**Correct:**

```tsx
function processData(data: Data | null) {
  if (!data) {
    return null
  }
  console.log('processed')
  sendAnalytics('processed')
  return data.value
}
```

---

## 3. Unused Variables (`unused-variables`)

**Pattern**: Variable assigned but never read.

**Incorrect:**

```tsx
const Component = ({ items }: Props) => {
  const result = expensiveCalculation(items) // assigned but never used
  const count = items.length // assigned but never used
  
  return <div>{items.map(item => <Item key={item.id} item={item} />)}</div>
}
```

**Correct:**

```tsx
const Component = ({ items }: Props) => {
  // Remove unused variables entirely
  return <div>{items.map(item => <Item key={item.id} item={item} />)}</div>
}
```

---

## 4. Unused Imports (`unused-imports`)

**Pattern**: Import statement with no references in file. IDE typically grays these out.

**Incorrect:**

```tsx
import { useState, useEffect, useCallback } from 'react' // useCallback never used
import { Button, Card, Modal } from '@/components' // Modal never used

const Component = () => {
  const [count, setCount] = useState(0)
  
  useEffect(() => {
    console.log(count)
  }, [count])
  
  return <Card><Button onClick={() => setCount(c => c + 1)}>{count}</Button></Card>
}
```

**Correct:**

```tsx
import { useState, useEffect } from 'react'
import { Button, Card } from '@/components'

const Component = () => {
  const [count, setCount] = useState(0)
  
  useEffect(() => {
    console.log(count)
  }, [count])
  
  return <Card><Button onClick={() => setCount(c => c + 1)}>{count}</Button></Card>
}
```

---

## 5. Unused Components (`unused-components`)

**Pattern**: Component defined but never rendered anywhere in the app.

**Detection**: Search the codebase for `<ComponentName` - if no results, it's unused.

**Incorrect:**

```tsx
// components/LegacyBanner.tsx - file exists but component never used
export const LegacyBanner = () => {
  return <div className="banner">Old feature announcement</div>
}
```

**Correct:**

```tsx
// Delete the file entirely, or if keeping for reference:
// Move to a /deprecated folder with a TODO comment
```

---

## 6. Unused Props (`unused-props`)

**Pattern**: Props destructured but never referenced in component body.

**Incorrect:**

```tsx
interface ButtonProps {
  label: string
  isLoading: boolean // passed to component but never used
  onClick: () => void
  variant: 'primary' | 'secondary' // defined but never used
}

const Button = ({ label, isLoading, onClick, variant }: ButtonProps) => {
  return <button onClick={onClick}>{label}</button>
}
```

**Correct:**

```tsx
interface ButtonProps {
  label: string
  onClick: () => void
}

const Button = ({ label, onClick }: ButtonProps) => {
  return <button onClick={onClick}>{label}</button>
}
```

---

## 7. Unused State (`unused-state`)

**Pattern**: useState where value is set but never read, or setter is never called.

**Incorrect:**

```tsx
const Component = () => {
  const [count, setCount] = useState(0) // count is set but never displayed
  const [isOpen, setIsOpen] = useState(false) // setIsOpen is never called
  
  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>Increment</button>
      {isOpen && <Modal />}
    </div>
  )
}
```

**Correct:**

```tsx
const Component = () => {
  const [count, setCount] = useState(0)
  
  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
    </div>
  )
}
```

---

## 8. Unused Effects (`unused-effects`)

**Pattern**: useEffect that doesn't cause observable side effects or set state.

**Incorrect:**

```tsx
const Component = ({ data }: Props) => {
  useEffect(() => {
    // Effect that does nothing observable
    const processed = data.map(item => item.value)
    console.log(processed) // only logs, no state change or side effect
  }, [data])
  
  return <div>{data.length} items</div>
}
```

**Correct:**

```tsx
const Component = ({ data }: Props) => {
  // Remove the effect if it has no purpose
  // Or make it actually do something:
  useEffect(() => {
    analytics.track('data_loaded', { count: data.length })
  }, [data])
  
  return <div>{data.length} items</div>
}
```

---

## 9. Commented-Out Code (`unused-commented-code`)

**Pattern**: Large blocks of commented code. Git preserves history—delete it.

**Incorrect:**

```tsx
const Component = () => {
  // const [oldState, setOldState] = useState(null)
  // 
  // useEffect(() => {
  //   fetchOldData().then(setOldState)
  // }, [])
  //
  // if (oldState) {
  //   return <OldComponent data={oldState} />
  // }
  
  return <NewComponent />
}
```

**Correct:**

```tsx
const Component = () => {
  return <NewComponent />
}
// If needed for reference, check git history: git log -p -- path/to/file.tsx
```

---

## Code Review Checklist

When reviewing code for unused items:

- [ ] Every export has at least one import (use Find All References)
- [ ] Every import is used in the file (check for grayed-out imports)
- [ ] Every prop is used in the component body
- [ ] Every useState value is read somewhere in render or effects
- [ ] Every useState setter is called somewhere
- [ ] No code exists after return/throw/break/continue
- [ ] No large commented-out code blocks
- [ ] No files that are never imported (search for filename)

---

## Finding Unused Files

To find potentially orphan files without external tools:

1. **Search for the filename** (without extension) across the codebase
2. **Check dynamic imports**: Search for `import(` and `lazy(` patterns
3. **Check route configs**: Files may be referenced in routing configuration
4. **Check package.json**: Entry points like `main`, `exports`, `bin`

```bash
# Search for references to a file
# In IDE: Cmd+Shift+F and search for "ComponentName" or "filename"
```

This approach relies entirely on built-in TypeScript, IDE features, and manual inspection.


================================================
FILE: .eslintrc.json
================================================
{
  "extends": [
    "next/core-web-vitals",
    "plugin:storybook/recommended"
  ],
  "plugins": [
    "no-conditional-literals-in-jsx"
  ],
  "rules": {
    "no-conditional-literals-in-jsx/no-conditional-literals-in-jsx": "error",
    "no-conditional-literals-in-jsx/no-unwrapped-jsx-text": "error",
    "react-hooks/exhaustive-deps": "off",
    "react/display-name": "off"
  }
}

================================================
FILE: .github/workflows/chromatic.yml
================================================
# .github/workflows/chromatic.yml

# Workflow name
name: 'Chromatic'

# Event for the workflow
on: push

# List of jobs
jobs:
  chromatic-deployment:
    # Operating System
    runs-on: ubuntu-latest
    # Job steps
    steps:
      - uses: actions/checkout@v1
      - name: Install dependencies
        # 👇 Install dependencies with the same package manager used in the project (replace it as needed), e.g. yarn, npm, pnpm
        run: yarn
        # 👇 Adds Chromatic as a step in the workflow
      - name: Publish to Chromatic
        uses: chromaui/action@v1
        # Chromatic GitHub Action options
        with:
          # 👇 Chromatic projectToken, refer to the manage page to obtain it.
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

================================================
FILE: .github/workflows/deploy.yml
================================================
name: Storybook PR Preview

on:
  pull_request:
    types: [opened, synchronize, reopened]
    branches: ["**"]

permissions:
  contents: write
  pull-requests: write 

concurrency:
  group: "pr-preview-${{ github.ref }}"
  cancel-in-progress: true

jobs:
  preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4 
        with:
          node-version: 20
          cache: yarn
      - run: yarn install --frozen-lockfile --ignore-engines
      - run: yarn build-storybook

      # Publishes to: https://<owner>.github.io/<repo>/pr-preview/pr-<PR_NUMBER>/
      - name: Deploy PR Preview to Pages
        id: preview
        uses: rossjrw/pr-preview-action@v1
        with:
          source-dir: storybook-static
          umbrella-dir: pr-preview
          comment: false  # we'll post our own comment below

      - name: Comment preview link on PR (sticky)
        if: steps.preview.outputs.deployment-action == 'deploy'
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: storybook-preview
          message: |
            🚀 **Storybook preview:** ${{ steps.preview.outputs.preview-url }}

      # Make the link visible in the job summary
      - name: Show Preview URL
        if: always()
        run: |
          echo "Preview: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr-preview/pr-${{ github.event.pull_request.number }}/" >> $GITHUB_STEP_SUMMARY


================================================
FILE: .github/workflows/rebase-main-sandbox.yml
================================================
name: Main to main-sandbox
on: 
  push:
    branches: [main]
permissions:
  contents: write
jobs:
  rebase-main-sandbox:
    timeout-minutes: 2
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set Git config
      run: |
          git config --local user.email "actions@github.com"
          git config --local user.name "Github Actions"
    - name: Merge main to main-sandbox
      run: |
          git fetch --unshallow
          git checkout main-sandbox
          git rebase main 
          git push


================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
*node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
.vercel

# Moving to yarn
package-lock.json
storybook-static/*
# Sentry Config File
.sentryclirc
.env*.local

# typescript
*.tsbuildinfo
next-env.d.ts

# PR Review Report
pr-review-report.md 

================================================
FILE: .storybook/main.ts
================================================
import { createRequire } from "node:module";
import type { StorybookConfig } from "@storybook/nextjs";
import path, { dirname, join } from "path";

const require = createRequire(import.meta.url);

const config: StorybookConfig = {
  env: () => ({
    NEXT_PUBLIC_LS_BRIDGE_API: "https://bridge-api-dev.layerswap.cloud",
    NEXT_PUBLIC_IDENTITY_API: "/",
    NEXT_PUBLIC_RESOURCE_STORAGE_URL: "https://devlslayerswapbridgesa.blob.core.windows.net",
    NEXT_PUBLIC_LS_API: "https://api-dev.layerswap.cloud",
    NEXT_PUBLIC_API_KEY: "sandbox",
    NEXT_PUBLIC_API_VERSION: "sandbox"
  }),

  stories: [
    "../stories/**/*.mdx",
    "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
  ],

  addons: [
    getAbsolutePath("@storybook/addon-links"),
    getAbsolutePath("@storybook/addon-onboarding"),
    getAbsolutePath("storybook-addon-mock"),
    getAbsolutePath("@storybook/addon-docs")
  ],

  framework: {
    name: getAbsolutePath("@storybook/nextjs"),
    options: {},
  },

  webpackFinal: async (config) => {
    config.module?.rules?.push({
      test: /\.scss$/,
      use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"],
    });

    if (config.resolve) {
      config.resolve.alias = {
        ...config.resolve.alias,
        '@': path.resolve(__dirname, '../'),
      };
    }

    return config;
  }
};
export default config;

function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, "package.json")));
}


================================================
FILE: .storybook/manager.js
================================================
import { addons } from 'storybook/manager-api';
import { themes } from 'storybook/theming';

addons.setConfig({
    theme: themes.dark,
});

================================================
FILE: .storybook/preview.ts
================================================
import type { Preview } from "@storybook/nextjs";
import "../styles/globals.css";
import { themes } from 'storybook/theming';

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
};

const preview: Preview = {
  loaders: [
    async () => {
      const response = await fetch(`https://api-dev.layerswap.cloud/api/v2/networks`, {
        headers: {
          'X-LS-APIKEY': "sandbox"
        }
      });
      const settings = await response.json();
      return { settings };
    },
  ],
  parameters: {
    docs: {
      theme: themes.dark,
    },
    actions: { argTypesRegex: "^on[A-Z].*" },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/,
      },
    },
  },
};

export default preview;


================================================
FILE: .vscode/launch.json
================================================
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run debug"
    },
    {
      "name": "Next.js: debug client-side",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000"
    },
    {
      "name": "Next.js: debug full stack",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run debug",
      "serverReadyAction": {
        "pattern": "started server on .+, url: (https?://.+)",
        "uriFormat": "%s",
        "action": "debugWithChrome"
      }
    }
  ],
  "tasks": [
    {
      "type": "npm",
      "script": "errors",
      "problemMatcher": "$tsc-watch",
      "isBackground": true,
      "presentation": {
        "revealProblems": "never"
      }
    }
  ]
}

================================================
FILE: .vscode/settings.json
================================================
{
    "files.associations": {
        "*.css": "tailwindcss"
    }
}

================================================
FILE: AGENTS.md
================================================
# AGENTS.md - Project Instructions for OpenAI Codex

This file provides instructions for OpenAI Codex users to leverage the project's agent tooling located in `.cursor/`.

## Project Overview

Layerswap UI - A Next.js web application for cross-chain token transfers.

### Quick Start

```bash
yarn
yarn dev
```

### Environment Variables

```yaml
NEXT_PUBLIC_LS_API = https://api-dev.layerswap.cloud/
NEXT_PUBLIC_API_KEY = mainnet  # sandbox for testnets
```

---

## Agent Tooling

This project has specialized agent tooling for common workflows. Before performing these tasks, read the relevant instruction files.

### PR Review System

We have a multi-perspective PR review system with 6 specialized reviewers.

#### Comprehensive Review (Recommended)

For thorough, multi-perspective code reviews, read and follow:

```
.cursor/agents/pr-review-coordinator.md
```

This orchestrates 6 specialized reviewers in parallel:

| Reviewer | File | Focus Area |
|----------|------|------------|
| Architecture | `.cursor/agents/pr-reviewer-architecture.md` | SOLID principles, design patterns, modularity |
| Bugs | `.cursor/agents/pr-reviewer-bugs.md` | Edge cases, null checks, race conditions, cross-file impact |
| Performance | `.cursor/agents/pr-reviewer-performance.md` | N+1 queries, memory leaks, caching, bundle size |
| Quality | `.cursor/agents/pr-reviewer-quality.md` | Naming, readability, DRY, maintainability |
| React | `.cursor/agents/pr-reviewer-react.md` | Hooks, re-renders, state management, a11y, Next.js |
| Security | `.cursor/agents/pr-reviewer-security.md` | Auth, XSS, injection, secrets, CORS |

#### Quick Review

For a single focused review, read and follow:

```
.cursor/agents/pr-reviewer.md
```

---

## Commands Reference

These commands mirror the Cursor IDE commands available in `.cursor/commands/`.

### Review Changes

When asked to "review my changes" or "review this PR":

1. Read `.cursor/commands/reviewchanges.md` for the workflow
2. Follow the instructions to run the appropriate review

**Available review types**:
- `comprehensive` - Full multi-perspective review (default)
- `quick` - Single specialist review
- `explore` - Codebase exploration
- `general` - General purpose analysis

**Output**: Creates `pr-review-report.md` with:
- TL;DR section with verdict and action items
- Effort estimates for each fix
- Blocking vs non-blocking classification
- Copy-paste ready code fixes

---

## Skills Reference

### React & Next.js Best Practices

When writing, reviewing, or refactoring React/Next.js code, reference:

```
.cursor/skills/vercel-react-best-practices/SKILL.md
```

This contains 45+ performance optimization rules organized by priority:

| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Eliminating Waterfalls | CRITICAL | `async-` |
| 2 | Bundle Size Optimization | CRITICAL | `bundle-` |
| 3 | Server-Side Performance | HIGH | `server-` |
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | `client-` |
| 5 | Re-render Optimization | MEDIUM | `rerender-` |
| 6 | Rendering Performance | MEDIUM | `rendering-` |
| 7 | Unused Code Detection | MEDIUM | `unused-` |
| 8 | JavaScript Performance | LOW-MEDIUM | `js-` |
| 9 | Advanced Patterns | LOW | `advanced-` |

Individual rules are in `.cursor/skills/vercel-react-best-practices/rules/`.

**Key rules to check**:
- `async-parallel.md` - Use Promise.all() for independent operations
- `bundle-barrel-imports.md` - Import directly, avoid barrel files
- `bundle-dynamic-imports.md` - Use next/dynamic for heavy components
- `rerender-memo.md` - Extract expensive work into memoized components

---

## Project Structure

```
components/     # React components (284 .tsx files)
context/        # React context providers
hooks/          # Custom React hooks
lib/            # Utilities and libraries
Models/         # TypeScript interfaces and types
pages/          # Next.js pages
stores/         # State management (Zustand)
styles/         # CSS styles
```

---

## Common Tasks

### "Review my changes"

1. Read `.cursor/commands/reviewchanges.md`
2. Follow the comprehensive review workflow
3. Output findings to `pr-review-report.md`

### "Review this PR for [specific concern]"

Read the relevant specialist file:
- Security concerns → `.cursor/agents/pr-reviewer-security.md`
- Performance issues → `.cursor/agents/pr-reviewer-performance.md`
- React patterns → `.cursor/agents/pr-reviewer-react.md`
- Bug detection → `.cursor/agents/pr-reviewer-bugs.md`
- Architecture → `.cursor/agents/pr-reviewer-architecture.md`
- Code quality → `.cursor/agents/pr-reviewer-quality.md`

### "Help me optimize this React component"

1. Read `.cursor/skills/vercel-react-best-practices/SKILL.md`
2. Apply relevant rules from the `rules/` directory
3. Focus on `rerender-*` and `rendering-*` rules for component optimization

### "Check for performance issues"

1. Read `.cursor/agents/pr-reviewer-performance.md`
2. Also reference `.cursor/skills/vercel-react-best-practices/rules/` for:
   - `bundle-*.md` rules
   - `async-*.md` rules
   - `js-*.md` rules

---

## Guidelines

- Always read the full file context, not just diffs
- Provide copy-paste ready code fixes
- Include effort estimates for fixes
- Distinguish blocking issues from suggestions
- Follow the output formats specified in agent files


================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Layerswap UI — a Next.js 15 web application (Pages Router) for cross-chain token swaps across 9+ blockchain networks (EVM, Solana, Starknet, TON, TRON, Fuel, Bitcoin, Cosmos, ZkSync).

## Commands

```bash
yarn              # Install dependencies
yarn dev          # Start dev server
yarn build        # Production build
yarn lint         # ESLint (next/core-web-vitals + custom JSX literal plugin)
yarn storybook    # Component docs on port 6006
ANALYZE=true yarn build  # Bundle analysis
```

No unit test framework is configured. Storybook is used for component documentation.

## Environment Variables

```bash
NEXT_PUBLIC_LS_API=https://api-dev.layerswap.cloud/   # API base URL
NEXT_PUBLIC_API_KEY=mainnet                            # "sandbox" for testnets
```

Production uses `https://api.layerswap.io` with additional env vars for identity API, Immutable, WalletConnect, and PostHog (see `.env`).

## Architecture

### Data Flow

1. **Server-side**: `getServerSideProps` in `helpers/getSettings.ts` fetches networks, exchanges, and routes via `LayerSwapApiClient`, compresses them with `settingsCompression`, and passes as page props
2. **Client-side**: Settings are inflated and pre-populated into SWR cache as fallback data. SWR handles subsequent client-side data fetching (5s dedup, no revalidation on focus)
3. **State**: Zustand stores for wallet state, balances, slippage, routes, and transactions. React Context for swap flow, settings, form wizard, validation, and wallet providers

### Key Architectural Patterns

- **Pages Router** (not App Router) — routes are in `pages/`, SSR via `getServerSideProps`
- **Hybrid state**: Zustand for persistent/global state (10 stores in `stores/`), React Context for component-tree-scoped state (13 contexts in `context/`)
- **Multi-chain wallet abstraction**: `lib/wallets/` contains adapters for each chain type, unified through `WalletProvider` model and `walletStore`
- **API client**: `lib/apiClients/layerSwapApiClient.ts` — Axios-based with auth interceptors, retry logic, and PostHog error tracking
- **SWR fallback pattern**: Server-fetched data is injected into SWR cache at page level, enabling instant renders with background revalidation
- **Settings compression**: Large settings objects are compressed for SSR transfer (`helpers/settingsCompression.ts`)
- **Path alias**: `@/*` maps to project root

### Network Types

Defined in `Models/Network.ts` as `NetworkType` enum: EVM, Starknet, Solana, Cosmos, StarkEx, ZkSyncLite, TON, Fuel, Bitcoin. Each has chain-specific wallet adapters, balance resolvers, and gas estimators in `lib/`.

### Key Entry Points

- `pages/_app.js` — Root: SWRConfig, PostHog, Intercom providers
- `pages/index.tsx` — Home: inflates settings, sets up SWR fallback, renders `<Layout>` + `<Swap>`
- `components/layout.tsx` — Layout wrapper with settings/query/wallet providers
- `components/swapComponent.tsx` — Main swap interface orchestrator

## Linting Rules

- **Custom ESLint plugin** `no-conditional-literals-in-jsx`: prevents conditional literals and unwrapped text in JSX (both set to `error`)
- `react-hooks/exhaustive-deps` is **disabled**
- `react/display-name` is **disabled**

## Project Structure

```
components/     # React components (~284 .tsx files)
context/        # React context providers (swap, settings, wallet, wizard, validation, etc.)
hooks/          # Custom React hooks (useWallet, useFee, useFormRoutes, etc.)
helpers/        # Utility functions (settings, balances, routes, tokens)
lib/            # API clients, wallet adapters, balance resolvers, gas estimators
  ├── apiClients/   # LayerSwap API, JSON-RPC, Hyperliquid clients
  ├── wallets/      # Per-chain wallet integrations
  ├── balances/     # Per-chain balance fetchers
  └── gas/          # Per-chain gas estimation
Models/         # TypeScript interfaces (Network, Token, Route, Exchange, SwapStatus, etc.)
pages/          # Next.js pages (index, swap/[swapId], transactions, campaigns)
stores/         # Zustand stores (wallet, balance, slippage, routes, transactions)
styles/         # Global CSS
stories/        # Storybook stories
```

## Key Dependencies

| Category | Libraries |
|----------|-----------|
| Framework | Next.js 15, React 18, TypeScript 5 |
| Styling | Tailwind CSS v4, Framer Motion, Headless UI, Radix UI |
| State | Zustand, SWR, React Query, Formik |
| EVM | wagmi, viem, ethers v5 |
| Solana | @solana/web3.js, wallet-adapter-react |
| Starknet | starknet v8, @starknet-react/core, starknetkit |
| Other chains | @ton/ton, @tronweb3/*, @fuel-ts/*, @imtbl/sdk, @paradex/sdk |
| Analytics | PostHog |

## PR Review System

This project includes specialized review tooling in `.cursor/agents/`. For comprehensive reviews, read `.cursor/agents/pr-review-coordinator.md` which orchestrates 6 parallel reviewers (architecture, bugs, performance, quality, react, security). For quick single-perspective reviews, use `.cursor/agents/pr-reviewer.md`.

Review workflow: read `.cursor/commands/reviewchanges.md`, output findings to `pr-review-report.md`.

## React Performance Rules

`.cursor/skills/vercel-react-best-practices/SKILL.md` contains 45+ optimization rules. Key ones:
- `async-parallel.md` — Use `Promise.all()` for independent operations
- `bundle-barrel-imports.md` — Import directly, avoid barrel files
- `bundle-dynamic-imports.md` — Use `next/dynamic` for heavy components
- `rerender-memo.md` — Extract expensive work into memoized components


================================================
FILE: Models/ApiError.ts
================================================
export type ApiError = {
    code: LSAPIKnownErrorCode | string,
    message: string;
    metadata: {
        AvailableTransactionAmount: number
        RemainingLimitPeriod: string
        ActivationUrl: string
    }
}

export enum LSAPIKnownErrorCode {
    NOT_FOUND = "NOT_FOUND",
    INVALID_CREDENTIALS = "INVALID_CREDENTIALS",
    INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS",
    FUNDS_ON_HOLD = "FUNDS_ON_HOLD_ERROR",
    COINBASE_AUTHORIZATION_LIMIT_EXCEEDED = "COINBASE_AUTHORIZATION_LIMIT_EXCEEDED",
    COINBASE_INVALID_2FA = "COINBASE_INVALID_2FA",
    ACTIVE_SWAP_LIMIT_EXCEEDED = "ACTIVE_SWAP_LIMIT_EXCEEDED",
    NETWORK_ACCOUNT_ALREADY_EXISTS = "NETWORK_ACCOUNT_ALREADY_EXISTS",
    BLACKLISTED_ADDRESS = "BLACKLISTED_ADDRESS",
    INVALID_ADDRESS_ERROR = "INVALID_ADDRESS_ERROR",
    UNACTIVATED_ADDRESS_ERROR = "UNACTIVATED_ADDRESS_ERROR",
    NETWORK_CURRENCY_DAILY_LIMIT_REACHED = "NETWORK_CURRENCY_DAILY_LIMIT_REACHED",
    ROUTE_NOT_FOUND_ERROR = "ROUTE_NOT_FOUND_ERROR"
}

================================================
FILE: Models/ApiResponse.ts
================================================
import { ApiError } from "./ApiError";

export class EmptyApiResponse {
    constructor(error?: ApiError) {
        this.error = error;
    }

    error?: ApiError;
}

export class ApiResponse<T> extends EmptyApiResponse {
    data?: T
}


================================================
FILE: Models/Balance.ts
================================================
import { Network, Token } from "./Network"
import { Wallet } from "./WalletProvider"
import { NodeErrorCategory } from "@/lib/balances/nodeErrorClassifier"

export type GasProps = {
    network: Network,
    token: Token,
    address?: string,
    recipientAddress?: string,
    wallet?: Wallet,
    amount?: number,
}

export type TokenBalanceError = {
    message: string;
    name?: string;
    stack?: string;
    code?: string;
    status?: number;
    statusText?: string;
    responseData?: unknown;
    requestUrl?: string;
    category?: NodeErrorCategory;
}

export type TokenBalance = {
    network: string,
    amount: number | undefined,
    decimals: number,
    isNativeCurrency: boolean,
    token: string,
    request_time: string,
    error?: TokenBalanceError
}

export type NetworkBalance = {
    balances?: TokenBalance[] | null,
}

================================================
FILE: Models/BalanceProvider.ts
================================================
import posthog from "posthog-js";
import { TokenBalance } from "./Balance";
import { Network, NetworkWithTokens, Token } from "./Network";
import { extractErrorDetails } from "@/lib/balances/errorUtils";
import { classifyNodeError } from "@/lib/balances/nodeErrorClassifier";

export abstract class BalanceProvider {
    abstract supportsNetwork: (network: NetworkWithTokens) => boolean
    abstract fetchBalance: (address: string, network: NetworkWithTokens, options?: { timeoutMs?: number, retryCount?: number }) => Promise<TokenBalance[] | null | undefined>
    protected resolveTokenBalanceFetchError = (err: Error, token: Token, network: Network, isNativeCurrency?: boolean) => {
        console.error("balance_fetch_error", network.name, err)
        
        const errorDetails = extractErrorDetails(err);
        const category = classifyNodeError(err);
        
        const tokenBalance: TokenBalance = {
            network: network.name,
            token: token.symbol,
            amount: undefined,
            request_time: new Date().toJSON(),
            decimals: Number(token?.decimals),
            isNativeCurrency: isNativeCurrency ?? !token.contract,
            error: {
                message: errorDetails.message,
                name: errorDetails.name,
                stack: errorDetails.stack,
                code: errorDetails.code,
                status: errorDetails.status,
                statusText: errorDetails.statusText,
                responseData: errorDetails.responseData,
                requestUrl: errorDetails.requestUrl,
                category: category
            }
        }

        return tokenBalance
    }
}


================================================
FILE: Models/Exchange.ts
================================================
import { Network, Token } from "./Network";

export class Exchange {
    display_name: string;
    name: string;
    logo: string;
    metadata: {
        o_auth: {
            connect_url: string,
            authorize_url: string
        } | null
    }
}

export class ExchangeNetwork {
    token: Token;
    network: Network;
    fee: {
        total_fee: number;
        total_fee_in_usd: number
    }
}

================================================
FILE: Models/LayerSwapAppSettings.ts
================================================
import { NetworkWithTokens, NetworkRoute } from "./Network";
import { Exchange } from "./Exchange";
import { LayerSwapSettings } from "./LayerSwapSettings";

export class LayerSwapAppSettings {
    constructor(settings: LayerSwapSettings) {

        this.networks = settings.networks;
        this.sourceExchanges = settings.sourceExchanges || [];

        this.sourceRoutes = settings.sourceRoutes || []
        this.destinationRoutes = settings.destinationRoutes || []
    }

    sourceExchanges: Exchange[]

    networks: NetworkWithTokens[]
    sourceRoutes: NetworkRoute[]
    destinationRoutes: NetworkRoute[]

}


================================================
FILE: Models/LayerSwapAuth.ts
================================================
export class AuthGetCodeResponse {
    data: {
        next: Date,
        already_sent: boolean
    };
    error: string;
}

================================================
FILE: Models/LayerSwapSettings.ts
================================================
import { NetworkWithTokens, NetworkRoute } from "./Network";
import { Exchange } from "./Exchange";

export class LayerSwapSettings {
    sourceExchanges?: Exchange[];
    networks: NetworkWithTokens[];
    sourceRoutes?: NetworkRoute[];
    destinationRoutes?: NetworkRoute[];
};

================================================
FILE: Models/Network.ts
================================================
import { Refuel } from "../lib/apiClients/layerSwapApiClient";

export enum NetworkType {
    EVM = "evm",
    Starknet = "starknet",
    Solana = "solana",
    Cosmos = "cosmos",
    StarkEx = "starkex",//TODO check this
    ZkSyncLite = "zksynclite",
    TON = 'ton',
    Fuel = 'fuel',
    Bitcoin = 'bitcoin',
}

export class Network {
    name: string;
    display_name: string;
    logo: string;
    chain_id: string | null;
    node_url: string;
    nodes: string[];
    type: NetworkType;
    transaction_explorer_template: string;
    account_explorer_template: string;
    metadata?: Metadata;
    deposit_methods: string[]
    token?: Token
    source_rank?: number | undefined;
    destination_rank?: number | undefined;
}

export class NetworkWithTokens extends Network {
    tokens: Token[];
}

export class NetworkRoute extends Network {
    tokens: NetworkRouteToken[]
}

export class Token {
    symbol: string;
    display_asset?: string
    logo: string;
    //TODO may be plain string
    contract: string | null | undefined;
    decimals: number;
    price_in_usd: number;
    precision: number;
    listing_date: string;
    status?: 'active' | 'inactive' | 'not_found';
    source_rank?: number | undefined;
    destination_rank?: number | undefined;
}

export class NetworkRouteToken extends Token {
    refuel?: Refuel
}

export class Metadata {
    evm_oracle_contract?: `0x${string}` | null
    evm_multicall_contract?: string | null
    listing_date: string
    zks_paymaster_contract?: `0x${string}` | null
    watchdog_contract?: string | null
}

================================================
FILE: Models/Partner.ts
================================================
export class Partner {
    display_name: string;
    logo: string;
    is_wallet: boolean;
    id: number;
    client_id: string
}

================================================
FILE: Models/QueryParams.ts
================================================

export class PersistantQueryParams {
    from?: string = "";
    to?: string = "";
    fromExchange?: string = "";
    lockFrom?: boolean = false;
    lockTo?: boolean = false;

    lockFromAsset?: boolean = false;
    lockToAsset?: boolean = false;
    destination_address?: string = "";
    fromAsset?: string = "";
    toAsset?: string = "";
    hideRefuel?: boolean = false;
    hideAddress?: boolean = false;
    hideFrom?: boolean = false;
    hideTo?: boolean = false;
    amount?: string = "";
    externalId?: string = ""
    signature?: string = "";
    timestamp?: string = "";
    apiKey?: string = "";
    balances?: string = "";
    account?: string = "";
    actionButtonText?: string = "";
    theme?: string = "";
    appName?: string = "";
    depositMethod?: string = "";
    hideDepositMethod?: boolean = false;
    hideLogo?: boolean = false
    sameAccountNetwork?: string = "";
    lockAddress?: boolean = false;
    clientId?: string = "";
    defaultTab?: string = "";

    // Obsolate
    sourceExchangeName?: string = "";
    destNetwork?: string = "";
    lockNetwork?: boolean = false;
    lockExchange?: boolean = false;
    addressSource?: string = "";
    asset?: string = "";
    lockAsset?: boolean = false;
    destAddress?: string = "";

}


export class QueryParams extends PersistantQueryParams {
    coinbase_redirect?: string = "";
}

================================================
FILE: Models/RangeError.ts
================================================
export enum SwapFailReasons {
    RECEIVED_LESS_THAN_VALID_RANGE = "received_less_than_valid_range",
    RECEIVED_MORE_THAN_VALID_RANGE = "received_more_than_valid_range"
}

================================================
FILE: Models/Route.ts
================================================
import { Exchange } from "./Exchange";
import { NetworkRouteToken, NetworkRoute } from "./Network";

export type NetworkElement = {
    type: 'network';
    route: NetworkRoute;
}
export type NetworkTokenElement = {
    type: 'network_token' | 'suggested_token';
    route: {
        token: NetworkRouteToken;
        route: NetworkRoute
    }
}
export type TitleElement = {
    type: 'group_title';
    text: string
}
export type GroupedTokenElement = {
    type: 'grouped_token';
    symbol: string;
    items: NetworkTokenElement[];
}
export type TokenSceletonElement = {
    type: 'sceleton_token';
}
export type RowElement = {}
    & (NetworkElement
        | NetworkTokenElement
        | TitleElement
        | GroupedTokenElement
        | TokenSceletonElement);


================================================
FILE: Models/SwapStatus.ts
================================================
export enum SwapStatus {
    Created = 'created',
    
    UserTransferPending= 'user_transfer_pending',
    UserTransferDelayed = 'user_transfer_delayed',
    LsTransferPending = "ls_transfer_pending",

    Completed = 'completed',
    Failed = 'failed',
    Expired = "expired",
    Cancelled = "cancelled",
    PendingRefund = "pending_refund",
    Refunded = "refunded",
}

================================================
FILE: Models/Theme.ts
================================================
import { HTMLAttributes } from "react"

export type ThemeData = {
    buttonTextColor?: string,
    logo?: string,
    tertiary?: string,
    primary?: ThemeColor,
    secondary?: ThemeColor,
    headerLogo?: string,
    footerLogo?: string,
    footerLogoHeight?: string,
    warning?: StatusColor,
    error?: StatusColor,
    success?: StatusColor,
    header?: {
        hideMenu?: boolean,
        hideTabs?: boolean,
        hideWallets?: boolean,
    }
    cardBackgroundStyle?: HTMLAttributes<HTMLDivElement>['style']
}

export type ThemeColor = {
    DEFAULT: string;
    100: string;
    200: string;
    300: string;
    400: string;
    500: string;
    600: string;
    700: string;
    800: string;
    900: string;
    text: string,
}

export type StatusColor = {
    Foreground: string;
    Background: string;
}

export const THEME_COLORS: { [key: string]: ThemeData } = {
    "imxMarketplace": {
        buttonTextColor: '255, 255, 255',
        tertiary: '140, 152, 192',
        logo: '255, 255, 255',
        footerLogo: 'none',
        primary: {
            DEFAULT: '46, 236, 255',
            '100': '209, 251, 255',
            '200': '168, 247, 255',
            '300': '128, 243, 255',
            '400': '87, 240, 255',
            '500': '46, 236, 255',
            '600': '0, 232, 255',
            '700': '0, 172, 189',
            '800': '0, 121, 133',
            '900': '0, 70, 77',
            'text': '255, 255, 255',
        },
        secondary: {
            DEFAULT: '17, 29, 54',
            '100': '46, 59, 147',
            '200': '35, 42, 112',
            '300': '32, 41, 101',
            '400': '28, 39, 89',
            '500': '22, 37, 70',
            '600': '20, 33, 62',
            '700': '17, 29, 54',
            '800': '15, 25, 47',
            '900': '12, 21, 39',
            'text': '209, 251, 255',
        },
    },
    "light": {
        tertiary: '134, 134, 134',
        buttonTextColor: '17, 17, 17',
        logo: '255, 0, 147',
        footerLogo: 'none',
        primary: {
            DEFAULT: '228, 37, 117',
            '100': '246, 182, 209',
            '200': '241, 146, 186',
            '300': '237, 110, 163',
            '400': '232, 73, 140',
            '500': '228, 37, 117',
            '600': '166, 51, 94',
            '700': '136, 17, 67',
            '800': '147, 8, 99',
            '900': '196, 153, 175',
            'text': '17, 17, 17',
        },
        secondary: {
            DEFAULT: '240, 240, 240',
            '100': '46, 59, 147',
            '200': '134, 134, 134',
            '300': '139, 139, 139',
            '400': '177, 177, 177',
            '500': '218, 218, 218',
            '600': '223, 223, 223',
            '700': '240, 240, 240',
            '800': '243, 244, 246',
            '900': '250, 248, 248',
            'text': '108, 108, 108',
        },
    },
    "default": {
        tertiary: '118, 128, 147',
        buttonTextColor: '228, 229, 240',
        logo: '255, 0, 147',
        footerLogo: 'none',
        warning: {
            Foreground: '255, 201, 74',
            Background: '47, 43, 29',
        },
        error: {
            Foreground: '255, 97, 97',
            Background: '46, 27, 27',
        },
        success: {
            Foreground: '89, 224, 125',
            Background: '14, 43, 22',
        },
        primary: {
            DEFAULT: '204, 45, 93',
            '100': '255, 148, 176',
            '200': '245, 103, 141',
            '300': '235, 84, 129',
            '400': '229, 64, 114',
            '500': '204, 45, 93',
            '600': '178, 29, 74',
            '700': ' 143, 23, 59',
            '800': '89, 14, 37',
            '900': '46, 7, 19',
            'text': '225, 227, 230',
        },
        secondary: {
            DEFAULT: '17, 29, 54',
            '100': '60, 72, 97',
            '200': '52, 63, 87',
            '300': '40, 50, 71',
            '400': '31, 40, 61',
            '500': '23, 31, 49',
            '600': '18, 25, 41',
            '700': '14, 21, 36',
            '800': '11, 17, 31',
            '900': '7, 12, 23',
            'text': '163, 173, 194',
        },
    },
    "halloween": {
        tertiary: "110, 80, 140",
        buttonTextColor: "255, 240, 200",
        logo: '255, 0, 147',
        footerLogo: "none",
        warning: {
            Foreground: "255, 180, 70",
            Background: "45, 30, 10",
        },
        error: {
            Foreground: "255, 90, 90",
            Background: "40, 15, 15",
        },
        success: {
            Foreground: "150, 255, 180",
            Background: "20, 40, 25",
        },
        primary: {
            DEFAULT: "230, 80, 25",
            "100": "255, 180, 120",
            "200": "255, 150, 70",
            "300": "255, 120, 50",
            "400": "255, 100, 30",
            "500": "230, 80, 25",
            "600": "190, 60, 20",
            "700": "150, 45, 15",
            "800": "100, 30, 10",
            "900": "50, 15, 5",
            "text": "255, 240, 200",
        },
        secondary: {
            DEFAULT: "35, 25, 60",
            "100": "90, 75, 130",
            "200": "75, 60, 120",
            "300": "60, 50, 110",
            "400": "50, 40, 90",
            "500": "40, 30, 75",
            "600": "30, 25, 65",
            "700": "25, 20, 55",
            "800": "18, 15, 45",
            "900": "12, 10, 35",
            "text": "220, 210, 250",
        },
    },
    "ton": {
        tertiary: '134, 134, 134',
        buttonTextColor: '15, 15, 15',
        logo: '15, 15, 15',
        footerLogo: 'none',
        primary: {
            DEFAULT: '51, 144, 236',
            '100': '246, 182, 209',
            '200': '241, 146, 186',
            '300': '237, 110, 163',
            '400': '232, 73, 140',
            '500': '45, 148, 229',
            '600': '166, 51, 94',
            '700': '136, 17, 67',
            '800': '45, 148, 229',
            '900': '51, 144, 236',
            'text': '15, 15, 15',
        },
        secondary: {
            DEFAULT: '240, 240, 240',
            '100': '199, 201, 206',
            '200': '208, 210, 211',
            '300': '212, 214, 219',
            '400': '220, 222, 226',
            '500': '227, 230, 233',
            '600': '229, 231, 235',
            '700': '241, 243, 245',
            '800': '243, 244, 246',
            '900': '250, 248, 248',
            'text': '106, 119, 133',
        },
    },
    "immutable": {
        tertiary: '182, 182, 182',
        buttonTextColor: '19, 19, 19',
        logo: '187, 187, 187',
        headerLogo: 'none',
        footerLogo: 'block',
        footerLogoHeight: '20px',
        primary: {
            DEFAULT: '243, 243, 243',
            '100': '255, 255, 255',
            '200': '255, 255, 255',
            '300': '255, 255, 255',
            '400': '255, 255, 255',
            '500': '243, 243, 243',
            '600': '215, 215, 215',
            '700': '187, 187, 187',
            '800': '159, 159, 159',
            '900': '131, 131, 131',
            'text': '243, 243, 243',
        },
        secondary: {
            DEFAULT: '37, 37, 37',
            '100': '119, 119, 119',
            '200': '98, 98, 98',
            '300': '78, 78, 78',
            '400': '57, 57, 57',
            '500': '37, 37, 37',
            '600': '13, 13, 13',
            '700': '13, 13, 13',
            '800': '13, 13, 13',
            '900': '0, 0, 0',
            'text': '182, 182, 182',
        },
    },
    "immutablePlay": {
        tertiary: '182, 182, 182',
        buttonTextColor: '19, 19, 19',
        logo: '187, 187, 187',
        headerLogo: 'none',
        footerLogo: 'block',
        footerLogoHeight: '20px',
        header: {
            hideMenu: true,
            hideTabs: true,
            hideWallets: true,
        },
        cardBackgroundStyle: {
            backgroundColor: 'transparent',
        },
        primary: {
            DEFAULT: '243, 243, 243',
            '100': '255, 255, 255',
            '200': '255, 255, 255',
            '300': '255, 255, 255',
            '400': '255, 255, 255',
            '500': '243, 243, 243',
            '600': '215, 215, 215',
            '700': '187, 187, 187',
            '800': '159, 159, 159',
            '900': '131, 131, 131',
            'text': '243, 243, 243',
        },
        secondary: {
            DEFAULT: '37, 37, 37',
            '100': '119, 119, 119',
            '200': '98, 98, 98',
            '300': '78, 78, 78',
            '400': '57, 57, 57',
            '500': '37, 37, 37',
            '600': '13, 13, 13',
            '700': '13, 13, 13',
            '800': '13, 13, 13',
            '900': '0, 0, 0',
            'text': '182, 182, 182',
        },
    }
}


================================================
FILE: Models/WalletConnectWallet.ts
================================================
import { InternalConnector } from "./WalletProvider";

export type WalletConnectWallet = {
    id: string;
    name: string;
    mobile: {
        native?: string | null;
        universal?: string | null;
    };
    desktop?: {
        native?: string | null;
        universal?: string | null;
    };
    rdns?: string;
    hasBrowserExtension?: boolean;
    extensionNotFound: boolean;
    type: string;
    icon: string;
    projectId: string;
    showQrModal: boolean;
    customStoragePrefix: string;
} & InternalConnector;


================================================
FILE: Models/WalletProvider.ts
================================================
import { WalletAccount } from 'starknet';
import { StarknetWindowObject } from 'starknetkit';

export type InternalConnector = {
    name: string,
    id: string,
    icon?: string | undefined,
    order?: number,
    type?: 'injected' | 'walletConnect' | 'other' | string,
    isMultiChain?: boolean,
    providerName: string,
    installUrl?: string,
    isMobileSupported?: boolean,
    hasBrowserExtension?: boolean,
    extensionNotFound: boolean,
}

export type Wallet = {
    id: string;
    internalId?: string;
    displayName?: string;
    // TODO: might be unused and unnecessary check
    isActive: boolean;
    address: string | `0x${string}`;
    addresses: string[];
    providerName: string
    icon: (props: any) => React.JSX.Element;
    //TODO: this is name of the connector, should be changed to connectorId
    metadata?: {
        starknetAccount?: WalletAccount,
        wallet?: StarknetWindowObject,
        l1Address?: string,
        deepLink?: string
    }
    chainId?: string | number,
    isLoading?: boolean,
    disconnect?: () => Promise<void> | undefined | void;
    connect?: () => Promise<Wallet | undefined>;
    isNotAvailable?: boolean;
    //TODO: refactor
    withdrawalSupportedNetworks?: string[],
    asSourceSupportedNetworks?: string[],
    autofillSupportedNetworks?: string[],
    networkIcon?: string,
}

export type RequestAdditionalConnectorsParams = {
    page?: number,
    pageSize?: number,
    query?: string,
}

export type RequestAdditionalConnectorsResult = {
    connectors: InternalConnector[],
    nextPage: number | null,
    totalCount: number,
}

export type WalletProvider = {
    hideFromList?: boolean,
    connectWallet: (props?: { connector?: InternalConnector }) => Promise<Wallet | undefined> | undefined,
    disconnectWallets?: () => Promise<void> | undefined | void,
    switchAccount?: (connector: Wallet, address: string) => Promise<void>,
    switchChain?: (connector: Wallet, chainId: string | number) => Promise<void>
    isNotAvailableCondition?: (connector: string, network: string, purpose?: "withdrawal" | "autofill" | "asSource") => boolean,
    availableConnectors?: InternalConnector[],
    additionalConnectors?: InternalConnector[],
    connectedWallets: Wallet[] | undefined,
    activeWallet: Wallet | undefined,
    autofillSupportedNetworks?: string[],
    withdrawalSupportedNetworks: string[],
    asSourceSupportedNetworks?: string[],
    name: string,
    id: string,
    providerIcon?: string,
    unsupportedPlatforms?: string[],
    ready: boolean,
    requestAdditionalConnectors?: (params?: RequestAdditionalConnectorsParams) => Promise<RequestAdditionalConnectorsResult>,
}


export type SelectAccountProps = {
    walletId: string;
    address: string;
    providerName: string;
}


================================================
FILE: Models/Wizard.ts
================================================
import { FC } from "react"

export type FormSteps = "SwapForm" | "OffRampExchangeOAuth" | "ExchangeOAuth" | "ExchangeApiCredentials" | "SwapConfirmation"

export type SwapSteps = "Overview" | "Withdrawal" | "OffRampWithdrawal" | "Processing" | "Success" | "Failed" | "ExternalPayment"

export type BaseWizard = {
    [key: string]: SwapCreateStep
}

export type FormWizardSteps = {
    [Property in FormSteps]: SwapCreateStep
}
export type SwapWizardSteps = {
    [Property in SwapSteps]: SwapCreateStep
}

export enum SwapCreateStep {
    MainForm = "MainForm",
    PendingSwaps = "PendingSwaps",
    AuthorizeCoinbaseWithdrawal = "AuthorizeCoinbaseWithdrawal",
    OffRampOAuth = "OffRampOAuth",
    ApiKey = "ApiKey",
    ActiveSwapLimit = 'ActiveSwapLimit',
    Error = "Error"
}

export enum SwapWithdrawalStep {
    Withdrawal = "Withdrawal",
    CoinbaseManualWithdrawal = "CoinbaseManualWithdrawal",
    SwapProcessing = 'SwapProcessing',
    ProcessingWalletTransaction = "ProcessingWalletTransaction",
    Success = "Success",
    Failed = "Failed",
    Error = "Error",
    Delay = "Delay",
    OffRampWithdrawal = "OffRampWithdrawal",
    WithdrawFromStarknet = "WithdrawFromStarknet",
    SelectWithdrawalType = "SelectWithdrawalType",
    CoinbaseInternalWithdrawal = "CoinbaseInternalWithdrawal",
}

export enum MenuStep {
    Menu = "Menu",
    Transactions = "Transactions",
    TransactionDetails = "Transaction Details"
}

export type Steps = SwapWithdrawalStep | SwapCreateStep | MenuStep

export const ExchangeAuthorizationSteps: { [key: string]: SwapCreateStep } = {
    "api_credentials": SwapCreateStep.ApiKey,
    "o_auth2": SwapCreateStep.AuthorizeCoinbaseWithdrawal
}

export const OfframpExchangeAuthorizationSteps: { [key: string]: SwapCreateStep } = {
    "api_credentials": SwapCreateStep.ApiKey,
    "o_auth2": SwapCreateStep.OffRampOAuth
}

export class WizardStep<T> {
    Name: T;
    Content: FC;
    onBack?: () => void;
    onNext?: (data?: any) => Promise<void>;
    positionPercent?: number;
}

================================================
FILE: README.md
================================================

<br />
<div align="left">
  <h1 align="left">UI for Layerswap web application</h1>
</div>
 
This repository contains implementation of Layerswap UI

 

### Run locally


  ```sh
  yarn
  yarn dev 
  ```

 
### Required environment variables

  ```yaml
  NEXT_PUBLIC_LS_API = https://api-dev.layerswap.cloud/
  NEXT_PUBLIC_API_KEY = mainnet #sandbox for testnets
  ```



================================================
FILE: components/AddressIcon/colors.mjs
================================================
export default [
    '#01888C', // teal
    '#FC7500', // bright orange
    '#034F5D', // dark teal
    '#F73F01', // orangered
    '#FC1960', // magenta
    '#C7144C', // raspberry
    '#F3C100', // goldenrod
    '#1598F2', // lightning blue
    '#2465E1', // sail blue
    '#F19E02', // gold
]


================================================
FILE: components/AddressIcon/index.tsx
================================================
'use client'
import Jazzicon from "./jazzicon.mjs";
import { FC, useEffect, useRef } from "react";

type Props = {
    address: string;
    size: number;
    className?: string;
    rounded?: string;
}

const AddressIcon: FC<Props> = ({ address, size, className, rounded }) => {
    const ref = useRef<HTMLDivElement>(null)
    useEffect(() => {
        if (address && ref.current) {
            ref.current.innerHTML = "";
            const iconElement = Jazzicon(size, parseInt(address.slice(2, 10), 16))
            if (iconElement) {
                iconElement.style.display = 'block'
                iconElement.style.width = "100%"
                iconElement.style.height = "100%"
                iconElement.style.borderRadius = rounded || "3px"
                ref.current.appendChild(iconElement);
            }
        }
    }, [address, size]);

    return <div className={className} ref={ref as any} />
}
export default AddressIcon

================================================
FILE: components/AddressIcon/jazzicon/colors.js
================================================
module.exports = [
    '#01888C', // teal
    '#FC7500', // bright orange
    '#034F5D', // dark teal
    '#F73F01', // orangered
    '#FC1960', // magenta
    '#C7144C', // raspberry
    '#F3C100', // goldenrod
    '#1598F2', // lightning blue
    '#2465E1', // sail blue
    '#F19E02', // gold
]


================================================
FILE: components/AddressIcon/jazzicon/index.js
================================================
var MersenneTwister = require('./mersenne-twister');
var paperGen = require('./paper')
var Color = require('color')
var colors = require('./colors')
var shapeCount = 4
var svgns = 'http://www.w3.org/2000/svg'

module.exports = generateIdenticon

var generator
function generateIdenticon(diameter, seed) {
  generator = new MersenneTwister(seed);
  var remainingColors = hueShift(colors.slice(), generator)

  var elements = paperGen(diameter, genColor(remainingColors))
  var container = elements.container

  var svg = document.createElementNS(svgns, 'svg')
  svg.setAttributeNS(null, 'x', '0')
  svg.setAttributeNS(null, 'y', '0')
  svg.setAttributeNS(null, 'width', diameter)
  svg.setAttributeNS(null, 'height', diameter)

  container.appendChild(svg)

  for(var i = 0; i < shapeCount - 1; i++) {
    genShape(remainingColors, diameter, i, shapeCount - 1, svg)
  }

  return container
}

function genShape(remainingColors, diameter, i, total, svg) {
  var center = diameter / 2

  var shape = document.createElementNS(svgns, 'rect')
  shape.setAttributeNS(null, 'x', '0')
  shape.setAttributeNS(null, 'y', '0')
  shape.setAttributeNS(null, 'width', diameter)
  shape.setAttributeNS(null, 'height', diameter)

  var firstRot = generator.random()
  var angle = Math.PI * 2 * firstRot
  var velocity = diameter / total * generator.random() + (i * diameter / total)

  var tx = (Math.cos(angle) * velocity)
  var ty = (Math.sin(angle) * velocity)

  var translate = 'translate(' + tx + ' ' +  ty + ')'

  // Third random is a shape rotation on top of all of that.
  var secondRot = generator.random()
  var rot = (firstRot * 360) + secondRot * 180
  var rotate = 'rotate(' + rot.toFixed(1) + ' ' + center + ' ' + center + ')'
  var transform = translate + ' ' + rotate
  shape.setAttributeNS(null, 'transform', transform)
  var fill = genColor(remainingColors)
  shape.setAttributeNS(null, 'fill', fill)

  svg.appendChild(shape)
}

function genColor(colors) {
  var rand = generator.random()
  var idx = Math.floor(colors.length * generator.random())
  var color = colors.splice(idx,1)[0]
  return color
}

var wobble = 30
function hueShift(colors, generator) {
  var amount = (generator.random() * 30) - (wobble / 2)
  return colors.map(function(hex) {
    var color = Color(hex)
    color.rotate(amount)
    return color.hex()
  })
}

================================================
FILE: components/AddressIcon/jazzicon/mersenne-twister.js
================================================

/*
  https://github.com/banksean wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace
  so it's better encapsulated. Now you can have multiple random number generators
  and they won't stomp all over eachother's state.

  If you want to use this as a substitute for Math.random(), use the random()
  method like so:

  var m = new MersenneTwister();
  var randomNumber = m.random();

  You can also call the other genrand_{foo}() methods on the instance.

  If you want to use a specific seed in order to get a repeatable random
  sequence, pass an integer into the constructor:

  var m = new MersenneTwister(123);

  and that will always produce the same random sequence.

  Sean McCullough (banksean@gmail.com)
*/

/*
   A C-program for MT19937, with initialization improved 2002/1/26.
   Coded by Takuji Nishimura and Makoto Matsumoto.

   Before using, initialize the state by using init_seed(seed)
   or init_by_array(init_key, key_length).

   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

     1. Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.

     2. Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.

     3. The names of its contributors may not be used to endorse or promote
        products derived from this software without specific prior written
        permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


   Any feedback is very welcome.
   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/

/**
 * @constructor
 * @param {number|Array<number>} [seed] - Optional seed for the random number generator
 */
function MersenneTwister(seed) {
    if (seed == undefined) {
        seed = new Date().getTime();
    }

    /* Period parameters */
    this.N = 624;
    this.M = 397;
    this.MATRIX_A = 0x9908b0df;   /* constant vector a */
    this.UPPER_MASK = 0x80000000; /* most significant w-r bits */
    this.LOWER_MASK = 0x7fffffff; /* least significant r bits */

    this.mt = new Array(this.N); /* the array for the state vector */
    this.mti = this.N + 1; /* mti==N+1 means mt[N] is not initialized */

    if (seed.constructor == Array) {
        this.init_by_array(seed, seed.length);
    }
    else {
        this.init_seed(seed);
    }
}

/* initializes mt[N] with a seed */
/* origin name init_genrand */
MersenneTwister.prototype.init_seed = function (s) {
    this.mt[0] = s >>> 0;
    for (this.mti = 1; this.mti < this.N; this.mti++) {
        var s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30);
        this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253)
            + this.mti;
        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
        /* In the previous versions, MSBs of the seed affect   */
        /* only MSBs of the array mt[].                        */
        /* 2002/01/09 modified by Makoto Matsumoto             */
        this.mt[this.mti] >>>= 0;
        /* for >32 bit machines */
    }
}

/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
/* slight change for C++, 2004/2/26 */
MersenneTwister.prototype.init_by_array = function (init_key, key_length) {
    var i, j, k;
    this.init_seed(19650218);
    i = 1; j = 0;
    k = (this.N > key_length ? this.N : key_length);
    for (; k; k--) {
        var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30)
        this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525)))
            + init_key[j] + j; /* non linear */
        this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */
        i++; j++;
        if (i >= this.N) {
Download .txt
gitextract_wrqmm7zr/

├── .claude/
│   ├── agents/
│   │   ├── pr-review-coordinator.md
│   │   ├── pr-reviewer-architecture.md
│   │   ├── pr-reviewer-bugs.md
│   │   ├── pr-reviewer-performance.md
│   │   ├── pr-reviewer-quality.md
│   │   ├── pr-reviewer-react.md
│   │   ├── pr-reviewer-security.md
│   │   └── pr-reviewer.md
│   ├── commands/
│   │   └── reviewchanges.md
│   └── skills/
│       └── vercel-react-best-practices/
│           ├── SKILL.md
│           └── rules/
│               ├── advanced-event-handler-refs.md
│               ├── advanced-use-latest.md
│               ├── async-api-routes.md
│               ├── async-defer-await.md
│               ├── async-dependencies.md
│               ├── async-parallel.md
│               ├── async-suspense-boundaries.md
│               ├── bundle-barrel-imports.md
│               ├── bundle-conditional.md
│               ├── bundle-defer-third-party.md
│               ├── bundle-dynamic-imports.md
│               ├── bundle-preload.md
│               ├── client-event-listeners.md
│               ├── client-localstorage-schema.md
│               ├── client-passive-event-listeners.md
│               ├── client-swr-dedup.md
│               ├── js-batch-dom-css.md
│               ├── js-cache-function-results.md
│               ├── js-cache-property-access.md
│               ├── js-cache-storage.md
│               ├── js-combine-iterations.md
│               ├── js-early-exit.md
│               ├── js-hoist-regexp.md
│               ├── js-index-maps.md
│               ├── js-length-check-first.md
│               ├── js-min-max-loop.md
│               ├── js-set-map-lookups.md
│               ├── js-tosorted-immutable.md
│               ├── rendering-activity.md
│               ├── rendering-animate-svg-wrapper.md
│               ├── rendering-conditional-render.md
│               ├── rendering-content-visibility.md
│               ├── rendering-hoist-jsx.md
│               ├── rendering-hydration-no-flicker.md
│               ├── rendering-svg-precision.md
│               ├── rerender-defer-reads.md
│               ├── rerender-dependencies.md
│               ├── rerender-derived-state.md
│               ├── rerender-functional-setstate.md
│               ├── rerender-lazy-state-init.md
│               ├── rerender-memo.md
│               ├── rerender-simple-expression-in-memo.md
│               ├── rerender-transitions.md
│               ├── server-after-nonblocking.md
│               ├── server-auth-actions.md
│               ├── server-cache-lru.md
│               ├── server-cache-react.md
│               ├── server-dedup-props.md
│               ├── server-parallel-fetching.md
│               ├── server-serialization.md
│               └── unused-detection.md
├── .eslintrc.json
├── .github/
│   └── workflows/
│       ├── chromatic.yml
│       ├── deploy.yml
│       └── rebase-main-sandbox.yml
├── .gitignore
├── .storybook/
│   ├── main.ts
│   ├── manager.js
│   └── preview.ts
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── AGENTS.md
├── CLAUDE.md
├── Models/
│   ├── ApiError.ts
│   ├── ApiResponse.ts
│   ├── Balance.ts
│   ├── BalanceProvider.ts
│   ├── Exchange.ts
│   ├── LayerSwapAppSettings.ts
│   ├── LayerSwapAuth.ts
│   ├── LayerSwapSettings.ts
│   ├── Network.ts
│   ├── Partner.ts
│   ├── QueryParams.ts
│   ├── RangeError.ts
│   ├── Route.ts
│   ├── SwapStatus.ts
│   ├── Theme.ts
│   ├── WalletConnectWallet.ts
│   ├── WalletProvider.ts
│   └── Wizard.ts
├── README.md
├── components/
│   ├── AddressIcon/
│   │   ├── colors.mjs
│   │   ├── index.tsx
│   │   ├── jazzicon/
│   │   │   ├── colors.js
│   │   │   ├── index.js
│   │   │   ├── mersenne-twister.js
│   │   │   └── paper.js
│   │   ├── jazzicon.mjs
│   │   ├── mersenne-twister.mjs
│   │   └── paper.mjs
│   ├── AvatarGroup.tsx
│   ├── Campaigns/
│   │   ├── Details/
│   │   │   ├── Leaderboard.tsx
│   │   │   ├── Rewards.tsx
│   │   │   └── index.tsx
│   │   └── index.tsx
│   ├── Carousel.tsx
│   ├── ColorSchema.tsx
│   ├── Common/
│   │   ├── AnimatedValue.tsx
│   │   ├── AverageCompletionTime.tsx
│   │   ├── ConnectWalletButton.tsx
│   │   ├── CountDownTimer.tsx
│   │   ├── FormattedAverageCompletionTime.tsx
│   │   ├── FormattedDate.tsx
│   │   ├── ImageWithFallback.tsx
│   │   ├── LinkWithIcon.tsx
│   │   ├── NumFlowWithFallback.tsx
│   │   ├── ReactPortal.tsx
│   │   └── TypingEffect.tsx
│   ├── ConnectNetwork.tsx
│   ├── ContactSupport.tsx
│   ├── DTOs/
│   │   ├── SwapConfirmationFormValues.ts
│   │   └── SwapFormValues.ts
│   ├── ErrorFallback.tsx
│   ├── FeeDetails/
│   │   ├── DepositMethod/
│   │   │   └── index.tsx
│   │   ├── Rate.tsx
│   │   ├── ReceiveAmounts.tsx
│   │   ├── Refuel.tsx
│   │   ├── RefuelModal.tsx
│   │   ├── Slippage.tsx
│   │   ├── SwapQuote/
│   │   │   ├── DetailedEstimates.tsx
│   │   │   ├── SummaryRow.tsx
│   │   │   └── index.tsx
│   │   └── index.tsx
│   ├── HeaderWithMenu/
│   │   └── index.tsx
│   ├── Input/
│   │   ├── Address/
│   │   │   ├── AddressPicker/
│   │   │   │   ├── AddressBook.tsx
│   │   │   │   ├── AddressButton.tsx
│   │   │   │   ├── AddressWithIcon.tsx
│   │   │   │   ├── ConnectedWallets.tsx
│   │   │   │   ├── ManualAddressInput.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── ContractAddressNote.tsx
│   │   │   ├── UrlAddressNote.tsx
│   │   │   └── index.tsx
│   │   ├── Amount/
│   │   │   ├── Balance.tsx
│   │   │   ├── ExchangeAmountField.tsx
│   │   │   ├── ExchangeReceiveAmount.tsx
│   │   │   ├── MinMax.tsx
│   │   │   ├── PriceImpact.tsx
│   │   │   ├── ReceiveAmount.tsx
│   │   │   ├── helpers.ts
│   │   │   └── index.tsx
│   │   ├── CexPicker.tsx
│   │   ├── DestinationPicker.tsx
│   │   ├── DestinationWalletPicker.tsx
│   │   ├── NumericInput.tsx
│   │   ├── RoutePicker/
│   │   │   ├── Content.tsx
│   │   │   ├── RouteSearch.tsx
│   │   │   ├── RouteSortingMenu.tsx
│   │   │   ├── RouteTokenSwitch.tsx
│   │   │   ├── RouterPickerWalletConnect.tsx
│   │   │   ├── Routes.tsx
│   │   │   ├── Rows/
│   │   │   │   ├── CollapsableHeader.tsx
│   │   │   │   ├── CollapsibleRow.tsx
│   │   │   │   ├── StickyHeader.tsx
│   │   │   │   ├── SuggestionsHeader.tsx
│   │   │   │   ├── TitleRow.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── TokenTitleDetails.tsx
│   │   │   └── index.tsx
│   │   ├── Search.tsx
│   │   ├── SourcePicker.tsx
│   │   ├── SourceWalletPicker.tsx
│   │   └── TransferCEX.tsx
│   ├── LayerswapMenu/
│   │   ├── Menu.tsx
│   │   ├── MenuList.tsx
│   │   └── index.tsx
│   ├── LinkWraapper.tsx
│   ├── LoadingCard.tsx
│   ├── MessageComponent.tsx
│   ├── NavigatableList/
│   │   ├── NavigatableItem.tsx
│   │   ├── NavigatableList.tsx
│   │   ├── context.ts
│   │   ├── hooks.ts
│   │   └── index.tsx
│   ├── NoCookies.tsx
│   ├── ProgressBar.tsx
│   ├── QRCodeWallet.tsx
│   ├── ReserveGasNote.tsx
│   ├── ResizablePanel.tsx
│   ├── Sceletons.tsx
│   ├── Select/
│   │   ├── Command/
│   │   │   ├── CommandSelectWrapper.tsx
│   │   │   └── commandSelect.tsx
│   │   ├── Popover/
│   │   │   ├── PopoverSelect.tsx
│   │   │   └── PopoverSelectWrapper.tsx
│   │   ├── Selector/
│   │   │   ├── Index.tsx
│   │   │   └── SelectItem.tsx
│   │   └── Shared/
│   │       ├── Props/
│   │       │   ├── SelectProps.tsx
│   │       │   └── selectMenuItem.tsx
│   │       └── SelectItem.tsx
│   ├── Swap/
│   │   ├── Form/
│   │   │   ├── ExchangeForm.tsx
│   │   │   ├── FormWrapper.tsx
│   │   │   ├── NetworkExchangeTabs.tsx
│   │   │   ├── NetworkForm.tsx
│   │   │   ├── index.tsx
│   │   │   └── updateForm.ts
│   │   ├── FormButton.tsx
│   │   ├── NotFound.tsx
│   │   ├── Step.tsx
│   │   ├── StepsComponent.tsx
│   │   ├── Summary/
│   │   │   ├── Summary.tsx
│   │   │   └── index.tsx
│   │   ├── Withdraw/
│   │   │   ├── Failed.tsx
│   │   │   ├── ManualWithdraw.tsx
│   │   │   ├── Processing/
│   │   │   │   ├── Processing.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   └── types.ts
│   │   │   ├── QuoteUpdate.tsx
│   │   │   ├── Success.tsx
│   │   │   ├── SwapQuoteDetails.tsx
│   │   │   ├── Wallet/
│   │   │   │   ├── Common/
│   │   │   │   │   ├── buttons.tsx
│   │   │   │   │   └── sharedTypes.ts
│   │   │   │   ├── WithdrawalProviders/
│   │   │   │   │   ├── BitcoinWalletWithdraw/
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   ├── sendTransaction.ts
│   │   │   │   │   │   └── transactionBuilder/
│   │   │   │   │   │       ├── buildPsbt.ts
│   │   │   │   │   │       ├── estimateFee.ts
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── EVMWalletWithdraw/
│   │   │   │   │   │   ├── RPCUnhealthyMessage.tsx
│   │   │   │   │   │   ├── TransferToken.tsx
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   ├── resolveError.tsx
│   │   │   │   │   │   └── transactionMessage.tsx
│   │   │   │   │   ├── FuelWalletWithdrawal.tsx
│   │   │   │   │   ├── Loopring/
│   │   │   │   │   │   ├── ActivationTokentPicker.tsx
│   │   │   │   │   │   ├── hooks.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SVMWalletWithdraw/
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   └── transactionSender.ts
│   │   │   │   │   ├── StarknetWalletWithdraw.tsx
│   │   │   │   │   ├── TempoWalletWithdraw/
│   │   │   │   │   │   ├── TransferToken.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── TonWalletWithdraw.tsx
│   │   │   │   │   ├── TronWalletWithdraw.tsx
│   │   │   │   │   ├── ZKsyncWalletWithdraw.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── paradex/
│   │   │   │   │       ├── Evm.tsx
│   │   │   │   │       ├── Starknet.tsx
│   │   │   │   │       └── index.tsx
│   │   │   │   └── index.tsx
│   │   │   ├── WalletTransferButton.tsx
│   │   │   ├── WalletTransferContent.tsx
│   │   │   ├── index.tsx
│   │   │   └── messages/
│   │   │       ├── Message.tsx
│   │   │       └── TransactionMessages.tsx
│   │   └── index.tsx
│   ├── SwapGuide.tsx
│   ├── SwapHistory/
│   │   ├── Filters/
│   │   │   ├── CheckboxRow.tsx
│   │   │   ├── ClearAllButton.tsx
│   │   │   ├── NetworksDropdown.tsx
│   │   │   ├── NoMatches.tsx
│   │   │   ├── SearchResult.tsx
│   │   │   ├── WalletsDropdown.tsx
│   │   │   ├── chipStyles.ts
│   │   │   ├── filterSwaps.ts
│   │   │   ├── index.tsx
│   │   │   └── types.ts
│   │   ├── Header.tsx
│   │   ├── History.tsx
│   │   ├── HistorySummary.tsx
│   │   ├── Snippet.tsx
│   │   ├── StatusIcons.tsx
│   │   ├── SwapDetailsComponent.tsx
│   │   └── index.tsx
│   ├── SwapWithdrawal.tsx
│   ├── Tooltips/
│   │   └── ClickTooltip.tsx
│   ├── Wallet/
│   │   ├── ConnectedWallets.tsx
│   │   └── WalletsList.tsx
│   ├── WalletModal/
│   │   ├── Connector.tsx
│   │   ├── ConnectorsList.tsx
│   │   ├── InstalledExtensionNotFound.tsx
│   │   ├── LoadingConnect.tsx
│   │   ├── MultichainConnectorPicker.tsx
│   │   ├── ProviderPicker.tsx
│   │   ├── WalletQrCode.tsx
│   │   ├── index.tsx
│   │   └── utils.ts
│   ├── WalletProviders/
│   │   ├── ActiveEvmAccount.tsx
│   │   ├── ActiveParadexAccount.tsx
│   │   ├── BitcoinProvider.tsx
│   │   ├── FuelProvider.tsx
│   │   ├── ImtblPassportProvider.tsx
│   │   ├── SolanaProvider.tsx
│   │   ├── StarknetProvider.tsx
│   │   ├── TonConnectProvider.tsx
│   │   ├── TronProvider.tsx
│   │   ├── Wagmi.tsx
│   │   └── index.tsx
│   ├── WarningMessage.tsx
│   ├── Widget/
│   │   ├── Content.tsx
│   │   ├── Footer.tsx
│   │   └── Index.tsx
│   ├── Wizard/
│   │   ├── Wizard.tsx
│   │   └── WizardItem.tsx
│   ├── backgroundField.tsx
│   ├── banner.tsx
│   ├── buttons/
│   │   ├── connectButton.tsx
│   │   ├── copyButton.tsx
│   │   ├── exploreButton.tsx
│   │   ├── iconButton.tsx
│   │   ├── secondaryButton.tsx
│   │   ├── submitButton.tsx
│   │   └── toggleButton.tsx
│   ├── cardContainer.tsx
│   ├── docInIframe.tsx
│   ├── gauge.tsx
│   ├── globalFooter.tsx
│   ├── guideLink.tsx
│   ├── icons/
│   │   ├── AlertIcon.tsx
│   │   ├── CancelIcon.tsx
│   │   ├── ChatIcon.tsx
│   │   ├── CheckIcon.tsx
│   │   ├── CircleCheckIcon.tsx
│   │   ├── CircularLoader.tsx
│   │   ├── Clock.tsx
│   │   ├── ConnectorIcons.tsx
│   │   ├── CopyIcon.tsx
│   │   ├── DelayIcon.tsx
│   │   ├── DiscordLogo.tsx
│   │   ├── ExchangeGasIcon.tsx
│   │   ├── ExchangeTabIcon.tsx
│   │   ├── FailIcon.tsx
│   │   ├── FeeIcon.tsx
│   │   ├── FilledCheck.tsx
│   │   ├── FilledX.tsx
│   │   ├── GasIcon.tsx
│   │   ├── GitHubLogo.tsx
│   │   ├── GlobeIcon.tsx
│   │   ├── InfoIcon.tsx
│   │   ├── LogoPlaceholder.tsx
│   │   ├── MenuIcon.tsx
│   │   ├── NetworkTabIcon.tsx
│   │   ├── NotFoundIcon.tsx
│   │   ├── QRIcon.tsx
│   │   ├── Question.tsx
│   │   ├── RouteIcon.tsx
│   │   ├── RoutePickerPlaceholder.tsx
│   │   ├── SearchIcon.tsx
│   │   ├── SignatureIcon.tsx
│   │   ├── SubstackLogo.tsx
│   │   ├── SuccessIcon.tsx
│   │   ├── SvgWithImg.tsx
│   │   ├── TokenIcon.tsx
│   │   ├── TwitterLogo.tsx
│   │   ├── WalletIcon.tsx
│   │   ├── Wallets/
│   │   │   ├── Argent.tsx
│   │   │   ├── ArgentX.tsx
│   │   │   ├── BakoSafe.tsx
│   │   │   ├── BitKeep.tsx
│   │   │   ├── Bitget.tsx
│   │   │   ├── Braavos.tsx
│   │   │   ├── BrowserWallet.tsx
│   │   │   ├── Coinbase.tsx
│   │   │   ├── Controller.tsx
│   │   │   ├── Ethereum.tsx
│   │   │   ├── Fuel.tsx
│   │   │   ├── Fuelet.tsx
│   │   │   ├── Glow.tsx
│   │   │   ├── IMX.tsx
│   │   │   ├── ImtblPassport.tsx
│   │   │   ├── Keplr.tsx
│   │   │   ├── MetaMask.tsx
│   │   │   ├── MyTonWallet.tsx
│   │   │   ├── OpenMask.tsx
│   │   │   ├── Phantom.tsx
│   │   │   ├── Rainbow.tsx
│   │   │   ├── Solana.tsx
│   │   │   ├── Solflare.tsx
│   │   │   ├── Starknet.tsx
│   │   │   ├── TON.tsx
│   │   │   ├── TonKeeper.tsx
│   │   │   ├── WalletConnect.tsx
│   │   │   └── Xverse.tsx
│   │   ├── YoutubeLogo.tsx
│   │   ├── layerSwapLogo.tsx
│   │   ├── layerSwapLogoSmall.tsx
│   │   ├── layerSwapMobileLogo.tsx
│   │   └── spinIcon.tsx
│   ├── layout.tsx
│   ├── maintanance/
│   │   └── maintanance.tsx
│   ├── modal/
│   │   ├── leaflet.tsx
│   │   ├── modal.tsx
│   │   ├── modalWithoutAnimation.tsx
│   │   ├── vaul/
│   │   │   ├── browser.ts
│   │   │   ├── constants.ts
│   │   │   ├── context.ts
│   │   │   ├── helpers.ts
│   │   │   ├── index.tsx
│   │   │   ├── types.ts
│   │   │   ├── use-composed-refs.ts
│   │   │   ├── use-controllable-state.ts
│   │   │   ├── use-position-fixed.ts
│   │   │   ├── use-prevent-scroll.ts
│   │   │   ├── use-scale-background.ts
│   │   │   └── use-snap-points.ts
│   │   └── vaulModal.tsx
│   ├── navbar.tsx
│   ├── sendFeedback.tsx
│   ├── shadcn/
│   │   ├── accordion.tsx
│   │   ├── checkbox.tsx
│   │   ├── command.tsx
│   │   ├── dialog.tsx
│   │   ├── popover.tsx
│   │   ├── select.tsx
│   │   ├── tab.tsx
│   │   └── tooltip.tsx
│   ├── swapComponent.tsx
│   ├── themeWrapper.tsx
│   ├── utils/
│   │   ├── GoHome.tsx
│   │   ├── RoundDecimals.ts
│   │   ├── ShortenString.tsx
│   │   ├── classNames.ts
│   │   ├── convertSvgComponentToBase64.tsx
│   │   ├── dateDifference.ts
│   │   ├── formatUsdAmount.ts
│   │   ├── groupBy.ts
│   │   ├── inIframe.ts
│   │   ├── isGuid.ts
│   │   ├── numbers.ts
│   │   ├── resolveSwapPhase.ts
│   │   ├── swapUtils.ts
│   │   ├── timeCalculations.ts
│   │   └── upperCaseKeys.ts
│   └── validationError/
│       ├── AdjustAmountButton.tsx
│       ├── ContractAddressValidationCache.tsx
│       ├── ErrorDisplay.tsx
│       ├── RefreshBalanceButton.tsx
│       ├── constants.ts
│       └── index.tsx
├── context/
│   ├── asyncModal.tsx
│   ├── formWizardProvider.tsx
│   ├── loadingContext.tsx
│   ├── query.tsx
│   ├── settings.tsx
│   ├── snapPointsContext.tsx
│   ├── swap.tsx
│   ├── swapAccounts.tsx
│   ├── timerContext.tsx
│   ├── validationContext.tsx
│   ├── walletProviders.tsx
│   └── withdrawalContext.tsx
├── eslint-plugins/
│   └── eslint-plugin-no-conditional-literals-in-jsx/
│       ├── index.js
│       ├── package.json
│       ├── rules/
│       │   ├── no-conditional-literals-in-jsx.js
│       │   └── no-unwrapped-jsx-text.js
│       ├── tests.js
│       └── utils/
│           ├── constants.js
│           └── jsx.js
├── funding.json
├── helpers/
│   ├── accountSelectHelper.ts
│   ├── balanceHelper.ts
│   ├── errorHelper.ts
│   ├── getSettings.ts
│   ├── querryHelper.ts
│   ├── routes.ts
│   ├── settingsCompression.ts
│   ├── settingsHelper.ts
│   ├── storageAvailable.ts
│   ├── tokenHelper.tsx
│   └── validateSignature.ts
├── hooks/
│   ├── useAllWithdrawalBalances.tsx
│   ├── useAutoSlippageTest.tsx
│   ├── useClickOutside.ts
│   ├── useConnectors.ts
│   ├── useCopyClipboard.ts
│   ├── useExchangeNetworks.ts
│   ├── useFee.tsx
│   ├── useFormRoutes.ts
│   ├── useFormValidation.ts
│   ├── useGoHome.ts
│   ├── useHistoryFilters.ts
│   ├── useInterval.ts
│   ├── useIsWindowVisible.ts
│   ├── useKeyboardNavigation.ts
│   ├── useNavigatableList.ts
│   ├── usePersistedState.ts
│   ├── useResolvedSwapStatus.ts
│   ├── useRouteValidation.tsx
│   ├── useStorage.ts
│   ├── useSuggestionsLimit.tsx
│   ├── useSwapByTransactionHash.ts
│   ├── useSwapHistoryData.ts
│   ├── useSwrSwaps.ts
│   ├── useUsdTokenSync.ts
│   ├── useWallet.ts
│   ├── useWalletRpcHealth.tsx
│   ├── useWalletTransferOptions.ts
│   └── useWindowDimensions.tsx
├── lib/
│   ├── AnimatedNumber.tsx
│   ├── AppSettings.ts
│   ├── CurrencySettings.ts
│   ├── Errors/
│   │   └── AuthRefreshFailedError.ts
│   ├── ExchangeSettings.ts
│   ├── NetworkSettings.ts
│   ├── SwapSettings.ts
│   ├── abis/
│   │   ├── BALANCEGETTERABI.json
│   │   ├── ERC20.json
│   │   ├── FUELWATCHDOG.json
│   │   ├── LSWATCHDOG.json
│   │   └── usdt.json
│   ├── address/
│   │   ├── Address.ts
│   │   ├── explorerUrl.ts
│   │   ├── formatter.ts
│   │   ├── index.ts
│   │   └── validator/
│   │       ├── index.ts
│   │       └── starkNetAddressValidator.ts
│   ├── apiClients/
│   │   ├── hyperliquidClient.ts
│   │   ├── jsonRpcClient.ts
│   │   └── layerSwapApiClient.ts
│   ├── axiosInterceptor.ts
│   ├── balances/
│   │   ├── balanceResolver.ts
│   │   ├── errorUtils.ts
│   │   ├── helpers.ts
│   │   ├── nodeErrorClassifier.ts
│   │   ├── providers/
│   │   │   ├── bitcoinBalanceProvider.ts
│   │   │   ├── evmBalanceProvider.ts
│   │   │   ├── fuelBalanceProvider.ts
│   │   │   ├── hyperliquidBalanceProvider.ts
│   │   │   ├── index.ts
│   │   │   ├── loopringBalanceProvider.ts
│   │   │   ├── paradexBalanceProvider.ts
│   │   │   ├── queryBalanceProvider.ts
│   │   │   ├── solanaBalanceProvider.ts
│   │   │   ├── starknetBalanceProvider.ts
│   │   │   ├── tonBalanceProvider.ts
│   │   │   ├── tronBalanceProvider.ts
│   │   │   └── zkSyncBalanceProvider.ts
│   │   └── useBalance.ts
│   ├── calculateDatesDifference.ts
│   ├── dynamicWithRetries/
│   │   └── defaultError.tsx
│   ├── ethersToViem/
│   │   └── ethers.ts
│   ├── external/
│   │   └── nameof/
│   │       ├── index.ts
│   │       ├── name-of.ts
│   │       ├── path-of.ts
│   │       ├── separated-path-of.ts
│   │       └── types.ts
│   ├── fees.ts
│   ├── fetchWithTimeout.ts
│   ├── fuels/
│   │   ├── common/
│   │   │   ├── FakeAccount.ts
│   │   │   ├── PredicateConnector.ts
│   │   │   ├── PredicateFactory.ts
│   │   │   ├── PredicateWalletAdapter.ts
│   │   │   ├── index.ts
│   │   │   ├── networks.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── connectors/
│   │   │   ├── bako-safe/
│   │   │   │   ├── BakoSafeConnector.ts
│   │   │   │   ├── BakoSafeStorage.ts
│   │   │   │   ├── DAPPWindow.ts
│   │   │   │   ├── SocketClient.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── request.ts
│   │   │   │   └── types.ts
│   │   │   ├── fuel-wallet/
│   │   │   │   ├── FuelWalletConnector.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── fuelet-wallet/
│   │   │   │   ├── FueletWalletConnector.ts
│   │   │   │   ├── constants.ts
│   │   │   │   └── index.ts
│   │   │   └── walletConnect/
│   │   │       ├── WalletConnectConnector.ts
│   │   │       ├── constants.ts
│   │   │       ├── index.ts
│   │   │       ├── types.ts
│   │   │       ├── utils/
│   │   │       │   ├── index.ts
│   │   │       │   └── subscribeAndEnforceChain.ts
│   │   │       └── web3Modal.ts
│   │   └── evm-predicates/
│   │       ├── 0xbbae06500cd11e6c1d024ac587198cb30c504bf14ba16548f19e21fa9e8f5f95/
│   │       │   └── index.ts
│   │       ├── 0xfdac03fc617c264fa6f325fd6f4d2a5470bf44cfbd33bc11efb3bf8b7ee2e938/
│   │       │   └── index.ts
│   │       └── index.ts
│   ├── gases/
│   │   ├── gasResolver.ts
│   │   ├── providers/
│   │   │   ├── bitcoinGasProvider.ts
│   │   │   ├── evmGasProvider.ts
│   │   │   ├── fuelGasProvider.ts
│   │   │   ├── loopringGasProvider.ts
│   │   │   ├── solanaGasProvider.ts
│   │   │   ├── starknetGasProvider.ts
│   │   │   ├── tonGasProvider.ts
│   │   │   ├── tronGasProvider.ts
│   │   │   ├── types.ts
│   │   │   └── zkSyncGasProvider.ts
│   │   ├── useOutOfGas.ts
│   │   └── useSWRGas.tsx
│   ├── generateSwapInitialValues.ts
│   ├── isMobile.ts
│   ├── jwtParser.ts
│   ├── knownIds.ts
│   ├── logError.ts
│   ├── loopring/
│   │   ├── LoopringAPI.ts
│   │   ├── defs.ts
│   │   ├── eddsa.ts
│   │   ├── field.ts
│   │   ├── formatter.ts
│   │   ├── helpers.ts
│   │   ├── jubjub.ts
│   │   ├── permutation.ts
│   │   ├── poseidon/
│   │   │   ├── EDDSAUtil.ts
│   │   │   ├── babyJub.ts
│   │   │   └── eddsa.ts
│   │   └── utils.ts
│   ├── nft/
│   │   ├── nftBalanceResolver.ts
│   │   ├── providers/
│   │   │   ├── starknetNftProvider.ts
│   │   │   └── types.ts
│   │   └── useSWRNftBalance.tsx
│   ├── openLink.ts
│   ├── resolveChain.ts
│   ├── resolveTransports.ts
│   ├── retry.ts
│   ├── telegram.ts
│   ├── virtual/
│   │   ├── core/
│   │   │   ├── index.ts
│   │   │   └── utils.ts
│   │   └── index.tsx
│   └── wallets/
│       ├── bitcoin/
│       │   ├── getConnections.ts
│       │   ├── useAccount.ts
│       │   ├── useBitcoin.ts
│       │   └── useSyncExternalStoreWithTracked.ts
│       ├── connectors/
│       │   ├── browserInjected/
│       │   │   └── index.ts
│       │   ├── explicitInjectedProviderDetected.ts
│       │   ├── resolveConnectors/
│       │   │   └── walletConnect.ts
│       │   ├── types.ts
│       │   ├── useSyncProviders/
│       │   │   ├── EthereumProviderTypes.d.ts
│       │   │   ├── index.ts
│       │   │   └── store.ts
│       │   └── utils/
│       │       └── isMobile.ts
│       ├── evm/
│       │   ├── KnownEVMConnectors.tsx
│       │   ├── constants.ts
│       │   └── useEVM.ts
│       ├── fuel/
│       │   ├── Bako.ts
│       │   ├── KnownFuelConnectors.tsx
│       │   └── useFuel.ts
│       ├── paradex/
│       │   ├── Authorize/
│       │   │   ├── Ethereum.ts
│       │   │   └── Starknet.ts
│       │   ├── lib/
│       │   │   ├── account.ts
│       │   │   ├── config.ts
│       │   │   ├── constants.ts
│       │   │   ├── ethereum-signer.ts
│       │   │   ├── index.ts
│       │   │   ├── paraclear-provider.ts
│       │   │   ├── paraclear.ts
│       │   │   ├── starknet-account-support.ts
│       │   │   ├── starknet-signer.ts
│       │   │   └── types.ts
│       │   └── useParadex.ts
│       ├── solana/
│       │   ├── KnownSolanaConnectors.tsx
│       │   ├── SolanaWalletConnectAdapter.ts
│       │   ├── transactionBuilder.ts
│       │   └── useSVM.tsx
│       ├── starknet/
│       │   ├── KnownStarknetConnectors.tsx
│       │   └── useStarknet.ts
│       ├── ton/
│       │   ├── client.ts
│       │   └── useTON.ts
│       ├── tron/
│       │   └── useTron.ts
│       ├── utils/
│       │   ├── resolveWalletIcon.tsx
│       │   └── sleep.ts
│       └── walletConnect/
│           ├── api.ts
│           ├── buildDeepLink.ts
│           ├── config.ts
│           ├── createRegistryConnector.ts
│           ├── decorateForWagmi.ts
│           ├── dynamicMetadata.ts
│           ├── mapConnectError.ts
│           ├── mapWallet.ts
│           ├── registry.ts
│           ├── subscribeDisplayUri.ts
│           ├── types.ts
│           └── useAdditionalConnectors.ts
├── next.config.js
├── package.json
├── pages/
│   ├── 404.tsx
│   ├── _app.js
│   ├── _document.tsx
│   ├── _error.jsx
│   ├── campaigns/
│   │   ├── [campaign].tsx
│   │   └── index.tsx
│   ├── imtblRedirect.tsx
│   ├── index.tsx
│   ├── nocookies.tsx
│   ├── salon.tsx
│   ├── swap/
│   │   └── [swapId].tsx
│   └── transactions.tsx
├── postcss.config.js
├── public/
│   ├── doc/
│   │   └── userGuide.md
│   ├── favicon/
│   │   ├── browserconfig.xml
│   │   └── site.webmanifest
│   ├── manualTransfer.json
│   ├── robots.txt
│   ├── sitemap.xml
│   └── tonconnect-manifest.json
├── stores/
│   ├── balanceStore.ts
│   ├── contractAddressStore.ts
│   ├── contractWalletsStore.ts
│   ├── manualDestAddressesStore.ts
│   ├── recentRoutesStore.ts
│   ├── routeSortingStore.ts
│   ├── routeTokenSwitchStore.ts
│   ├── slippageStore.ts
│   ├── starknetWalletStore.ts
│   ├── swapTransactionStore.tsx
│   ├── usdModeStore.ts
│   └── walletStore.ts
├── stories/
│   ├── Data/
│   │   ├── initialValues.ts
│   │   ├── settings.ts
│   │   └── swaps.tsx
│   ├── Docs/
│   │   ├── MessageDocs/
│   │   │   └── Docs.mdx
│   │   └── ProcessDocs/
│   │       └── Docs.mdx
│   ├── Message.stories.tsx
│   ├── Mocks/
│   │   └── context/
│   │       └── SwapDataUpdate.ts
│   ├── PriceImpact.stories.tsx
│   ├── Process.stories.tsx
│   └── SwapNotFound.stories.tsx
├── styles/
│   ├── dialog-transition.css
│   ├── globals.css
│   ├── manual-trasnfer-svg.css
│   └── vaul.css
├── tailwind.config.js
├── tsconfig.json
└── vercel.json
Download .txt
SYMBOL INDEX (1561 symbols across 449 files)

FILE: .storybook/main.ts
  function getAbsolutePath (line 52) | function getAbsolutePath(value: string): any {

FILE: Models/ApiError.ts
  type ApiError (line 1) | type ApiError = {
  type LSAPIKnownErrorCode (line 11) | enum LSAPIKnownErrorCode {

FILE: Models/ApiResponse.ts
  class EmptyApiResponse (line 3) | class EmptyApiResponse {
    method constructor (line 4) | constructor(error?: ApiError) {
  class ApiResponse (line 11) | class ApiResponse<T> extends EmptyApiResponse {

FILE: Models/Balance.ts
  type GasProps (line 5) | type GasProps = {
  type TokenBalanceError (line 14) | type TokenBalanceError = {
  type TokenBalance (line 26) | type TokenBalance = {
  type NetworkBalance (line 36) | type NetworkBalance = {

FILE: Models/Exchange.ts
  class Exchange (line 3) | class Exchange {
  class ExchangeNetwork (line 15) | class ExchangeNetwork {

FILE: Models/LayerSwapAppSettings.ts
  class LayerSwapAppSettings (line 5) | class LayerSwapAppSettings {
    method constructor (line 6) | constructor(settings: LayerSwapSettings) {

FILE: Models/LayerSwapAuth.ts
  class AuthGetCodeResponse (line 1) | class AuthGetCodeResponse {

FILE: Models/LayerSwapSettings.ts
  class LayerSwapSettings (line 4) | class LayerSwapSettings {

FILE: Models/Network.ts
  type NetworkType (line 3) | enum NetworkType {
  class Network (line 15) | class Network {
  class NetworkWithTokens (line 32) | class NetworkWithTokens extends Network {
  class NetworkRoute (line 36) | class NetworkRoute extends Network {
  class Token (line 40) | class Token {
  class NetworkRouteToken (line 55) | class NetworkRouteToken extends Token {
  class Metadata (line 59) | class Metadata {

FILE: Models/Partner.ts
  class Partner (line 1) | class Partner {

FILE: Models/QueryParams.ts
  class PersistantQueryParams (line 2) | class PersistantQueryParams {
  class QueryParams (line 49) | class QueryParams extends PersistantQueryParams {

FILE: Models/RangeError.ts
  type SwapFailReasons (line 1) | enum SwapFailReasons {

FILE: Models/Route.ts
  type NetworkElement (line 4) | type NetworkElement = {
  type NetworkTokenElement (line 8) | type NetworkTokenElement = {
  type TitleElement (line 15) | type TitleElement = {
  type GroupedTokenElement (line 19) | type GroupedTokenElement = {
  type TokenSceletonElement (line 24) | type TokenSceletonElement = {
  type RowElement (line 27) | type RowElement = {}

FILE: Models/SwapStatus.ts
  type SwapStatus (line 1) | enum SwapStatus {

FILE: Models/Theme.ts
  type ThemeData (line 3) | type ThemeData = {
  type ThemeColor (line 23) | type ThemeColor = {
  type StatusColor (line 37) | type StatusColor = {
  constant THEME_COLORS (line 42) | const THEME_COLORS: { [key: string]: ThemeData } = {

FILE: Models/WalletConnectWallet.ts
  type WalletConnectWallet (line 3) | type WalletConnectWallet = {

FILE: Models/WalletProvider.ts
  type InternalConnector (line 4) | type InternalConnector = {
  type Wallet (line 18) | type Wallet = {
  type RequestAdditionalConnectorsParams (line 47) | type RequestAdditionalConnectorsParams = {
  type RequestAdditionalConnectorsResult (line 53) | type RequestAdditionalConnectorsResult = {
  type WalletProvider (line 59) | type WalletProvider = {
  type SelectAccountProps (line 82) | type SelectAccountProps = {

FILE: Models/Wizard.ts
  type FormSteps (line 3) | type FormSteps = "SwapForm" | "OffRampExchangeOAuth" | "ExchangeOAuth" |...
  type SwapSteps (line 5) | type SwapSteps = "Overview" | "Withdrawal" | "OffRampWithdrawal" | "Proc...
  type BaseWizard (line 7) | type BaseWizard = {
  type FormWizardSteps (line 11) | type FormWizardSteps = {
  type SwapWizardSteps (line 14) | type SwapWizardSteps = {
  type SwapCreateStep (line 18) | enum SwapCreateStep {
  type SwapWithdrawalStep (line 28) | enum SwapWithdrawalStep {
  type MenuStep (line 43) | enum MenuStep {
  type Steps (line 49) | type Steps = SwapWithdrawalStep | SwapCreateStep | MenuStep
  class WizardStep (line 61) | class WizardStep<T> {

FILE: components/AddressIcon/index.tsx
  type Props (line 5) | type Props = {

FILE: components/AddressIcon/jazzicon.mjs
  function generateIdenticon (line 10) | function generateIdenticon(diameter, seed) {
  function genShape (line 32) | function genShape(remainingColors, diameter, i, total, svg) {
  function genColor (line 62) | function genColor(colors) {
  function hueShift (line 70) | function hueShift(colors, generator) {

FILE: components/AddressIcon/jazzicon/index.js
  function generateIdenticon (line 11) | function generateIdenticon(diameter, seed) {
  function genShape (line 33) | function genShape(remainingColors, diameter, i, total, svg) {
  function genColor (line 63) | function genColor(colors) {
  function hueShift (line 71) | function hueShift(colors, generator) {

FILE: components/AddressIcon/jazzicon/mersenne-twister.js
  function MersenneTwister (line 72) | function MersenneTwister(seed) {

FILE: components/AddressIcon/jazzicon/paper.js
  function newPaper (line 1) | function newPaper(diameter, color) {

FILE: components/AddressIcon/mersenne-twister.mjs
  function MersenneTwister (line 28) | function MersenneTwister(seed) {

FILE: components/AddressIcon/paper.mjs
  function newPaper (line 1) | function newPaper(diameter, color) {

FILE: components/AvatarGroup.tsx
  type Props (line 3) | type Props = {

FILE: components/Campaigns/Details/Leaderboard.tsx
  type Props (line 16) | type Props = {

FILE: components/Campaigns/Details/Rewards.tsx
  type Props (line 15) | type Props = {

FILE: components/Campaigns/Details/index.tsx
  function CampaignDetails (line 18) | function CampaignDetails() {
  type BriefInformationProps (line 86) | type BriefInformationProps = {

FILE: components/Campaigns/index.tsx
  type CampaignProps (line 76) | type CampaignProps = {
  function IsCampaignActive (line 107) | function IsCampaignActive(campaign: Campaign) {

FILE: components/Carousel.tsx
  type CarouselItemProps (line 5) | interface CarouselItemProps {
  type CarouselProps (line 18) | interface CarouselProps {
  type CarouselRef (line 25) | type CarouselRef = {

FILE: components/ColorSchema.tsx
  type Props (line 4) | type Props = {

FILE: components/Common/AnimatedValue.tsx
  type AnimatedValueProps (line 4) | type AnimatedValueProps = {

FILE: components/Common/AverageCompletionTime.tsx
  type AverageCompletionTimeProps (line 3) | type AverageCompletionTimeProps = {

FILE: components/Common/ConnectWalletButton.tsx
  type Props (line 8) | interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> {

FILE: components/Common/CountDownTimer.tsx
  function timeStringToMilliseconds (line 67) | function timeStringToMilliseconds(timeString) {

FILE: components/Common/FormattedAverageCompletionTime.tsx
  type AverageCompletionTimeProps (line 3) | type AverageCompletionTimeProps = {

FILE: components/Common/LinkWithIcon.tsx
  type LinkWithIconProps (line 5) | interface LinkWithIconProps {

FILE: components/Common/NumFlowWithFallback.tsx
  type NumFlowProps (line 4) | type NumFlowProps = ComponentProps<typeof NumberFlow>;
  function getSupportsSnapshot (line 7) | function getSupportsSnapshot() {

FILE: components/Common/ReactPortal.tsx
  type Props (line 4) | type Props = {

FILE: components/Common/TypingEffect.tsx
  type TypingEffectProps (line 4) | type TypingEffectProps = {
  function TypingEffect (line 11) | function TypingEffect({ text = 'Typing Effect', onComplete, withShine = ...

FILE: components/ConnectNetwork.tsx
  type Props (line 5) | type Props = {

FILE: components/DTOs/SwapConfirmationFormValues.ts
  type SwapConfirmationFormValues (line 1) | interface SwapConfirmationFormValues {

FILE: components/DTOs/SwapFormValues.ts
  type SwapFormValues (line 4) | type SwapFormValues = {
  type SwapDirection (line 21) | type SwapDirection = "from" | "to";

FILE: components/ErrorFallback.tsx
  function ErrorFallback (line 12) | function ErrorFallback({ error, resetErrorBoundary }) {

FILE: components/FeeDetails/DepositMethod/index.tsx
  type DespositMethodItemProps (line 98) | type DespositMethodItemProps = {
  type DepositMethod (line 147) | type DepositMethod = {
  function GenerateDepositMethodMenuItems (line 152) | function GenerateDepositMethodMenuItems(network: Network, depositMethods...

FILE: components/FeeDetails/ReceiveAmounts.tsx
  type WillReceiveProps (line 7) | type WillReceiveProps = {

FILE: components/FeeDetails/Refuel.tsx
  type RefuelProps (line 13) | type RefuelProps = {

FILE: components/FeeDetails/RefuelModal.tsx
  type RefuelModalProps (line 10) | type RefuelModalProps = {

FILE: components/FeeDetails/Slippage.tsx
  type SlippageProps (line 11) | type SlippageProps = {
  constant HIGH_SLIPPAGE_THRESHOLD_PERCENT (line 16) | const HIGH_SLIPPAGE_THRESHOLD_PERCENT = 4.2;
  type QuickActionProps (line 135) | type QuickActionProps = {
  type SlippageInputProps (line 161) | type SlippageInputProps = {

FILE: components/FeeDetails/SwapQuote/DetailedEstimates.tsx
  type DetailedEstimatesProps (line 19) | type DetailedEstimatesProps = {
  type RowWrapperProps (line 51) | type RowWrapperProps = {
  type RateProps (line 191) | type RateProps = {

FILE: components/FeeDetails/SwapQuote/index.tsx
  type SwapValues (line 14) | interface SwapValues extends Omit<SwapFormValues, 'from' | 'to'> {
  type QuoteComponentProps (line 19) | interface QuoteComponentProps {

FILE: components/FeeDetails/index.tsx
  type SwapValues (line 23) | interface SwapValues extends Omit<SwapFormValues, 'from' | 'to'> {
  type QuoteComponentProps (line 28) | interface QuoteComponentProps {
  function QuoteDetails (line 39) | function QuoteDetails({ swapValues: values, quote, isQuoteLoading, rewar...

FILE: components/HeaderWithMenu/index.tsx
  type Props (line 9) | type Props = {
  function HeaderWithMenu (line 13) | function HeaderWithMenu({ goBack, contextualMenu }: Props) {

FILE: components/Input/Address/AddressPicker/AddressBook.tsx
  type AddressBookProps (line 12) | type AddressBookProps = {

FILE: components/Input/Address/AddressPicker/AddressButton.tsx
  type AddressButtonProps (line 7) | type AddressButtonProps = {

FILE: components/Input/Address/AddressPicker/AddressWithIcon.tsx
  type Props (line 16) | type Props = {
  type ExtendedAddressBaseProps (line 137) | type ExtendedAddressBaseProps = {
  type ExtendedAddressProps (line 152) | type ExtendedAddressProps = ExtendedAddressBaseProps
  type AddressDetailsPopoverProps (line 175) | type AddressDetailsPopoverProps = ExtendedAddressBaseProps
  type ActionButtonProps (line 332) | type ActionButtonProps = {

FILE: components/Input/Address/AddressPicker/ConnectedWallets.tsx
  type Props (line 11) | type Props = {
  type NotCompatibleWalletsProps (line 73) | type NotCompatibleWalletsProps = {

FILE: components/Input/Address/AddressPicker/ManualAddressInput.tsx
  type AddressInput (line 13) | type AddressInput = {

FILE: components/Input/Address/AddressPicker/index.tsx
  type AddressGroup (line 20) | enum AddressGroup {
  type AddressItem (line 27) | type AddressItem = {
  type AddressTriggerProps (line 35) | type AddressTriggerProps = {
  type Input (line 42) | interface Input {

FILE: components/Input/Address/ContractAddressNote.tsx
  type Props (line 7) | type Props = {

FILE: components/Input/Address/UrlAddressNote.tsx
  type Props (line 10) | type Props = {

FILE: components/Input/Address/index.tsx
  type AddressProps (line 4) | type AddressProps = {

FILE: components/Input/Amount/ExchangeAmountField.tsx
  type ExchangeAmountFieldProps (line 10) | interface ExchangeAmountFieldProps {
  function getTextWidth (line 90) | function getTextWidth(text: string = "", font: string): number {
  function getFontFromElement (line 101) | function getFontFromElement(el: HTMLElement | null): string {

FILE: components/Input/Amount/ExchangeReceiveAmount.tsx
  type ReceiveAmountProps (line 7) | type ReceiveAmountProps = {

FILE: components/Input/Amount/MinMax.tsx
  type MinMaxProps (line 15) | type MinMaxProps = {
  type ActionButtonProps (line 141) | type ActionButtonProps = React.DetailedHTMLProps<React.ButtonHTMLAttribu...

FILE: components/Input/Amount/PriceImpact.tsx
  type PriceImpactProps (line 8) | type PriceImpactProps = {

FILE: components/Input/Amount/ReceiveAmount.tsx
  type ReceiveAmountProps (line 9) | type ReceiveAmountProps = {

FILE: components/Input/Amount/helpers.ts
  type ResoleMaxAllowedAmountProps (line 5) | type ResoleMaxAllowedAmountProps = {

FILE: components/Input/Amount/index.tsx
  type AmountFieldProps (line 11) | interface AmountFieldProps {
  function getTextWidth (line 186) | function getTextWidth(text: string = '', font: string): number {
  function getFontFromElement (line 197) | function getFontFromElement(el: HTMLElement | null): string {
  function formatTokenAmount (line 203) | function formatTokenAmount(value: number, precision: number): string {

FILE: components/Input/CexPicker.tsx
  type CexPickerContentProps (line 83) | type CexPickerContentProps = {
  type ExchangeNetworkProps (line 128) | type ExchangeNetworkProps = {
  type SelectedNetworkDisplayProps (line 156) | type SelectedNetworkDisplayProps = {

FILE: components/Input/DestinationPicker.tsx
  type Props (line 13) | type Props = {

FILE: components/Input/DestinationWalletPicker.tsx
  type AdderssIconprops (line 55) | type AdderssIconprops = {

FILE: components/Input/NumericInput.tsx
  type Input (line 7) | type Input = {
  function limitDecimalPlaces (line 88) | function limitDecimalPlaces(e, count) {
  function ParseFloat (line 95) | function ParseFloat(str, val) {
  function replaceComma (line 101) | function replaceComma(e) {

FILE: components/Input/RoutePicker/Content.tsx
  type ContentProps (line 16) | type ContentProps = {

FILE: components/Input/RoutePicker/RouteSearch.tsx
  type RouteSearchProps (line 7) | type RouteSearchProps = {

FILE: components/Input/RoutePicker/RouterPickerWalletConnect.tsx
  type Props (line 120) | type Props = {

FILE: components/Input/RoutePicker/Routes.tsx
  type TokenItemProps (line 17) | type TokenItemProps = {
  type NetworkTokenItemProps (line 38) | type NetworkTokenItemProps = {
  type NetworkRouteItemProps (line 87) | type NetworkRouteItemProps = {
  type SelectedCurrencyDisplayProps (line 159) | type SelectedCurrencyDisplayProps = {
  type SelectedRouteDisplayProps (line 305) | type SelectedRouteDisplayProps = {

FILE: components/Input/RoutePicker/Rows/CollapsableHeader.tsx
  type Props (line 5) | type Props = {

FILE: components/Input/RoutePicker/Rows/CollapsibleRow.tsx
  type GenericAccordionRowProps (line 13) | type GenericAccordionRowProps = {
  type ChildWrapper (line 25) | type ChildWrapper = {

FILE: components/Input/RoutePicker/Rows/StickyHeader.tsx
  type StickyHeaderProps (line 7) | type StickyHeaderProps = {
  function StickyHeader (line 20) | function StickyHeader({

FILE: components/Input/RoutePicker/Rows/TitleRow.tsx
  type Props (line 6) | type Props = {

FILE: components/Input/RoutePicker/Rows/index.tsx
  type Props (line 11) | type Props = {
  function Row (line 24) | function Row({

FILE: components/Input/RoutePicker/TokenTitleDetails.tsx
  type TokenTitleWithBalanceProps (line 11) | type TokenTitleWithBalanceProps = {
  type TokenInfoTriggerProps (line 72) | type TokenInfoTriggerProps = {
  type NativeTokenTitleProps (line 88) | type NativeTokenTitleProps = {

FILE: components/Input/Search.tsx
  type SearchComponentProps (line 8) | type SearchComponentProps = DetailedHTMLProps<InputHTMLAttributes<HTMLIn...

FILE: components/Input/SourcePicker.tsx
  type Props (line 12) | type Props = {

FILE: components/Input/TransferCEX.tsx
  type Props (line 6) | type Props = {

FILE: components/LayerswapMenu/Menu.tsx
  type ItemType (line 59) | enum ItemType {
  type Target (line 64) | type Target = '_blank' | '_self'
  type MenuIemProps (line 66) | type MenuIemProps = {
  type FooterProps (line 96) | type FooterProps = {

FILE: components/LoadingCard.tsx
  type Props (line 3) | type Props = {

FILE: components/MessageComponent.tsx
  type iconStyle (line 5) | type iconStyle = 'red' | 'green' | 'yellow' | 'gray'
  class MessageComponentProps (line 7) | class MessageComponentProps {
  function constructIcons (line 13) | function constructIcons(icon: iconStyle) {

FILE: components/NavigatableList/NavigatableItem.tsx
  type NavigatableItemProps (line 6) | interface NavigatableItemProps {

FILE: components/NavigatableList/NavigatableList.tsx
  type RegisteredItem (line 15) | interface RegisteredItem {
  type StoreSnapshot (line 20) | interface StoreSnapshot {
  function createAutoDetectionStore (line 25) | function createAutoDetectionStore() {
  type NavigatableListProps (line 112) | interface NavigatableListProps {
  function NavigatableListRoot (line 120) | function NavigatableListRoot({

FILE: components/NavigatableList/context.ts
  type FocusedIndex (line 4) | type FocusedIndex =
  function focusedIndexEquals (line 9) | function focusedIndexEquals(a: FocusedIndex | null, b: FocusedIndex | nu...
  function focusedIndexToString (line 15) | function focusedIndexToString(idx: FocusedIndex): string {
  type NavigatableListStateContextType (line 19) | interface NavigatableListStateContextType {
  type NavigatableListUpdateContextType (line 24) | interface NavigatableListUpdateContextType {
  type NavigatableRegistrationContextType (line 29) | interface NavigatableRegistrationContextType {
  function useNavigatableListState (line 43) | function useNavigatableListState() {
  function useNavigatableListUpdate (line 51) | function useNavigatableListUpdate() {
  function useNavigatableRegistration (line 59) | function useNavigatableRegistration() {

FILE: components/NavigatableList/hooks.ts
  function useScrollIntoView (line 7) | function useScrollIntoView(isFocused: boolean, isKeyboardNavigating: boo...
  function useSpaceKeyClick (line 22) | function useSpaceKeyClick(onClick?: () => void, onKeyDown?: (e: React.Ke...
  function useHoverHandler (line 39) | function useHoverHandler(index: FocusedIndex, onMouseEnter?: () => void) {
  function useFocusHandler (line 56) | function useFocusHandler(onFocus?: () => void) {
  function useMergedRefs (line 70) | function useMergedRefs<T>(...refs: Array<React.Ref<T> | undefined>) {

FILE: components/NoCookies.tsx
  function NoCookies (line 6) | function NoCookies(props) {

FILE: components/QRCodeWallet.tsx
  type QRCodeModalProps (line 9) | type QRCodeModalProps = {

FILE: components/ReserveGasNote.tsx
  type BalanceWarningTooltipProps (line 6) | interface BalanceWarningTooltipProps {

FILE: components/ResizablePanel.tsx
  function ResizablePanel (line 5) | function ResizablePanel({ children, className }: { children: ReactNode, ...

FILE: components/Select/Command/CommandSelectWrapper.tsx
  type CommandSelectWrapperProps (line 8) | type CommandSelectWrapperProps = {
  function CommandSelectWrapper (line 27) | function CommandSelectWrapper<T>({

FILE: components/Select/Command/commandSelect.tsx
  type CommandSelectProps (line 20) | interface CommandSelectProps extends SelectProps {
  class SelectMenuItemGroup (line 31) | class SelectMenuItemGroup {
    method constructor (line 32) | constructor(init?: Partial<SelectMenuItemGroup>) {
  function CommandSelect (line 40) | function CommandSelect({ values, setValue, show, setShow, searchHint, va...
  type GroupProps (line 87) | type GroupProps = {
  type GroupItemProps (line 106) | type GroupItemProps = {

FILE: components/Select/Popover/PopoverSelect.tsx
  function PopoverSelect (line 5) | function PopoverSelect({ values, value, setValue }: SelectProps) {

FILE: components/Select/Popover/PopoverSelectWrapper.tsx
  type PopoverSelectWrapper (line 8) | type PopoverSelectWrapper = {
  function PopoverSelectWrapper (line 17) | function PopoverSelectWrapper<T>({

FILE: components/Select/Selector/Index.tsx
  type ContentChildProps (line 16) | type ContentChildProps = {
  type SelectContentProps (line 21) | type SelectContentProps = {
  type SelectTriggerProps (line 40) | type SelectTriggerProps = {

FILE: components/Select/Selector/SelectItem.tsx
  type SelectItemWrapperProps (line 5) | type SelectItemWrapperProps = {
  type SelectItemLogoProps (line 14) | type SelectItemLogoProps = {
  type SelectItemTitleProps (line 37) | type SelectItemTitleProps = {
  type SelectItemDetailedTitleProps (line 47) | type SelectItemDetailedTitleProps = {

FILE: components/Select/Shared/Props/SelectProps.tsx
  type SelectProps (line 3) | interface SelectProps {

FILE: components/Select/Shared/Props/selectMenuItem.tsx
  class SelectMenuItem (line 1) | class SelectMenuItem<T> implements ISelectMenuItem {
    method constructor (line 18) | constructor(baseObject: T, id: string, name: string, order: number, im...
  type ISelectMenuItem (line 30) | interface ISelectMenuItem {

FILE: components/Select/Shared/SelectItem.tsx
  function SelectItem (line 4) | function SelectItem({ item, underline }: { item: ISelectMenuItem, underl...

FILE: components/Swap/Form/ExchangeForm.tsx
  type Props (line 32) | type Props = {

FILE: components/Swap/Form/FormWrapper.tsx
  type NetworkToConnect (line 27) | type NetworkToConnect = {
  function FormWrapper (line 32) | function FormWrapper({ children, type, partner }: { children?: React.Rea...
  type SubmitProps (line 189) | type SubmitProps = {

FILE: components/Swap/Form/NetworkExchangeTabs.tsx
  type TabsContextType (line 8) | interface TabsContextType {
  type TabsProps (line 14) | interface TabsProps {
  type TabsListProps (line 27) | interface TabsListProps { children: ReactNode }
  type TabsTriggerProps (line 52) | interface TabsTriggerProps {
  type TabsContentProps (line 81) | interface TabsContentProps { value: string; children: ReactNode }

FILE: components/Swap/Form/NetworkForm.tsx
  type Props (line 32) | type Props = {

FILE: components/Swap/Form/index.tsx
  function Form (line 17) | function Form() {

FILE: components/Swap/Form/updateForm.ts
  function updateQueries (line 16) | function updateQueries({ formDataKey, formDataValue, }: { formDataKey: s...
  function updateForm (line 46) | async function updateForm<K extends keyof SwapFormValues>({ formDataKey,...
  function updateQueriesBulk (line 58) | function updateQueriesBulk(
  function updateFormBulk (line 96) | async function updateFormBulk(

FILE: components/Swap/FormButton.tsx
  type Props (line 8) | type Props = {

FILE: components/Swap/Step.tsx
  function renderStepIcon (line 7) | function renderStepIcon(step: StatusStep) {
  function Step (line 43) | function Step({ step, isLastStep }: { step: StatusStep, isLastStep: bool...

FILE: components/Swap/StepsComponent.tsx
  function Steps (line 4) | function Steps({ steps }: { steps: StatusStep[] }) {

FILE: components/Swap/Summary/Summary.tsx
  type SwapInfoProps (line 15) | type SwapInfoProps = Omit<SwapResponse, 'quote' | 'swap'> & {
  type RouteTokenPairProps (line 139) | type RouteTokenPairProps = {

FILE: components/Swap/Withdraw/Failed.tsx
  type Props (line 56) | type Props = {

FILE: components/Swap/Withdraw/ManualWithdraw.tsx
  type Props (line 29) | interface Props {

FILE: components/Swap/Withdraw/Processing/Processing.tsx
  type Props (line 27) | type Props = {

FILE: components/Swap/Withdraw/Processing/types.ts
  type ProgressStates (line 2) | type ProgressStates = {
  type Progress (line 10) | enum Progress {
  type ProgressStatus (line 16) | enum ProgressStatus {
  type StatusStep (line 24) | type StatusStep = {

FILE: components/Swap/Withdraw/QuoteUpdate.tsx
  type QuoteUpdatedProps (line 7) | interface QuoteUpdatedProps {
  function handleLimitsUpdate (line 47) | async function handleLimitsUpdate(params: {

FILE: components/Swap/Withdraw/SwapQuoteDetails.tsx
  type Props (line 11) | type Props = {

FILE: components/Swap/Withdraw/Wallet/Common/buttons.tsx
  type ChangeNetworkProps (line 79) | type ChangeNetworkProps = {
  type ButtonWrapperProps (line 148) | type ButtonWrapperProps = ComponentProps<typeof ButtonWrapper>;
  type SendFromWalletButtonProps (line 149) | type SendFromWalletButtonProps = Omit<ButtonWrapperProps, 'onClick'> & {

FILE: components/Swap/Withdraw/Wallet/Common/sharedTypes.ts
  type ActionData (line 3) | type ActionData = {
  type WithdrawPageProps (line 9) | type WithdrawPageProps = {
  type TransferProps (line 16) | type TransferProps = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/BitcoinWalletWithdraw/sendTransaction.ts
  type sendTransactionParams (line 8) | type sendTransactionParams = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/BitcoinWalletWithdraw/transactionBuilder/buildPsbt.ts
  constant MIN_FEE (line 9) | const MIN_FEE = 0n // sats, as BigInt
  function fetchUtxos (line 11) | async function fetchUtxos(
  function fetchAllRawTxs (line 20) | async function fetchAllRawTxs(
  function selectUtxos (line 35) | function selectUtxos(utxos: Utxo[], target: bigint): { selected: Utxo[];...
  function buildPsbt (line 50) | async function buildPsbt({

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/BitcoinWalletWithdraw/transactionBuilder/estimateFee.ts
  type RecommendedFeeResponse (line 13) | type RecommendedFeeResponse = {
  function fetchRecommendedFee (line 21) | async function fetchRecommendedFee(
  function calculateFee (line 29) | function calculateFee(numInputs: number, numOutputs: number, feePerByte:...

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/BitcoinWalletWithdraw/transactionBuilder/types.ts
  type TransactionBuilderParams (line 4) | type TransactionBuilderParams = {
  type Utxo (line 15) | interface Utxo {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/EVMWalletWithdraw/RPCUnhealthyMessage.tsx
  constant HEALTH_CHECK_INTERVAL (line 10) | const HEALTH_CHECK_INTERVAL = 1500 // 1.5 seconds
  type SuggestRpcResult (line 12) | type SuggestRpcResult = { success: true } | { success: false; error: str...
  type Props (line 14) | type Props = {
  type MessageContentProps (line 66) | type MessageContentProps = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/EVMWalletWithdraw/TransferToken.tsx
  type Props (line 17) | type Props = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/EVMWalletWithdraw/resolveError.tsx
  type ResolvedError (line 3) | type ResolvedError = "insufficient_funds" | "transaction_rejected"

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/EVMWalletWithdraw/transactionMessage.tsx
  type TransactionMessageProps (line 7) | type TransactionMessageProps = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/FuelWalletWithdrawal.tsx
  type FuelPrepareData (line 55) | type FuelPrepareData = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/Loopring/ActivationTokentPicker.tsx
  type Props (line 9) | type Props = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/Loopring/hooks.tsx
  type FeeData (line 79) | type FeeData = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/SVMWalletWithdraw/transactionSender.ts
  type TransactionSenderAndConfirmationWaiterArgs (line 10) | type TransactionSenderAndConfirmationWaiterArgs = {
  constant SEND_OPTIONS (line 16) | const SEND_OPTIONS = {
  function transactionSenderAndConfirmationWaiter (line 20) | async function transactionSenderAndConfirmationWaiter({

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/TempoWalletWithdraw/TransferToken.tsx
  type Props (line 17) | type Props = {

FILE: components/Swap/Withdraw/Wallet/WithdrawalProviders/TronWalletWithdraw.tsx
  type BuildIniitialTransactionProps (line 105) | type BuildIniitialTransactionProps = {

FILE: components/Swap/Withdraw/Wallet/index.tsx
  type Props (line 56) | type Props = {

FILE: components/Swap/Withdraw/WalletTransferButton.tsx
  type Props (line 5) | type Props = {

FILE: components/Swap/Withdraw/WalletTransferContent.tsx
  type Props (line 15) | type Props = {

FILE: components/Swap/Withdraw/messages/Message.tsx
  type WalletMessageProps (line 7) | type WalletMessageProps = {

FILE: components/Swap/index.tsx
  type Props (line 13) | type Props = {

FILE: components/SwapHistory/Filters/CheckboxRow.tsx
  type CheckboxRowProps (line 4) | type CheckboxRowProps = {

FILE: components/SwapHistory/Filters/ClearAllButton.tsx
  type ClearAllButtonProps (line 3) | type ClearAllButtonProps = {

FILE: components/SwapHistory/Filters/NetworksDropdown.tsx
  type NetworksDropdownProps (line 10) | type NetworksDropdownProps = {

FILE: components/SwapHistory/Filters/NoMatches.tsx
  type NoMatchesProps (line 3) | type NoMatchesProps = { onClear: () => void }

FILE: components/SwapHistory/Filters/SearchResult.tsx
  type SearchResultProps (line 9) | type SearchResultProps = {

FILE: components/SwapHistory/Filters/WalletsDropdown.tsx
  type WalletsDropdownProps (line 11) | type WalletsDropdownProps = {
  type Row (line 18) | type Row = {

FILE: components/SwapHistory/Filters/filterSwaps.ts
  constant INCOMPLETE_STATUSES (line 4) | const INCOMPLETE_STATUSES: string[] = [

FILE: components/SwapHistory/Filters/index.tsx
  type FiltersProps (line 9) | type FiltersProps = {

FILE: components/SwapHistory/Filters/types.ts
  type FilterNetworkOption (line 1) | type FilterNetworkOption = {

FILE: components/SwapHistory/History.tsx
  type ListProps (line 29) | type ListProps = {
  type SwapHistoryData (line 122) | type SwapHistoryData = ReturnType<typeof useSwapHistoryData>
  type SwapsListProps (line 124) | type SwapsListProps = {
  type HistoryEmptyStateProps (line 379) | type HistoryEmptyStateProps = {
  type BlankHistoryProps (line 400) | type BlankHistoryProps = {
  type DaysAgoProps (line 438) | type DaysAgoProps = {
  function DaysAgo (line 441) | function DaysAgo({ dateInput }: DaysAgoProps) {

FILE: components/SwapHistory/HistorySummary.tsx
  type SwapInfoProps (line 15) | type SwapInfoProps = {

FILE: components/SwapHistory/StatusIcons.tsx
  function StatusIcon (line 5) | function StatusIcon({ swap, withBg, short }: { swap: SwapItem, withBg?: ...
  type IconComponentProps (line 106) | type IconComponentProps = {

FILE: components/SwapHistory/SwapDetailsComponent.tsx
  type Props (line 18) | type Props = {

FILE: components/SwapHistory/index.tsx
  function TransactionsHistory (line 4) | function TransactionsHistory() {

FILE: components/Tooltips/ClickTooltip.tsx
  type Props (line 6) | type Props = {

FILE: components/Wallet/ConnectedWallets.tsx
  type WalletsIconsProps (line 46) | type WalletsIconsProps = {

FILE: components/Wallet/WalletsList.tsx
  type Props (line 17) | type Props = {
  type WalletItemProps (line 78) | type WalletItemProps = {
  type NestedWalletAddressProps (line 230) | type NestedWalletAddressProps = {
  function hasNetworkIcon (line 317) | function hasNetworkIcon(w: AccountIdentity | Wallet): w is Wallet & { ne...
  function hasDisconnect (line 320) | function hasDisconnect(w: AccountIdentity | Wallet): w is Wallet & { dis...
  function isLoading (line 323) | function isLoading(w: AccountIdentity | Wallet): w is Wallet & { isLoadi...

FILE: components/WalletModal/Connector.tsx
  type Connector (line 7) | type Connector = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElemen...

FILE: components/WalletModal/ConnectorsList.tsx
  type ProviderPaginationState (line 18) | type ProviderPaginationState = {
  type RequestCapableWalletProvider (line 26) | type RequestCapableWalletProvider = WalletProvider & {
  constant DEFAULT_BROWSE_PAGE_SIZE (line 30) | const DEFAULT_BROWSE_PAGE_SIZE = 40
  constant SEARCH_PAGE_SIZE (line 31) | const SEARCH_PAGE_SIZE = 100

FILE: components/WalletModal/MultichainConnectorPicker.tsx
  type MultichainConnectorModalProps (line 7) | type MultichainConnectorModalProps = {

FILE: components/WalletModal/index.tsx
  type WalletModalConnector (line 4) | type WalletModalConnector = InternalConnector & {
  type ModalWalletProvider (line 17) | type ModalWalletProvider = WalletProvider & {
  type SharedType (line 21) | type SharedType = { provider?: WalletProvider, connectCallback: (value: ...
  type ConnectModalContextType (line 23) | type ConnectModalContextType = {
  function WalletModalProvider (line 41) | function WalletModalProvider({ children }) {

FILE: components/WalletModal/utils.ts
  function removeDuplicatesWithKey (line 1) | function removeDuplicatesWithKey(arr: any[], key: string) {
  function sortRecentConnectors (line 38) | function sortRecentConnectors(a: { name: string, type?: string }, b: { n...

FILE: components/WalletProviders/ActiveEvmAccount.tsx
  type ActiveAccountState (line 4) | type ActiveAccountState = {
  type Props (line 14) | type Props = {
  function useActiveEvmAccount (line 41) | function useActiveEvmAccount() {

FILE: components/WalletProviders/ActiveParadexAccount.tsx
  type ActiveAccountState (line 6) | type ActiveAccountState = {
  type Account (line 13) | type Account = {
  type Props (line 19) | type Props = {
  function useActiveParadexAccount (line 60) | function useActiveParadexAccount() {

FILE: components/WalletProviders/BitcoinProvider.tsx
  function useBitcoinConnectors (line 58) | function useBitcoinConnectors() {
  function createDefaultBigmiConfig (line 104) | function createDefaultBigmiConfig(network?: NetworkWithTokens) {

FILE: components/WalletProviders/FuelProvider.tsx
  constant HOST_URL (line 11) | const HOST_URL = 'https://api.bako.global';

FILE: components/WalletProviders/ImtblPassportProvider.tsx
  constant PUBLISHABLE_KEY (line 4) | const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_IMMUTABLE_PUBLISHABLE_KEY;
  constant CLIENT_ID (line 5) | const CLIENT_ID = process.env.NEXT_PUBLIC_IMMUTABLE_CLIENT_ID;
  function ImtblPassportProvider (line 31) | function ImtblPassportProvider({ children }: { children: JSX.Element | J...

FILE: components/WalletProviders/SolanaProvider.tsx
  constant SOLANA_NETWORK (line 10) | const SOLANA_NETWORK = process.env.NEXT_PUBLIC_API_VERSION == 'sandbox' ...
  function SolanaProvider (line 12) | function SolanaProvider({ children }: { children: ReactNode }) {

FILE: components/WalletProviders/StarknetProvider.tsx
  class DiscoveryConnector (line 11) | class DiscoveryConnector extends Connector {
    method constructor (line 15) | constructor(wallet, store) {
    method id (line 21) | get id() {
    method icon (line 25) | get icon() {
    method name (line 32) | get name() {
    method available (line 36) | available() {
    method connect (line 40) | connect(): any {
    method wallet (line 45) | get wallet() {
    method disconnect (line 49) | disconnect(): any {
    method account (line 53) | account(): any {
    method ready (line 56) | ready(): Promise<boolean> {
    method chainId (line 59) | chainId(): Promise<bigint> {
    method request (line 62) | request<T extends RpcMessage["type"]>(call: RequestFnCall<T>): Promise...

FILE: components/WalletProviders/TonConnectProvider.tsx
  function componentToHex (line 8) | function componentToHex(c: number) {

FILE: components/WalletProviders/TronProvider.tsx
  function TronProvider (line 4) | function TronProvider({ children }: { children: React.ReactNode }) {

FILE: components/WalletProviders/Wagmi.tsx
  type Props (line 17) | type Props = {
  function WagmiComponent (line 61) | function WagmiComponent({ children }: Props) {

FILE: components/WarningMessage.tsx
  type messageType (line 6) | type messageType = 'warning' | 'informing'
  type Props (line 8) | type Props = {
  function constructIcons (line 14) | function constructIcons(messageType: messageType) {

FILE: components/Widget/Content.tsx
  type ContetProps (line 1) | type ContetProps = {

FILE: components/Widget/Footer.tsx
  type FooterProps (line 27) | type FooterProps = {

FILE: components/Widget/Index.tsx
  type Props (line 12) | type Props = {

FILE: components/Wizard/Wizard.tsx
  type Props (line 6) | type Props = {
  function handleResize (line 19) | function handleResize() {

FILE: components/Wizard/WizardItem.tsx
  type Props (line 6) | type Props = {

FILE: components/backgroundField.tsx
  type Props (line 7) | type Props = {

FILE: components/banner.tsx
  type BannerProps (line 4) | interface BannerProps {
  function onClickClose (line 18) | function onClickClose() {

FILE: components/buttons/copyButton.tsx
  type CopyButtonProps (line 8) | interface CopyButtonProps {

FILE: components/buttons/exploreButton.tsx
  type ExploreButtonProps (line 6) | interface ExploreButtonProps extends AnchorHTMLAttributes<HTMLAnchorElem...

FILE: components/buttons/iconButton.tsx
  type IconButtonProps (line 4) | interface IconButtonProps extends Omit<ComponentProps<'button'>, 'color'...

FILE: components/buttons/secondaryButton.tsx
  type buttonSize (line 5) | type buttonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
  type SecondaryButtonProps (line 7) | type SecondaryButtonProps = {

FILE: components/buttons/submitButton.tsx
  type buttonStyle (line 5) | type buttonStyle = 'outline' | 'filled' | 'secondary';
  type buttonSize (line 6) | type buttonSize = 'small' | 'medium' | 'large';
  type text_align (line 7) | type text_align = 'center' | 'left'
  type button_align (line 8) | type button_align = 'left' | 'right'
  class SubmitButtonProps (line 10) | class SubmitButtonProps {
  type DoubleLineTextProps (line 55) | type DoubleLineTextProps = {

FILE: components/buttons/toggleButton.tsx
  class ToggleButtonProps (line 5) | class ToggleButtonProps {

FILE: components/cardContainer.tsx
  function CardContainer (line 1) | function CardContainer(props) {

FILE: components/docInIframe.tsx
  type Props (line 5) | type Props = {
  function DocIframe (line 10) | function DocIframe({ URl, onConfirm, className }: Props) {

FILE: components/guideLink.tsx
  function GuideLink (line 8) | function GuideLink({ userGuideUrl, text, button, buttonClassNames }: { u...

FILE: components/layout.tsx
  type Props (line 23) | type Props = {
  function Layout (line 30) | function Layout({ children, settings, themeData }: Props) {

FILE: components/maintanance/maintanance.tsx
  function MaintananceContent (line 7) | function MaintananceContent() {

FILE: components/modal/leaflet.tsx
  type LeafletHeight (line 8) | type LeafletHeight = 'fit' | 'full' | '80%' | '90%';
  type LeafletPosition (line 11) | type LeafletPosition = 'absolute' | 'fixed';
  type LeafletProps (line 13) | interface LeafletProps {

FILE: components/modal/modal.tsx
  type ModalProps (line 7) | interface ModalProps {

FILE: components/modal/modalWithoutAnimation.tsx
  type ModalProps (line 8) | type ModalProps = {
  type ContentChildProps (line 36) | type ContentChildProps = {
  type ModalContentProps (line 41) | type ModalContentProps = {
  type ModalTriggerProps (line 107) | type ModalTriggerProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement...
  function openModal (line 119) | function openModal() {

FILE: components/modal/vaul/browser.ts
  function isMobileFirefox (line 1) | function isMobileFirefox(): boolean | undefined {
  function isMac (line 10) | function isMac(): boolean | undefined {
  function isIPhone (line 14) | function isIPhone(): boolean | undefined {
  function isSafari (line 18) | function isSafari(): boolean | undefined {
  function isIPad (line 22) | function isIPad(): boolean | undefined {
  function isIOS (line 30) | function isIOS(): boolean | undefined {
  function testPlatform (line 34) | function testPlatform(re: RegExp): boolean | undefined {

FILE: components/modal/vaul/constants.ts
  constant TRANSITIONS (line 1) | const TRANSITIONS = {
  constant VELOCITY_THRESHOLD (line 6) | const VELOCITY_THRESHOLD = 0.1;
  constant CLOSE_THRESHOLD (line 8) | const CLOSE_THRESHOLD = 0.1;
  constant SCROLL_LOCK_TIMEOUT (line 10) | const SCROLL_LOCK_TIMEOUT = 100;
  constant BORDER_RADIUS (line 12) | const BORDER_RADIUS = 8;
  constant NESTED_DISPLACEMENT (line 14) | const NESTED_DISPLACEMENT = 16;
  constant WINDOW_TOP_OFFSET (line 16) | const WINDOW_TOP_OFFSET = 26;
  constant DRAG_CLASS (line 18) | const DRAG_CLASS = 'vaul-dragging';

FILE: components/modal/vaul/context.ts
  type DrawerContextValue (line 4) | interface DrawerContextValue {

FILE: components/modal/vaul/helpers.ts
  type Style (line 3) | interface Style {
  function isInView (line 9) | function isInView(el: HTMLElement): boolean {
  function set (line 23) | function set(el: Element | HTMLElement | null | undefined, styles: Style...
  function reset (line 42) | function reset(el: Element | HTMLElement | null, prop?: string) {
  function getTranslate (line 72) | function getTranslate(element: HTMLElement, direction: DrawerDirection):...
  function dampenValue (line 90) | function dampenValue(v: number) {
  function assignStyle (line 94) | function assignStyle(element: HTMLElement | null | undefined, style: Par...
  function chain (line 108) | function chain<T>(...fns: T[]) {

FILE: components/modal/vaul/index.tsx
  type WithFadeFromProps (line 28) | interface WithFadeFromProps {
  type WithoutFadeFromProps (line 41) | interface WithoutFadeFromProps {
  type DialogProps (line 51) | type DialogProps = {
  function Root (line 140) | function Root({
  type ContentProps (line 828) | type ContentProps = React.ComponentPropsWithoutRef<typeof DialogPrimitiv...
  function handleOnPointerUp (line 892) | function handleOnPointerUp(event: React.PointerEvent<HTMLDivElement> | n...
  type HandleProps (line 986) | type HandleProps = React.ComponentPropsWithoutRef<'div'> & {
  constant LONG_HANDLE_PRESS_TIMEOUT (line 990) | const LONG_HANDLE_PRESS_TIMEOUT = 250;
  constant DOUBLE_TAP_TIMEOUT (line 991) | const DOUBLE_TAP_TIMEOUT = 120;
  function handleStartCycle (line 1013) | function handleStartCycle() {
  function handleCycleSnapPoints (line 1024) | function handleCycleSnapPoints() {
  function handleStartInteraction (line 1053) | function handleStartInteraction() {
  function handleCancelInteraction (line 1060) | function handleCancelInteraction() {
  function NestedRoot (line 1095) | function NestedRoot({ onDrag, onOpenChange, ...rest }: DialogProps) {
  type PortalProps (line 1123) | type PortalProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive...
  function Portal (line 1125) | function Portal(props: PortalProps) {

FILE: components/modal/vaul/types.ts
  type DrawerDirection (line 1) | type DrawerDirection = 'top' | 'bottom' | 'left' | 'right';
  type SnapPoint (line 2) | interface SnapPoint {
  type AnyFunction (line 7) | type AnyFunction = (...args: any) => any;

FILE: components/modal/vaul/use-composed-refs.ts
  type PossibleRef (line 5) | type PossibleRef<T> = React.Ref<T> | undefined;
  function setRef (line 11) | function setRef<T>(ref: PossibleRef<T>, value: T) {
  function composeRefs (line 23) | function composeRefs<T>(...refs: PossibleRef<T>[]) {
  function useComposedRefs (line 31) | function useComposedRefs<T>(...refs: PossibleRef<T>[]) {

FILE: components/modal/vaul/use-controllable-state.ts
  type UseControllableStateParams (line 5) | type UseControllableStateParams<T> = {
  type SetStateFn (line 11) | type SetStateFn<T> = (prevState?: T) => T;
  function useCallbackRef (line 13) | function useCallbackRef<T extends (...args: any[]) => any>(callback: T |...
  function useUncontrolledState (line 24) | function useUncontrolledState<T>({ defaultProp, onChange }: Omit<UseCont...
  function useControllableState (line 39) | function useControllableState<T>({ prop, defaultProp, onChange = () => {...

FILE: components/modal/vaul/use-position-fixed.ts
  function usePositionFixed (line 15) | function usePositionFixed({

FILE: components/modal/vaul/use-prevent-scroll.ts
  constant KEYBOARD_BUFFER (line 6) | const KEYBOARD_BUFFER = 24;
  type PreventScrollOptions (line 10) | interface PreventScrollOptions {
  function chain (line 16) | function chain(...callbacks: any[]): (...args: any[]) => void {
  function isScrollable (line 29) | function isScrollable(node: Element): boolean {
  function getScrollParent (line 34) | function getScrollParent(node: Element): Element {
  function usePreventScroll (line 68) | function usePreventScroll(options: PreventScrollOptions = {}) {
  function preventScrollMobileSafari (line 118) | function preventScrollMobileSafari() {
  function setStyle (line 243) | function setStyle(element: HTMLElement, style: keyof React.CSSProperties...
  function addEvent (line 257) | function addEvent<K extends keyof GlobalEventHandlersEventMap>(
  function scrollIntoView (line 272) | function scrollIntoView(target: Element) {
  function isInput (line 294) | function isInput(target: Element) {

FILE: components/modal/vaul/use-scale-background.ts
  function useScaleBackground (line 8) | function useScaleBackground() {

FILE: components/modal/vaul/use-snap-points.ts
  function useSnapPoints (line 7) | function useSnapPoints({

FILE: components/modal/vaulModal.tsx
  type VaulDrawerProps (line 12) | type VaulDrawerProps = {
  type Props (line 286) | type Props = {

FILE: components/navbar.tsx
  function Navbar (line 4) | function Navbar() {

FILE: components/sendFeedback.tsx
  type SendFeedbackFormValues (line 8) | interface SendFeedbackFormValues {
  type Props (line 12) | type Props = {

FILE: components/shadcn/accordion.tsx
  type AccordionContextValue (line 5) | interface AccordionContextValue {
  type AccordionProps (line 14) | interface AccordionProps {
  type AccordionItemContextValue (line 118) | interface AccordionItemContextValue {
  type AccordionContentProps (line 133) | interface AccordionContentProps extends React.HTMLAttributes<HTMLDivElem...

FILE: components/shadcn/popover.tsx
  function Popover (line 7) | function Popover({
  function PopoverTrigger (line 13) | function PopoverTrigger({
  function PopoverContent (line 19) | function PopoverContent({
  function PopoverAnchor (line 42) | function PopoverAnchor({

FILE: components/shadcn/tooltip.tsx
  function TooltipProvider (line 7) | function TooltipProvider({
  type TooltipProps (line 20) | type TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root> & {
  function Tooltip (line 29) | function Tooltip({
  function TooltipTrigger (line 70) | function TooltipTrigger({
  type TooltipContentProps (line 92) | type TooltipContentProps = React.ComponentProps<typeof TooltipPrimitive....
  function TooltipContent (line 97) | function TooltipContent({
  function TooltipArrow (line 123) | function TooltipArrow({ className, ...props }: React.ComponentProps<type...

FILE: components/swapComponent.tsx
  function updatePendingCount (line 17) | function updatePendingCount(useSWRNext) {

FILE: components/themeWrapper.tsx
  type Props (line 5) | type Props = {
  function ThemeWrapper (line 8) | function ThemeWrapper({ children }: Props) {

FILE: components/utils/GoHome.tsx
  type Props (line 11) | interface Props {

FILE: components/utils/RoundDecimals.ts
  function roundDecimals (line 1) | function roundDecimals(value: number, decimals: number) {
  function truncateDecimals (line 8) | function truncateDecimals(value: number, decimals = 0) {
  function truncateDecimalsToFloor (line 26) | function truncateDecimalsToFloor(number: number, decimalPlaces: number) {
  function findIndexOfFirstNonZeroAfterComma (line 31) | function findIndexOfFirstNonZeroAfterComma(number) {
  function isScientific (line 54) | function isScientific(x) {

FILE: components/utils/ShortenString.tsx
  function shortenString (line 8) | function shortenString(str: string) {

FILE: components/utils/classNames.ts
  function classNames (line 1) | function classNames(...classes: (string | boolean | undefined)[]): string {

FILE: components/utils/convertSvgComponentToBase64.tsx
  function convertSvgComponentToBase64 (line 3) | function convertSvgComponentToBase64(Component, props = {}) {

FILE: components/utils/formatUsdAmount.ts
  function formatUsd (line 1) | function formatUsd(amount: number | undefined | null): string {
  function floorUsd (line 14) | function floorUsd(value: number): string {
  function ceilUsd (line 22) | function ceilUsd(value: number): string {

FILE: components/utils/inIframe.ts
  function inIframe (line 1) | function inIframe () {

FILE: components/utils/isGuid.ts
  function isGuid (line 1) | function isGuid(stringToTest: string) {

FILE: components/utils/numbers.ts
  function isDiffByPercent (line 1) | function isDiffByPercent(a, b, perc) {

FILE: components/utils/resolveSwapPhase.ts
  type SwapPhase (line 14) | enum SwapPhase {
  type ResolveSwapPhaseInput (line 28) | type ResolveSwapPhaseInput = {
  type StepStatuses (line 35) | type StepStatuses = {
  type ResolvedSwapStatus (line 42) | type ResolvedSwapStatus = {
  constant TERMINAL_PHASES (line 58) | const TERMINAL_PHASES: ReadonlySet<SwapPhase> = new Set([
  constant NO_POLL_PHASES (line 66) | const NO_POLL_PHASES: ReadonlySet<SwapPhase> = new Set([
  function resolveSwapPhase (line 75) | function resolveSwapPhase(input: ResolveSwapPhaseInput): ResolvedSwapSta...
  function resolvePhase (line 149) | function resolvePhase(args: {
  function resolveStepStatuses (line 187) | function resolveStepStatuses(args: {
  function resolveGeneralStatus (line 257) | function resolveGeneralStatus(args: {
  constant BACKEND_TO_TX_STATUS (line 297) | const BACKEND_TO_TX_STATUS: Record<BackendTransactionStatus, Transaction...
  function resolveSwapInputTxStatus (line 304) | function resolveSwapInputTxStatus(
  function transactionStatusToProgressStatus (line 321) | function transactionStatusToProgressStatus(
  function formatElapsedTime (line 336) | function formatElapsedTime(inputTx: Transaction | undefined, outputTx: T...

FILE: components/utils/timeCalculations.ts
  function getSecondsToTomorrow (line 1) | function getSecondsToTomorrow() {
  function calculateSeconds (line 12) | function calculateSeconds(time: string) {

FILE: components/utils/upperCaseKeys.ts
  function upperCaseKeys (line 1) | function upperCaseKeys(obj: object) {

FILE: components/validationError/AdjustAmountButton.tsx
  type AdjustAmountButtonProps (line 4) | interface AdjustAmountButtonProps {

FILE: components/validationError/ContractAddressValidationCache.tsx
  type Props (line 6) | interface Props {

FILE: components/validationError/ErrorDisplay.tsx
  type ErrorDisplayProps (line 3) | interface ErrorDisplayProps {

FILE: components/validationError/RefreshBalanceButton.tsx
  constant MIN_SPIN_DURATION (line 4) | const MIN_SPIN_DURATION = 1000;
  type RefreshBalanceButtonProps (line 6) | interface RefreshBalanceButtonProps {

FILE: components/validationError/constants.ts
  constant ICON_CLASSES_WARNING (line 1) | const ICON_CLASSES_WARNING = 'w-5 h-5 text-warning-foreground';

FILE: context/asyncModal.tsx
  type AsyncModalProps (line 7) | interface AsyncModalProps extends VaulDrawerProps {
  type AsyncModalContextType (line 37) | type AsyncModalContextType = {

FILE: context/formWizardProvider.tsx
  type Direction (line 8) | type Direction = "back" | "forward"
  type StepError (line 10) | type StepError<T> = {
  type WizardProvider (line 15) | type WizardProvider<T> = {
  type UpdateInterface (line 28) | type UpdateInterface<T> = {
  type Props (line 39) | type Props<T> = {
  function useFormWizardState (line 77) | function useFormWizardState<T>() {
  function useFormWizardaUpdate (line 86) | function useFormWizardaUpdate<T>() {

FILE: context/loadingContext.tsx
  type Reg (line 5) | type Reg = {
  type ContextType (line 9) | type ContextType = {
  function LoadingProvider (line 15) | function LoadingProvider({ children }) {
  function useLoadingState (line 34) | function useLoadingState() {

FILE: context/query.tsx
  function mapLegacyQueryParams (line 14) | function mapLegacyQueryParams(params: QueryParams): QueryParams {
  function useQueryState (line 29) | function useQueryState() {

FILE: context/settings.tsx
  type SettingsState (line 5) | type SettingsState = LayerSwapAppSettings & { isEmbedded?: boolean }
  function useSettingsState (line 22) | function useSettingsState() {

FILE: context/snapPointsContext.tsx
  type SnapElement (line 3) | type SnapElement = {
  type SnapPointsState (line 9) | type SnapPointsState = {
  function sumBeforeIndex (line 56) | function sumBeforeIndex(arr, n) {
  function useSnapPoints (line 91) | function useSnapPoints() {

FILE: context/swap.tsx
  type UpdateSwapInterface (line 29) | type UpdateSwapInterface = {
  type SwapContextData (line 43) | type SwapContextData = {
  function SwapDataProvider (line 62) | function SwapDataProvider({ children, initialSwapData }: { children: Rea...
  function useSwapDataState (line 300) | function useSwapDataState() {
  function useSwapDataUpdate (line 309) | function useSwapDataUpdate() {

FILE: context/swapAccounts.tsx
  type PickerAccountsProviderProps (line 14) | type PickerAccountsProviderProps = {
  type SwapAccountsContextType (line 18) | type SwapAccountsContextType = {
  type SwapAccountsUpdateContextType (line 23) | type SwapAccountsUpdateContextType = {
  type BaseAccountIdentity (line 28) | type BaseAccountIdentity = {
  type AccountIdentity (line 34) | type AccountIdentity = BaseAccountIdentity & {
  type AccountIdentityWithSupportedNetworks (line 42) | type AccountIdentityWithSupportedNetworks = AccountIdentity & {
  function SwapAccountsProvider (line 47) | function SwapAccountsProvider({ children }: PickerAccountsProviderProps) {
  function useSwapAccounts (line 159) | function useSwapAccounts(direction: SwapDirection) {
  function useSelectedAccount (line 171) | function useSelectedAccount(direction: SwapDirection, networkName: strin...
  function useNetworkBalanceKey (line 187) | function useNetworkBalanceKey(direction: SwapDirection, networkName: str...
  function useNetworkBalance (line 193) | function useNetworkBalance(direction: SwapDirection, networkName: string...
  function useManualDestAddresses (line 199) | function useManualDestAddresses() {
  function useSelectSwapAccount (line 203) | function useSelectSwapAccount(direction: SwapDirection) {
  function hasWallet (line 212) | function hasWallet(
  function ResolveWalletSwapAccount (line 218) | function ResolveWalletSwapAccount(provider: WalletProvider, wallet: Wall...
  function ResolveManualSwapAccount (line 233) | function ResolveManualSwapAccount(provider: WalletProvider, address: str...

FILE: context/timerContext.tsx
  type DataContextType (line 7) | type DataContextType = {
  function TimerProvider (line 13) | function TimerProvider({ children }) {
  function useTimerState (line 45) | function useTimerState() {

FILE: context/validationContext.tsx
  type ValidationDetails (line 14) | interface ValidationDetails {
  type ValidationContextType (line 20) | interface ValidationContextType {

FILE: context/withdrawalContext.tsx
  type WalletWithdrawalContextValue (line 3) | type WalletWithdrawalContextValue = {
  function useWalletWithdrawalState (line 18) | function useWalletWithdrawalState() {

FILE: eslint-plugins/eslint-plugin-no-conditional-literals-in-jsx/rules/no-conditional-literals-in-jsx.js
  method JSXExpressionContainer (line 18) | JSXExpressionContainer(node) {

FILE: eslint-plugins/eslint-plugin-no-conditional-literals-in-jsx/rules/no-unwrapped-jsx-text.js
  constant RULE_DESCRIPTION (line 16) | const RULE_DESCRIPTION = 'JSX text that share a common parent with other...
  method JSXExpressionContainer (line 36) | JSXExpressionContainer(element) {
  method JSXText (line 86) | JSXText(element) {

FILE: helpers/accountSelectHelper.ts
  function SwitchWalletAccount (line 3) | function SwitchWalletAccount(props: SelectAccountProps, provider: Wallet...

FILE: helpers/balanceHelper.ts
  function getTotalBalanceInUSD (line 11) | function getTotalBalanceInUSD(networkBalance: NetworkBalance, network: N...

FILE: helpers/getSettings.ts
  function getServerSideProps (line 5) | async function getServerSideProps(context) {

FILE: helpers/routes.ts
  type IncludeOptions (line 62) | type IncludeOptions = {
  type ResolveRoutesURLForSelectedTokenProps (line 67) | type ResolveRoutesURLForSelectedTokenProps = {

FILE: helpers/settingsCompression.ts
  type CompactRouteToken (line 6) | type CompactRouteToken = {
  type CompactRoute (line 14) | type CompactRoute = {
  type CompressedLayerSwapSettings (line 22) | type CompressedLayerSwapSettings = {
  type EncodedLayerSwapSettings (line 30) | type EncodedLayerSwapSettings = {
  type MaybeCompressedSettings (line 36) | type MaybeCompressedSettings = LayerSwapSettings | CompressedLayerSwapSe...
  function bytesToBase64 (line 40) | function bytesToBase64(bytes: Uint8Array): string {
  function base64ToBytes (line 54) | function base64ToBytes(value: string): Uint8Array {
  function compactRouteToken (line 67) | function compactRouteToken(token: NetworkRouteToken): CompactRouteToken {
  function compactRoute (line 77) | function compactRoute(route: NetworkRoute): CompactRoute {
  function compactSettings (line 92) | function compactSettings(settings: LayerSwapSettings | null | undefined)...
  function isEncodedSettings (line 106) | function isEncodedSettings(settings: MaybeCompressedSettings | null | un...
  function encodeSettingsForSSR (line 110) | function encodeSettingsForSSR(settings: LayerSwapSettings | null | undef...
  function isCompressedSettings (line 134) | function isCompressedSettings(settings: MaybeCompressedSettings | null |...
  function inflateRouteToken (line 138) | function inflateRouteToken(
  function inflateRoutes (line 163) | function inflateRoutes(
  function inflateSettings (line 202) | function inflateSettings(settings: MaybeCompressedSettings | null | unde...

FILE: helpers/storageAvailable.ts
  type storageType (line 1) | type storageType = 'localStorage' |  'sessionStorage';
  function checkStorageIsAvailable (line 3) | function checkStorageIsAvailable(type: storageType) {

FILE: helpers/validateSignature.ts
  function validateSignature (line 4) | function validateSignature(queryParams: QueryParams): boolean {

FILE: hooks/useAllWithdrawalBalances.tsx
  function useAllWithdrawalBalances (line 9) | function useAllWithdrawalBalances() {

FILE: hooks/useAutoSlippageTest.tsx
  type AutoSlippageTestProps (line 7) | type AutoSlippageTestProps = {
  function useAutoSlippageTest (line 13) | function useAutoSlippageTest({ values, shouldTest }: AutoSlippageTestPro...

FILE: hooks/useClickOutside.ts
  type UseClickOutsideReturn (line 3) | type UseClickOutsideReturn<T extends HTMLElement> = {
  function handleClickOutside (line 17) | function handleClickOutside(e: MouseEvent | TouchEvent) {

FILE: hooks/useConnectors.ts
  type UseConnectorsParams (line 5) | type UseConnectorsParams = {
  type InitialSnapshot (line 13) | type InitialSnapshot = {
  function useConnectors (line 19) | function useConnectors({

FILE: hooks/useCopyClipboard.ts
  function useCopyClipboard (line 4) | function useCopyClipboard(timeout = 500): [boolean, (toCopy: string | nu...

FILE: hooks/useExchangeNetworks.ts
  type Props (line 8) | type Props = {
  function useExchangeNetworks (line 14) | function useExchangeNetworks({ fromExchange, to, toAsset }: Props) {

FILE: hooks/useFee.tsx
  type QuoteTokenPrices (line 11) | type QuoteTokenPrices = Pick<SwapQuote, 'source_token' | 'destination_to...
  type UseQuoteData (line 13) | type UseQuoteData = {
  type QuoteError (line 27) | type QuoteError = {
  type Props (line 47) | type Props = {
  function useQuoteData (line 58) | function useQuoteData(formValues: Props | undefined, refreshInterval?: n...
  function transformFormValuesToQuoteArgs (line 179) | function transformFormValuesToQuoteArgs(values: SwapFormValues, withDela...
  function transformSwapDataToQuoteArgs (line 192) | function transformSwapDataToQuoteArgs(swapData: SwapBasicData | undefine...
  type QuoteUrlArgs (line 204) | type QuoteUrlArgs = {
  function buildQuoteUrl (line 215) | function buildQuoteUrl(args: QuoteUrlArgs): string {
  type LimitsQueryOptions (line 273) | interface LimitsQueryOptions {
  function buildLimitsUrl (line 282) | function buildLimitsUrl({
  type LoadingState (line 306) | type LoadingState = {

FILE: hooks/useFormRoutes.ts
  type Props (line 21) | type Props = {
  function useFormRoutes (line 26) | function useFormRoutes({ direction, values }: Props, search?: string, su...
  function useRoutesData (line 93) | function useRoutesData<T extends object>(url: string, defaultData: T[], ...
  type QueryFilterParams (line 110) | type QueryFilterParams = {
  function filterRoutesByQuery (line 121) | function filterRoutesByQuery(
  function useRoutes (line 159) | function useRoutes({ direction, values }: Props) {
  function resolveTokenUSDBalance (line 169) | function resolveTokenUSDBalance(route: NetworkRoute, token: NetworkRoute...
  constant BALANCE_EPSILON (line 177) | const BALANCE_EPSILON = 0.001;
  function directionKeys (line 179) | function directionKeys(direction: SwapDirection) {
  function sortRoutesByMostUsed (line 186) | function sortRoutesByMostUsed(
  function sortRoutesByTrending (line 210) | function sortRoutesByTrending(
  function sortRoutesAlphabetically (line 226) | function sortRoutesAlphabetically(
  function sortRoutes (line 236) | function sortRoutes(
  function sortTokensByMostUsed (line 259) | function sortTokensByMostUsed(
  function sortTokensByTrending (line 279) | function sortTokensByTrending(
  function sortTokensAlphabetically (line 295) | function sortTokensAlphabetically(
  function sortTokens (line 305) | function sortTokens(
  function sortGroupedTokens (line 329) | function sortGroupedTokens(
  function sortGroupedTokenItems (line 380) | function sortGroupedTokenItems(
  function sortRoutesByRelevance (line 415) | function sortRoutesByRelevance(
  function sortTokensByRelevance (line 454) | function sortTokensByRelevance(
  function sortGroupedTokensByRelevance (line 484) | function sortGroupedTokensByRelevance(
  function sortTokenItemsByRelevance (line 520) | function sortTokenItemsByRelevance(
  function resolveSearch (line 548) | function resolveSearch(routes: NetworkRoute[], search: string, direction...
  type GroupRoutesProps (line 604) | type GroupRoutesProps = {
  function groupRoutes (line 616) | function groupRoutes(
  function filterExchangesByQuery (line 675) | function filterExchangesByQuery(
  function groupExchanges (line 694) | function groupExchanges(exchangesRoutes: (Exchange)[], search?: string, ...
  function groupByTokens (line 711) | function groupByTokens(routes: NetworkRoute[]): GroupedTokenElement[] {
  function sortNetworkTokens (line 730) | function sortNetworkTokens(
  function resolveSelectedRoute (line 748) | function resolveSelectedRoute(values: SwapFormValues, direction: SwapDir...
  function resolveSelectedToken (line 752) | function resolveSelectedToken(values: SwapFormValues, direction: SwapDir...
  function useExchangeRoutes (line 758) | function useExchangeRoutes({ values }: Props) {
  function getSuggestedRoutes (line 780) | function getSuggestedRoutes(routes: NetworkRoute[], balances: Record<str...

FILE: hooks/useFormValidation.ts
  type Params (line 6) | interface Params {
  constant FORM_VALIDATION_ERROR_CODES (line 18) | const FORM_VALIDATION_ERROR_CODES = {
  function resolveFormValidation (line 25) | function resolveFormValidation({ values, maxAllowedAmount, minAllowedAmo...

FILE: hooks/useHistoryFilters.ts
  type Args (line 4) | type Args = {
  function useHistoryFilters (line 8) | function useHistoryFilters({ wallets }: Args) {

FILE: hooks/useInterval.ts
  function useComplexInterval (line 3) | function useComplexInterval(callback: () => Promise<boolean>, dependenci...
  function useInterval (line 30) | function useInterval(callback, delay) {
  function useDelayedInterval (line 50) | function useDelayedInterval(callback: () => Promise<boolean>, dependenci...

FILE: hooks/useIsWindowVisible.ts
  function useIsWindowVisible (line 3) | function useIsWindowVisible(): boolean {

FILE: hooks/useNavigatableList.ts
  type NavigableItem (line 5) | interface NavigableItem {
  function parseNavIndex (line 10) | function parseNavIndex(navIndex: string): FocusedIndex | null {
  function getFocusedElementIndex (line 24) | function getFocusedElementIndex(): FocusedIndex | null {
  type UseNavigatableListOptions (line 31) | interface UseNavigatableListOptions {

FILE: hooks/usePersistedState.ts
  type PersistedState (line 4) | type PersistedState<T> = [T, Dispatch<SetStateAction<T>>];
  function usePersistedState (line 6) | function usePersistedState<T>(defaultValue: T, key: string, type: storag...
  function isJsonString (line 23) | function isJsonString(str) {

FILE: hooks/useResolvedSwapStatus.ts
  type Options (line 7) | type Options = { inputTxStatusFromApi?: TransactionStatus };
  function useResolvedSwapStatus (line 9) | function useResolvedSwapStatus(opts: Options = {}): ResolvedSwapStatus {

FILE: hooks/useRouteValidation.tsx
  type ValidationDetails (line 10) | interface ValidationDetails {
  function useRouteValidation (line 16) | function useRouteValidation(quoteError?: QuoteError, hasQuote?: boolean,...

FILE: hooks/useStorage.ts
  type UseStorageReturnValue (line 4) | type UseStorageReturnValue = {

FILE: hooks/useSuggestionsLimit.tsx
  constant SUGGESTION_ROW_HEIGHT (line 4) | const SUGGESTION_ROW_HEIGHT = 60;
  constant MIN_SUGGESTIONS (line 5) | const MIN_SUGGESTIONS = 4;
  constant MAX_SUGGESTIONS (line 6) | const MAX_SUGGESTIONS = 15;
  type WindowSize (line 8) | type WindowSize = {
  function calculateFromViewport (line 13) | function calculateFromViewport(windowSize: WindowSize, hasWallet: boolea...
  type Options (line 40) | type Options = {
  function useSuggestionsLimit (line 44) | function useSuggestionsLimit({ hasWallet }: Options) {

FILE: hooks/useSwapByTransactionHash.ts
  function useSwapByTransactionHash (line 6) | function useSwapByTransactionHash(hash: string, delayMs = 400) {

FILE: hooks/useSwapHistoryData.ts
  function useSwapHistoryData (line 8) | function useSwapHistoryData(addresses?: string[], networks?: string[]) {

FILE: hooks/useSwrSwaps.ts
  constant PAGE_SIZE (line 6) | const PAGE_SIZE = 20
  type UseSwrSwapsArgs (line 8) | type UseSwrSwapsArgs = {
  function useSwrSwaps (line 30) | function useSwrSwaps({ statuses, addresses, networks, refreshInterval, a...

FILE: hooks/useUsdTokenSync.ts
  function skipNextUsdSync (line 14) | function skipNextUsdSync() {
  type UseUsdTokenSyncArgs (line 18) | interface UseUsdTokenSyncArgs {
  type UseUsdTokenSyncReturn (line 28) | interface UseUsdTokenSyncReturn {
  function useUsdTokenSync (line 37) | function useUsdTokenSync({

FILE: hooks/useWallet.ts
  type WalletPurpose (line 6) | type WalletPurpose = "autofill" | "withdrawal" | "asSource"
  function useWallet (line 8) | function useWallet(network?: Network | undefined, purpose?: WalletPurpos...

FILE: hooks/useWalletRpcHealth.tsx
  type WalletRpcHealth (line 4) | type WalletRpcHealth =
  type AddEthereumChainParams (line 9) | type AddEthereumChainParams = {
  type SuggestRpcResult (line 21) | type SuggestRpcResult =
  function useWalletRpcHealth (line 25) | function useWalletRpcHealth() {

FILE: hooks/useWalletTransferOptions.ts
  function useWalletTransferOptions (line 10) | function useWalletTransferOptions() {

FILE: hooks/useWindowDimensions.tsx
  function useWindowDimensions (line 3) | function useWindowDimensions() {

FILE: lib/AnimatedNumber.tsx
  type AnimatedNumberProps (line 4) | type AnimatedNumberProps = {

FILE: lib/AppSettings.ts
  class AppSettings (line 1) | class AppSettings {

FILE: lib/CurrencySettings.ts
  class CurrencySettings (line 3) | class CurrencySettings {
    method Initialize (line 9) | public static Initialize() {

FILE: lib/Errors/AuthRefreshFailedError.ts
  class AuthRefreshFailedError (line 1) | class AuthRefreshFailedError extends Error {
    method constructor (line 2) | constructor() {

FILE: lib/ExchangeSettings.ts
  class ExchangeSettings (line 27) | class ExchangeSettings {
    method Initialize (line 45) | public static Initialize() {

FILE: lib/NetworkSettings.ts
  type GasCalculation (line 3) | enum GasCalculation {
  class NetworkSettings (line 48) | class NetworkSettings {
    method Initialize (line 64) | public static Initialize() {

FILE: lib/SwapSettings.ts
  class SwapSettings (line 3) | class SwapSettings {
    method Initialize (line 11) | public static Initialize() {

FILE: lib/address/Address.ts
  type AddressDisplayFormat (line 4) | type AddressDisplayFormat = 'short' | 'ending' | 'full' | 'emphasized';
  type AddressFormatOptions (line 6) | interface AddressFormatOptions {
  class Address (line 22) | class Address {
    method constructor (line 53) | constructor(address: string, network: { name: string } | null | undefi...
    method raw (line 68) | get raw(): string {
    method normalized (line 75) | get normalized(): string {
    method full (line 82) | get full(): string {
    method network (line 90) | get network(): { name: string } | null | undefined {
    method isValid (line 97) | static isValid(address: string, network: { name: string } | null = nul...
    method toShortString (line 105) | toShortString(): string {
    method toEndingString (line 120) | toEndingString(): string {
    method toEmphasizedParts (line 131) | toEmphasizedParts(): { start: string; middle: string; end: string } {
    method toIconSeed (line 149) | static toIconSeed(address: string): number {
    method fromEmail (line 160) | static fromEmail(email: string, maxNameLength: number = 14): EmailAddr...
    method toString (line 167) | toString(): string {
    method equals (line 180) | static equals(
  class EmailAddress (line 199) | class EmailAddress {
    method constructor (line 203) | constructor(email: string, maxNameLength: number = 14) {
    method toShortString (line 213) | toShortString(): string {
  function isEmailAddress (line 236) | function isEmailAddress(address: Address | EmailAddress): address is Ema...

FILE: lib/address/explorerUrl.ts
  function getExplorerUrl (line 15) | function getExplorerUrl(template: string | undefined | null, address: st...

FILE: lib/address/formatter.ts
  type AddressFormatProps (line 3) | type AddressFormatProps = {
  function addressFormat (line 9) | function addressFormat(props: AddressFormatProps): string {

FILE: lib/address/validator/index.ts
  function isValidAddress (line 8) | function isValidAddress(address?: string, network?: { name: string } | n...
  function isValidEtherAddress (line 73) | function isValidEtherAddress(address: string): boolean {
  function isChecksumAddress (line 86) | function isChecksumAddress(address: string): boolean {
  function isBlacklistedAddress (line 99) | function isBlacklistedAddress(address: string): boolean {
  function decodeBase58 (line 117) | function decodeBase58(base58Str) {

FILE: lib/address/validator/starkNetAddressValidator.ts
  constant TWO (line 3) | const TWO = toBN(2);
  constant MASK_251 (line 4) | const MASK_251 = TWO.pow(toBN(251));
  constant MASK_221 (line 5) | const MASK_221 = TWO.pow(toBN(221));
  type BigNumberish (line 7) | type BigNumberish = string | number | BN;
  function validateAndParseAddress (line 9) | function validateAndParseAddress(address: string): boolean {
  function addAddressPadding (line 27) | function addAddressPadding(address: string): string {
  function addHexPrefix (line 31) | function addHexPrefix(hex: string): string {
  function removeHexPrefix (line 35) | function removeHexPrefix(hex: string): string {
  function assertInRange (line 39) | function assertInRange(
  function toBN (line 57) | function toBN(number: BigNumberish, base?: number | 'hex') {
  function isHex (line 63) | function isHex(hex: string): boolean {

FILE: lib/apiClients/hyperliquidClient.ts
  type ClearinghouseState (line 1) | interface ClearinghouseState {
  class HyperliquidClient (line 43) | class HyperliquidClient {
    method getClearinghouseState (line 44) | async getClearinghouseState(user: string, nodeUrl: string, timeoutMs?:...

FILE: lib/apiClients/jsonRpcClient.ts
  type JsonRpcRequest (line 1) | interface JsonRpcRequest<P> {
  type JsonRpcError (line 8) | interface JsonRpcError {
  type JsonRpcResponse (line 14) | interface JsonRpcResponse<R> {
  class JsonRpcClient (line 21) | class JsonRpcClient {
    method constructor (line 25) | constructor(url: string) {
    method call (line 29) | async call<P, R>(method: string, params: P, timeoutMs?: number, retryC...

FILE: lib/apiClients/layerSwapApiClient.ts
  constant IGNORED_API_ERROR_CODES (line 12) | const IGNORED_API_ERROR_CODES = [
  class LayerSwapApiClient (line 18) | class LayerSwapApiClient {
    method constructor (line 25) | constructor() {
    method GetRoutesAsync (line 32) | async GetRoutesAsync(direction: 'sources' | 'destinations'): Promise<A...
    method GetSourceExchangesAsync (line 36) | async GetSourceExchangesAsync(): Promise<ApiResponse<Exchange[]>> {
    method GetLSNetworksAsync (line 40) | async GetLSNetworksAsync(): Promise<ApiResponse<NetworkWithTokens[]>> {
    method CreateSwapAsync (line 44) | async CreateSwapAsync(params: CreateSwapParams): Promise<ApiResponse<S...
    method GetTransactionStatus (line 49) | async GetTransactionStatus(network: string, tx_id: string): Promise<Ap...
    method SwapCatchup (line 53) | async SwapCatchup(swapId: string, tx_id: string): Promise<ApiResponse<...
    method GetSwapAsync (line 57) | async GetSwapAsync(swapId: string): Promise<ApiResponse<SwapResponse>> {
    method AuthenticatedRequest (line 61) | private async AuthenticatedRequest<T extends EmptyApiResponse>(method:...
    method UnauthenticatedRequest (line 96) | private async UnauthenticatedRequest<T extends EmptyApiResponse>(metho...
  type DepositAddress (line 114) | type DepositAddress = {
  type DepositAddressSource (line 119) | enum DepositAddressSource {
  type CreateSwapParams (line 124) | type CreateSwapParams = {
  type SwapResponse (line 142) | type SwapResponse = {
  type Refuel (line 149) | type Refuel = {
  type SwapBasicData (line 156) | type SwapBasicData = {
  type SwapDetails (line 167) | type SwapDetails = {
  type SwapItem (line 183) | type SwapItem = {
  type DepositAction (line 212) | type DepositAction = {
  type Quote (line 225) | type Quote = {
  type QuoteReward (line 231) | type QuoteReward = {
  type GetQuoteParams (line 240) | type GetQuoteParams = {
  type SwapQuote (line 253) | type SwapQuote = {
  type AddressBookItem (line 272) | type AddressBookItem = {
  type Transaction (line 279) | type Transaction = {
  type TransactionType (line 296) | enum TransactionType {
  type BackendTransactionStatus (line 303) | enum BackendTransactionStatus {
  type TransactionStatus (line 310) | enum TransactionStatus {
  type DepositType (line 316) | enum DepositType {
  type Fee (line 321) | type Fee = {
  type PublishedSwapTransactions (line 328) | type PublishedSwapTransactions = {
  type SwapTransaction (line 337) | type SwapTransaction = {
  type SwapType (line 342) | enum SwapType {
  type WithdrawType (line 348) | enum WithdrawType {
  type SwapStatusInNumbers (line 356) | enum SwapStatusInNumbers {
  type Campaign (line 366) | type Campaign = {
  type Reward (line 384) | type Reward = {
  type Leaderboard (line 395) | type Leaderboard = {
  type RewardPayout (line 404) | type RewardPayout = {

FILE: lib/balances/balanceResolver.ts
  constant SKIP_BALANCE_NETWORKS (line 9) | const SKIP_BALANCE_NETWORKS = [
  function formatErrorBalances (line 14) | function formatErrorBalances(errorBalances: TokenBalance[]) {
  class BalanceResolver (line 33) | class BalanceResolver {
    method getProviderInstance (line 37) | private async getProviderInstance(kind: ProviderKind): Promise<Balance...
    method loadProvider (line 58) | private async loadProvider(kind: ProviderKind): Promise<BalanceProvide...
    method resolveProvider (line 109) | private async resolveProvider(network: NetworkWithTokens): Promise<Bal...
    method resolvePrioritizedProviderKinds (line 133) | private resolvePrioritizedProviderKinds(network: NetworkWithTokens): P...
    method getBalance (line 181) | async getBalance(network: NetworkWithTokens, address?: string, options...
  type ProviderKind (line 239) | type ProviderKind =

FILE: lib/balances/errorUtils.ts
  type ErrorDetails (line 1) | type ErrorDetails = {
  function extractErrorDetails (line 12) | function extractErrorDetails(error: unknown): ErrorDetails {

FILE: lib/balances/nodeErrorClassifier.ts
  type NodeErrorCategory (line 3) | type NodeErrorCategory =
  function classifyNodeError (line 11) | function classifyNodeError(error: Error | unknown | TokenBalanceError): ...

FILE: lib/balances/providers/bitcoinBalanceProvider.ts
  type Utxo (line 7) | interface Utxo {
  class BitcoinBalanceProvider (line 14) | class BitcoinBalanceProvider extends BalanceProvider {
  function fetchUtxos (line 55) | async function fetchUtxos(address: string, networkName: string, timeoutM...
  function sumUtxos (line 63) | function sumUtxos(utxos: Utxo[]): number {
  function formatBtc (line 67) | function formatBtc(sats: number): number {

FILE: lib/balances/providers/evmBalanceProvider.ts
  class EVMBalanceProvider (line 20) | class EVMBalanceProvider extends BalanceProvider {
  type ERC20ContractRes (line 189) | type ERC20ContractRes = ({
  type GetBalanceArgs (line 199) | type GetBalanceArgs = {
  type NativeBalanceResponse (line 315) | type NativeBalanceResponse = (GetBalanceReturnType & {

FILE: lib/balances/providers/fuelBalanceProvider.ts
  class FuelBalanceProvider (line 9) | class FuelBalanceProvider extends BalanceProvider {

FILE: lib/balances/providers/hyperliquidBalanceProvider.ts
  class HyperliquidBalanceProvider (line 7) | class HyperliquidBalanceProvider extends BalanceProvider {
    method constructor (line 10) | constructor() {

FILE: lib/balances/providers/loopringBalanceProvider.ts
  class LoopringBalanceProvider (line 11) | class LoopringBalanceProvider extends BalanceProvider {
  type AccountInfo (line 66) | interface AccountInfo {
  type PendingBalances (line 70) | type PendingBalances = {
  type LpBalance (line 75) | type LpBalance = {

FILE: lib/balances/providers/paradexBalanceProvider.ts
  class ParadexBalanceProvider (line 6) | class ParadexBalanceProvider extends BalanceProvider {

FILE: lib/balances/providers/queryBalanceProvider.ts
  class QueryBalanceProvider (line 6) | class QueryBalanceProvider extends BalanceProvider {
    method constructor (line 14) | constructor() {
    method getQueryParams (line 19) | private getQueryParams() {

FILE: lib/balances/providers/solanaBalanceProvider.ts
  class SolanaBalanceProvider (line 8) | class SolanaBalanceProvider extends BalanceProvider {
    class SolanaConnection (line 18) | class SolanaConnection extends Connection { }
    method fetch (line 29) | fetch(input, init) {
    method getTokenBalanceWeb3 (line 35) | async function getTokenBalanceWeb3(connection: SolanaConnection, token...

FILE: lib/balances/providers/starknetBalanceProvider.ts
  class StarknetBalanceProvider (line 8) | class StarknetBalanceProvider extends BalanceProvider {

FILE: lib/balances/providers/tonBalanceProvider.ts
  class TonBalanceProvider (line 10) | class TonBalanceProvider extends BalanceProvider {

FILE: lib/balances/providers/tronBalanceProvider.ts
  class TronBalanceProvider (line 9) | class TronBalanceProvider extends BalanceProvider {
  type GetBalanceProps (line 35) | type GetBalanceProps = {

FILE: lib/balances/providers/zkSyncBalanceProvider.ts
  class ZkSyncBalanceProvider (line 5) | class ZkSyncBalanceProvider extends BalanceProvider {
  type Balances (line 44) | type Balances = {
  type zkSyncGas (line 48) | type zkSyncGas = {
  type AccountInfo (line 58) | type AccountInfo = {
  class ZkSyncLiteRPCClient (line 66) | class ZkSyncLiteRPCClient {
    method getPublicClient (line 68) | private async getPublicClient(nodeUrl: string) {
    method getTransferFee (line 79) | async getTransferFee(nodeUrl: string, recipientAddress: `0x${string}`,...
    method getAccountInfo (line 84) | async getAccountInfo(nodeUrl: string, address: string) {

FILE: lib/balances/useBalance.ts
  type Opts (line 6) | interface Opts {
  function useBalance (line 13) | function useBalance(

FILE: lib/calculateDatesDifference.ts
  function calculateDatesDifference (line 1) | function calculateDatesDifference(date1: string, date2: string) {

FILE: lib/ethersToViem/ethers.ts
  function walletClientToSigner (line 8) | function walletClientToSigner(walletClient: WalletClient) {
  function useEthersSigner (line 28) | function useEthersSigner({ chainId }: { chainId?: number } = {}) {

FILE: lib/external/nameof/name-of.ts
  function nameOf (line 16) | function nameOf<T>(

FILE: lib/external/nameof/path-of.ts
  function pathOf (line 15) | function pathOf<T>(

FILE: lib/external/nameof/separated-path-of.ts
  function separatedPathOf (line 17) | function separatedPathOf<T>(

FILE: lib/external/nameof/types.ts
  type CallBackForPropertyAccess (line 1) | type CallBackForPropertyAccess<T> = (obj: T) => void;

FILE: lib/fees.ts
  function CalculateMinimalAuthorizeAmount (line 3) | function CalculateMinimalAuthorizeAmount(usd_price: number, amount: numb...
  type PriceImpactValues (line 7) | type PriceImpactValues = {

FILE: lib/fetchWithTimeout.ts
  function fetchWithTimeout (line 1) | async function fetchWithTimeout(input: RequestInfo | URL, init?: Request...

FILE: lib/fuels/common/FakeAccount.ts
  type FakeAccount (line 6) | interface FakeAccount {
  class EthereumFakeAccount (line 15) | class EthereumFakeAccount implements FakeAccount {
    method constructor (line 17) | constructor() {
  class SolanaFakeAccount (line 40) | class SolanaFakeAccount implements FakeAccount {
    method constructor (line 42) | constructor() {

FILE: lib/fuels/common/PredicateConnector.ts
  constant SELECTED_PREDICATE_KEY (line 37) | const SELECTED_PREDICATE_KEY = 'fuel_selected_predicate_version';
  method disconnect (line 70) | public async disconnect(): Promise<boolean> {
  method constructor (line 98) | constructor() {
  method emitAccountChange (line 115) | protected async emitAccountChange(
  method predicateVersions (line 131) | protected get predicateVersions(): Array<PredicateFactory> {
  method getAvailablePredicateVersions (line 149) | public getAvailablePredicateVersions(): Array<{
  method getAllPredicateVersionsWithMetadata (line 163) | public async getAllPredicateVersionsWithMetadata(): Promise<
  method setSelectedPredicateVersion (line 238) | public setSelectedPredicateVersion(versionId: string): void {
  method getSelectedPredicateVersion (line 260) | public getSelectedPredicateVersion(): Maybe<string> {
  method getSmartDefaultPredicateVersion (line 264) | public async getSmartDefaultPredicateVersion(): Promise<Maybe<string>> {
  method switchPredicateVersion (line 283) | public async switchPredicateVersion(versionId: string): Promise<void> {
  method isAddressPredicate (line 295) | protected isAddressPredicate(b: BytesLike, walletAccount: string): boole...
  method getCurrentUserPredicate (line 301) | protected async getCurrentUserPredicate(): Promise<Maybe<PredicateFactor...
  method getNewestPredicate (line 321) | protected getNewestPredicate(): Maybe<PredicateFactory> {
  method getPredicateByVersion (line 325) | protected getPredicateByVersion(versionId: string): Maybe<PredicateFacto...
  method setupPredicate (line 333) | protected async setupPredicate(): Promise<PredicateFactory> {
  method subscribe (line 381) | protected subscribe(listener: () => void) {
  method prepareTransaction (line 385) | protected async prepareTransaction(
  method clearSubscriptions (line 474) | public clearSubscriptions() {
  method ping (line 482) | public async ping(): Promise<boolean> {
  method version (line 493) | public async version(): Promise<Version> {
  method isConnected (line 497) | public async isConnected(): Promise<boolean> {
  method accounts (line 503) | public async accounts(): Promise<Array<string>> {
  method currentAccount (line 512) | public async currentAccount(): Promise<string | null> {
  method networks (line 524) | public async networks(): Promise<Network[]> {
  method currentNetwork (line 528) | public async currentNetwork(): Promise<Network> {
  method signMessage (line 535) | public async signMessage(
  method addAssets (line 542) | public async addAssets(_assets: Asset[]): Promise<boolean> {
  method addAsset (line 546) | public async addAsset(_asset: Asset): Promise<boolean> {
  method assets (line 550) | public async assets(): Promise<Array<Asset>> {
  method addNetwork (line 554) | public async addNetwork(_networkUrl: string): Promise<boolean> {
  method selectNetwork (line 558) | public async selectNetwork(
  method addAbi (line 564) | public async addAbi(_abiMap: AbiMap): Promise<boolean> {
  method getAbi (line 568) | public async getAbi(_contractId: string): Promise<JsonAbi> {
  method hasAbi (line 572) | public async hasAbi(_contractId: string): Promise<boolean> {

FILE: lib/fuels/common/PredicateFactory.ts
  class PredicateFactory (line 19) | class PredicateFactory {
    method constructor (line 26) | constructor(

FILE: lib/fuels/common/PredicateWalletAdapter.ts
  type PredicateWalletAdapter (line 10) | interface PredicateWalletAdapter {
  class EthereumWalletAdapter (line 19) | class EthereumWalletAdapter implements PredicateWalletAdapter {
  class SolanaWalletAdapter (line 36) | class SolanaWalletAdapter implements PredicateWalletAdapter {

FILE: lib/fuels/common/networks.ts
  constant TESTNET_NETWORK (line 3) | const TESTNET_NETWORK: Network = {
  constant MAINNET_NETWORK (line 8) | const MAINNET_NETWORK: Network = {
  constant DEFAULT_NETWORKS (line 13) | const DEFAULT_NETWORKS: Network[] = [

FILE: lib/fuels/common/types.ts
  type Maybe (line 12) | type Maybe<T> = T | undefined | null;
  type Option (line 13) | type Option<T1, T2, T3 = string> = T1 | T2 | T3;
  type Hash (line 14) | type Hash = `0x${string}`;
  type MaybeAsync (line 15) | type MaybeAsync<T> = Promise<T> | T;
  type PredicateConfig (line 17) | interface PredicateConfig {
  type PredicateVersion (line 22) | interface PredicateVersion {
  type EIP1193Provider (line 27) | interface EIP1193Provider extends EventEmitter {
  type ConnectorConfig (line 34) | type ConnectorConfig = {
  type ProviderDictionary (line 39) | type ProviderDictionary = {
  type PreparedTransaction (line 45) | type PreparedTransaction = {
  type SignedMessageCustomCurve (line 53) | type SignedMessageCustomCurve = {
  type PredicateVersionWithMetadata (line 58) | interface PredicateVersionWithMetadata {

FILE: lib/fuels/connectors/bako-safe/BakoSafeConnector.ts
  class BakoSafeConnector (line 38) | class BakoSafeConnector extends FuelConnector {
    method constructor (line 64) | constructor(config?: BakoSafeConnectorConfig) {
    method getStorage (line 76) | private getStorage(storage?: StorageAbstract) {
    method getSessionId (line 85) | private async getSessionId() {
    method checkWindow (line 94) | private checkWindow() {
    method setup (line 120) | private async setup() {
    method requestConnectionState (line 146) | private async requestConnectionState() {
    method connect (line 166) | async connect() {
    method sendTransaction (line 204) | async sendTransaction(
    method selectNetwork (line 253) | async selectNetwork(_network: Network): Promise<boolean> {
    method ping (line 293) | async ping() {
    method version (line 301) | async version() {
    method isConnected (line 308) | async isConnected() {
    method accounts (line 313) | async accounts() {
    method currentAccount (line 320) | async currentAccount() {
    method disconnect (line 330) | async disconnect() {
    method currentNetwork (line 338) | async currentNetwork(): Promise<Network> {
    method networks (line 351) | async networks(): Promise<Array<Network>> {
    method assets (line 355) | async assets(): Promise<Asset[]> {
    method signMessage (line 359) | async signMessage(_address: string, _message: string): Promise<string> {
    method addAssets (line 363) | async addAssets(_assets: Asset[]): Promise<boolean> {
    method addAsset (line 367) | async addAsset(_assets: Asset): Promise<boolean> {
    method addNetwork (line 371) | async addNetwork(_networkUrl: string): Promise<boolean> {
    method addABI (line 375) | async addABI(_contractId: string, _abi: FuelABI): Promise<boolean> {
    method getABI (line 379) | async getABI(_id: string): Promise<FuelABI | null> {
    method hasABI (line 383) | async hasABI(_id: string): Promise<boolean> {
    method startConsolidation (line 390) | async startConsolidation(opts: StartConsolidateCoins): Promise<void> {

FILE: lib/fuels/connectors/bako-safe/BakoSafeStorage.ts
  class BakoStorage (line 3) | class BakoStorage extends StorageAbstract {
    method getItem (line 6) | async getItem(key: string): Promise<string | null | undefined> {
    method setItem (line 10) | async setItem(key: string, value: string): Promise<void> {
    method removeItem (line 16) | async removeItem(key: string): Promise<void> {
    method clear (line 20) | async clear(): Promise<void> {

FILE: lib/fuels/connectors/bako-safe/DAPPWindow.ts
  type PopupConfig (line 3) | type PopupConfig = {
  class DAppWindow (line 11) | class DAppWindow {
    method constructor (line 20) | constructor(private config: PopupConfig) {
    method popupConfig (line 24) | private get popupConfig() {
    method open (line 37) | open(method: string, reject: (e: Error) => void) {
    method close (line 57) | close() {
    method makeLink (line 68) | makeLink(method: string) {
    method makeFrame (line 77) | makeFrame(method: string, isSafari = false) {
    method makePopup (line 110) | makePopup(method: string) {
    method queryString (line 122) | private get queryString() {
    method small (line 127) | private get small() {

FILE: lib/fuels/connectors/bako-safe/SocketClient.ts
  constant DEFAULT_SOCKET_AUTH (line 15) | const DEFAULT_SOCKET_AUTH: Omit<ISocketAuth, 'sessionId'> = {
  class SocketClient (line 21) | class SocketClient {
    method constructor (line 28) | private constructor({ sessionId, events }: ICreateClientSocket) {
    method setupEventListeners (line 60) | private setupEventListeners(): void {
    method create (line 82) | static create(options: ICreateClientSocket) {
    method connect (line 90) | connect(): void {
    method isConnected (line 97) | get isConnected(): boolean {
    method checkConnection (line 101) | checkConnection(): void {

FILE: lib/fuels/connectors/bako-safe/constants.ts
  constant APP_VERSION (line 1) | const APP_VERSION = '0.0.0';
  constant APP_NETWORK (line 2) | const APP_NETWORK = '0.0.0';
  constant APP_NAME (line 3) | const APP_NAME = 'Bako Safe';
  constant APP_DESCRIPTION (line 4) | const APP_DESCRIPTION =
  constant APP_IMAGE_DARK (line 6) | const APP_IMAGE_DARK =
  constant APP_IMAGE_LIGHT (line 8) | const APP_IMAGE_LIGHT =
  constant APP_URL (line 11) | const APP_URL = 'https://safe.bako.global';
  constant HOST_URL (line 12) | const HOST_URL = 'https://api.bako.global';
  constant SOCKET_URL (line 13) | const SOCKET_URL = 'https://api.bako.global';
  constant HAS_WINDOW (line 16) | const HAS_WINDOW = typeof window !== 'undefined';
  constant WINDOW (line 18) | const WINDOW: any = HAS_WINDOW ? window : {};
  constant IS_SAFARI (line 19) | const IS_SAFARI = /^((?!chrome|android).)*safari/i.test(
  constant SESSION_ID (line 23) | const SESSION_ID = 'sessionId';

FILE: lib/fuels/connectors/bako-safe/request.ts
  class RequestAPI (line 3) | class RequestAPI {
    method constructor (line 6) | constructor(baseUrl: string) {
    method get (line 10) | async get(pathname: string) {
    method delete (line 17) | async delete(pathname: string) {

FILE: lib/fuels/connectors/bako-safe/types.ts
  type BakoSafeConnectorEvents (line 5) | enum BakoSafeConnectorEvents {
  type BakoSafeUsernames (line 29) | enum BakoSafeUsernames {
  type BakoSafeConnectorConfig (line 35) | type BakoSafeConnectorConfig = {
  type ISocketAuth (line 42) | interface ISocketAuth {
  type ISocketMessage (line 49) | interface ISocketMessage<T> {
  type ICreateClientSocket (line 57) | interface ICreateClientSocket {
  type IRequestTxPending (line 62) | interface IRequestTxPending {
  type IResponseTxCofirmed (line 67) | interface IResponseTxCofirmed {
  type IResponseAuthConfirmed (line 71) | interface IResponseAuthConfirmed {

FILE: lib/fuels/connectors/fuel-wallet/FuelWalletConnector.ts
  class FuelWalletConnector (line 33) | class FuelWalletConnector extends FuelConnector {
    method constructor (line 51) | constructor(name = 'Fuel Wallet') {
    method setupConnector (line 68) | private async setupConnector() {
    method acceptMessage (line 80) | private acceptMessage(message: MessageEvent<CommunicationMessage>): bo...
    method setupListener (line 90) | private setupListener() {
    method createRequestId (line 95) | private createRequestId(): string {
    method postMessage (line 99) | private postMessage(message: CommunicationMessage, origin?: string) {
    method sendRequest (line 103) | private async sendRequest(request: JSONRPCRequest | null) {
    method onResponse (line 113) | private onResponse(message: ResponseMessage): void {
    method onEvent (line 117) | private onEvent(message: EventMessage): void {
    method ping (line 151) | async ping(): Promise<boolean> {
    method isConnected (line 155) | async isConnected(): Promise<boolean> {
    method connect (line 164) | async connect(): Promise<boolean> {
    method disconnect (line 168) | async disconnect(): Promise<boolean> {
    method accounts (line 172) | async accounts(): Promise<Array<string>> {
    method currentAccount (line 177) | async currentAccount(): Promise<string | null> {
    method signMessage (line 183) | async signMessage(address: string, message: string): Promise<string> {
    method sendTransaction (line 193) | async sendTransaction(
    method assets (line 219) | async assets(): Promise<Array<Asset>> {
    method addAsset (line 223) | async addAsset(asset: Asset): Promise<boolean> {
    method addAssets (line 227) | async addAssets(assets: Asset[]): Promise<boolean> {
    method addABI (line 250) | async addABI(contractId: string, abi: FuelABI): Promise<boolean> {
    method getABI (line 258) | async getABI(contractId: string): Promise<FuelABI> {
    method hasABI (line 264) | async hasABI(contractId: string): Promise<boolean> {
    method currentNetwork (line 269) | async currentNetwork(): Promise<Network> {
    method selectNetwork (line 273) | async selectNetwork(network: SelectNetworkArguments): Promise<boolean> {
    method networks (line 279) | async networks(): Promise<Network[]> {
    method addNetwork (line 283) | async addNetwork(networkUrl: string): Promise<boolean> {
    method version (line 297) | async version(): Promise<Version> {

FILE: lib/fuels/connectors/fuel-wallet/constants.ts
  constant CONNECTOR_SCRIPT (line 1) | const CONNECTOR_SCRIPT = 'FuelConnectorScript';
  constant CONTENT_SCRIPT_NAME (line 2) | const CONTENT_SCRIPT_NAME = 'FuelContentScript';
  constant EVENT_MESSAGE (line 3) | const EVENT_MESSAGE = 'message';
  constant APP_IMAGE (line 5) | const APP_IMAGE =

FILE: lib/fuels/connectors/fuel-wallet/types.ts
  type MessageTypes (line 3) | enum MessageTypes {
  type MessageSender (line 12) | interface MessageSender {
  type BaseEvent (line 25) | type BaseEvent<T> = {
  type EventMessageEvents (line 32) | type EventMessageEvents = Array<{
  type UIEventMessage (line 37) | type UIEventMessage = BaseEvent<{
  type RequestMessage (line 43) | type RequestMessage = BaseEvent<{
  type ResponseMessage (line 48) | type ResponseMessage = BaseEvent<{
  type EventMessage (line 53) | type EventMessage<T = EventMessageEvents> = BaseEvent<{
  type CommunicationMessage (line 58) | type CommunicationMessage =

FILE: lib/fuels/connectors/fuelet-wallet/FueletWalletConnector.ts
  class FueletWalletConnector (line 5) | class FueletWalletConnector extends FuelWalletConnector {
    method constructor (line 19) | constructor() {

FILE: lib/fuels/connectors/fuelet-wallet/constants.ts
  constant APP_IMAGE_DARK (line 1) | const APP_IMAGE_DARK =
  constant APP_IMAGE_LIGHT (line 3) | const APP_IMAGE_LIGHT =

FILE: lib/fuels/connectors/walletConnect/constants.ts
  constant DEFAULT_PROJECT_ID (line 1) | const DEFAULT_PROJECT_ID = '00000000000000000000000000000000';
  constant ETHEREUM_ICON (line 2) | const ETHEREUM_ICON =
  constant TESTNET_URL (line 4) | const TESTNET_URL = 'https://testnet.fuel.network/v1/graphql';
  constant SINGATURE_VALIDATION_TIMEOUT (line 7) | const SINGATURE_VALIDATION_TIMEOUT = 1000 * 60;
  constant HAS_WINDOW (line 9) | const HAS_WINDOW = typeof window !== 'undefined';
  constant WINDOW (line 10) | const WINDOW = HAS_WINDOW ? window : null;

FILE: lib/fuels/connectors/walletConnect/types.ts
  type WalletConnectConfig (line 5) | type WalletConnectConfig = {

FILE: lib/fuels/connectors/walletConnect/utils/subscribeAndEnforceChain.ts
  function getCurrentChainId (line 9) | function getCurrentChainId(state: Pick<State, 'connections' | 'current'>) {
  function subscribeAndEnforceChain (line 15) | function subscribeAndEnforceChain(config: Config) {

FILE: lib/fuels/evm-predicates/index.ts
  constant PREDICATE_VERSIONS (line 13) | const PREDICATE_VERSIONS = {

FILE: lib/gases/gasResolver.ts
  class GasResolver (line 13) | class GasResolver {
    method getGas (line 25) | getGas({ address, network, token, recipientAddress, amount, wallet }: ...

FILE: lib/gases/providers/bitcoinGasProvider.ts
  class BitcoinGasProvider (line 9) | class BitcoinGasProvider implements GasProvider {
    method supportsNetwork (line 10) | supportsNetwork(network: Network): boolean {
    method getGas (line 14) | async getGas({ address, network, recipientAddress, amount }: GasProps)...

FILE: lib/gases/providers/evmGasProvider.ts
  class EVMGasProvider (line 14) | class EVMGasProvider implements GasProvider {
    method supportsNetwork (line 15) | supportsNetwork(network: Network): boolean {
  method constructor (line 77) | constructor(
  method resolveFeeData (line 110) | protected async resolveFeeData() {
  method getGasPrice (line 140) | private async getGasPrice() {
  method estimateFeesPerGas (line 152) | private async estimateFeesPerGas() {
  method estimateMaxPriorityFeePerGas (line 164) | private async estimateMaxPriorityFeePerGas() {
  method estimateNativeGasLimit (line 176) | protected async estimateNativeGasLimit() {
  method estimateERC20GasLimit (line 187) | protected async estimateERC20GasLimit() {
  class getEthereumGas (line 215) | class getEthereumGas extends getEVMGas {
  class getOptimismGas (line 239) | class getOptimismGas extends getEVMGas {

FILE: lib/gases/providers/fuelGasProvider.ts
  class FuelGasProvider (line 7) | class FuelGasProvider {
    method supportsNetwork (line 8) | supportsNetwork(network: Network): boolean {
    method getGas (line 12) | async getGas({ address, network, token }: GasProps): Promise<any> {

FILE: lib/gases/providers/loopringGasProvider.ts
  class LoopringGasProvider (line 10) | class LoopringGasProvider implements GasProvider {
    method supportsNetwork (line 11) | supportsNetwork(network: Network): boolean {
  type AccountInfo (line 29) | interface AccountInfo {

FILE: lib/gases/providers/solanaGasProvider.ts
  class SolanaGasProvider (line 6) | class SolanaGasProvider implements GasProvider {
    method supportsNetwork (line 7) | supportsNetwork(network: Network): boolean {

FILE: lib/gases/providers/starknetGasProvider.ts
  class StarknetGasProvider (line 8) | class StarknetGasProvider implements GasProvider {
    method supportsNetwork (line 9) | supportsNetwork(network: Network): boolean {

FILE: lib/gases/providers/tonGasProvider.ts
  class TonGasProvider (line 5) | class TonGasProvider implements GasProvider {
    method supportsNetwork (line 6) | supportsNetwork(network: Network): boolean {
    method getGas (line 10) | async getGas({address: string, network: Network, token: Token}): Promi...

FILE: lib/gases/providers/tronGasProvider.ts
  class TronGasProvider (line 7) | class TronGasProvider implements GasProvider {
    method supportsNetwork (line 8) | supportsNetwork(network: Network): boolean {
    method getGas (line 12) | async getGas({ address, network, token }: GasProps): Promise<any> {

FILE: lib/gases/providers/types.ts
  type GasProvider (line 4) | interface GasProvider {
  type GasWithToken (line 9) | type GasWithToken = {

FILE: lib/gases/providers/zkSyncGasProvider.ts
  class ZkSyncGasProvider (line 8) | class ZkSyncGasProvider implements GasProvider {
    method supportsNetwork (line 9) | supportsNetwork(network: Network): boolean {

FILE: lib/gases/useOutOfGas.ts
  type UseOutOfGasParams (line 5) | interface UseOutOfGasParams {

FILE: lib/generateSwapInitialValues.ts
  function generateSwapInitialValues (line 7) | function generateSwapInitialValues(settings: LayerSwapAppSettings, query...
  function generateSwapInitialValuesFromSwap (line 68) | function generateSwapInitialValuesFromSwap(swapResponse: SwapBasicData, ...

FILE: lib/isMobile.ts
  function isAndroid (line 1) | function isAndroid() {
  function isSmallIOS (line 4) | function isSmallIOS() {
  function isLargeIOS (line 7) | function isLargeIOS() {
  function isIOS (line 10) | function isIOS() {
  function isMobile (line 13) | function isMobile() {

FILE: lib/jwtParser.ts
  function parseJwt (line 1) | function parseJwt (token: string) {

FILE: lib/knownIds.ts
  class KnownInternalNames (line 1) | class KnownInternalNames {

FILE: lib/loopring/defs.ts
  type LOOPRING_URLs (line 3) | enum LOOPRING_URLs {
  type ChainId (line 174) | enum ChainId {
  type CounterFactualInfo (line 179) | interface CounterFactualInfo {
  type AccountInfo (line 187) | interface AccountInfo {
  type UserBalanceInfo (line 197) | interface UserBalanceInfo {
  type OffchainFeeReqType (line 206) | enum OffchainFeeReqType {
  type AccountInfo (line 222) | interface AccountInfo {
  type PublicKey (line 233) | interface PublicKey {
  constant KEY_MESSAGE (line 238) | const KEY_MESSAGE =
  type AmmPoolInfoV3 (line 244) | interface AmmPoolInfoV3 {
  type LoopringMap (line 262) | interface LoopringMap<T> {
  type MarketInfo (line 265) | interface MarketInfo {
  type MarketStatus (line 276) | enum MarketStatus {
  constant SEP (line 281) | const SEP = ",";
  type TokenAddress (line 283) | type TokenAddress = string;
  type TokenInfo (line 284) | interface TokenInfo {
  type TOKENMAPLIST (line 311) | type TOKENMAPLIST = {
  type TokenRelatedInfo (line 330) | interface TokenRelatedInfo {
  type DefiMarketInfo (line 334) | interface DefiMarketInfo {
  type DefiMarketStatus (line 357) | enum DefiMarketStatus {
  type PublicKey (line 371) | interface PublicKey {
  type TokenVolumeV3 (line 376) | interface TokenVolumeV3 {
  type UpdateAccountRequestV3 (line 380) | interface UpdateAccountRequestV3 {
  type UnlockedAccount (line 401) | type UnlockedAccount = {
  type OriginTransferRequestV3 (line 407) | interface OriginTransferRequestV3 {
  type LpFee (line 425) | type LpFee = {
  type ExchangeInfo (line 435) | interface ExchangeInfo {

FILE: lib/loopring/eddsa.ts
  class Signature (line 36) | class Signature {
    method constructor (line 40) | constructor(R: Point, s: FQ) {
    method toStr (line 45) | toStr() {
  class SignedMessage (line 50) | class SignedMessage {
    method constructor (line 55) | constructor(A: Point, sig: Signature, msg: BigNumber) {
    method toStr (line 61) | toStr() {
  class SignatureScheme (line 68) | class SignatureScheme {
    method to_bytes (line 69) | static to_bytes(arg: BigNumber) {
    method prehash_message (line 93) | static prehash_message(M: BigNumber) {
    method hash_secret_python (line 109) | static hash_secret_python(k: FQ, arg: BigNumber) {
    method B (line 134) | static B() {
    method sign (line 138) | static sign(msg: BigNumber, key: FQ, B: Point) {
    method as_scalar (line 166) | static as_scalar(point: Point) {
    method hash_public (line 170) | static hash_public(R: Point, A: Point, M: BigNumber) {
  function bnToBuf (line 189) | function bnToBuf(bn: string) {
  function bnToBufWithFixedLength (line 207) | function bnToBufWithFixedLength(bn: string, outputLength: number) {
  function bufToBn (line 237) | function bufToBn(buf: any) {
  function bytesToHexString (line 253) | function bytesToHexString(bytes: any) {

FILE: lib/loopring/field.ts
  class field (line 4) | class field {
  class FQ (line 14) | class FQ {
    method constructor (line 18) | constructor(n: BigNumber, field_modulus = field.SNARK_SCALAR_FIELD) {
    method add (line 27) | add(other: BigNumber) {
    method mul (line 33) | mul(other: BigNumber) {
    method sub (line 39) | sub(other: BigNumber) {
    method div (line 50) | div(other: BigNumber) {
    method one (line 60) | static one(modulus: BigNumber = field.SNARK_SCALAR_FIELD) {
    method zero (line 64) | static zero(modulus: BigNumber = field.SNARK_SCALAR_FIELD) {
  function modulo (line 70) | function modulo(n: BigNumber, p: BigNumber, m: BigNumber) {

FILE: lib/loopring/formatter.ts
  function addHexPrefix (line 32) | function addHexPrefix(input: any) {
  function toBuffer (line 44) | function toBuffer(mixed: any): Buffer {
  function zeroPad (line 60) | function zeroPad(num: any, places: any) {
  function toHex (line 69) | function toHex(mixed: number | BigNumber | BN | Buffer | string | Uint8A...
  function toNumber (line 93) | function toNumber(mixed: number | BigNumber | BN | Buffer | string | Uin...
  function toBig (line 118) | function toBig(mixed: number | BigNumber | BN | Buffer | string | Uint8A...
  function toBN (line 142) | function toBN(mixed: any) {
  function fromGWEI (line 151) | function fromGWEI(value: any) {
  function toGWEI (line 160) | function toGWEI(value: any) {
  function formatKey (line 169) | function formatKey(mixed: Buffer | string | Uint8Array) {
  function formatAddress (line 185) | function formatAddress(mixed: Buffer | string | Uint8Array) {
  function clearHexPrefix (line 201) | function clearHexPrefix(input: any) {
  function padLeftEven (line 213) | function padLeftEven(hex: any) {
  function getDisplaySymbol (line 222) | function getDisplaySymbol(settingsCurrency: any) {
  function toFixed (line 240) | function toFixed(number: any, precision: any, ceil: any) {
  function formatEddsaKey (line 258) | function formatEddsaKey(key: any) {
  function numberWithCommas (line 268) | function numberWithCommas(number: any) {
  function sortObjDictionary (line 286) | function sortObjDictionary(obj: { [key: string]: any }): Map<string, any> {
  function makeMarket (line 297) | function makeMarket<R extends TokenInfo = TokenInfo>(raw_data: R[]): TOK...
  function makeAmmPool (line 349) | function makeAmmPool<R>(raw_data: any): {
  function makeMarkets (line 391) | function makeMarkets<R, C extends MarketInfo>(
  function makeMarketsWithIdIndex (line 470) | function makeMarketsWithIdIndex<C extends MarketInfo>(
  function makeInvestMarkets (line 551) | function makeInvestMarkets<C extends DefiMarketInfo>(

FILE: lib/loopring/helpers.ts
  type UnlockApiRes (line 11) | type UnlockApiRes = {
  function unlockAccount (line 22) | async function unlockAccount(accInfo: AccountInfo, config: Config)
  function getExchangeInfo (line 61) | async function getExchangeInfo()
  function getOffchainFeeAmt (line 67) | async function getOffchainFeeAmt
  type StorageIdRes (line 75) | type StorageIdRes = {
  function getNextStorageId (line 80) | async function getNextStorageId
  type TransferProps (line 96) | type TransferProps = {
  type TransferApiRes (line 105) | type TransferApiRes = {
  function transfer (line 118) | async function transfer
  function submitInternalTransfer (line 164) | async function submitInternalTransfer
  type ActivateAccountProps (line 186) | type ActivateAccountProps = {
  function activateAccount (line 191) | async function activateAccount

FILE: lib/loopring/jubjub.ts
  class jubjub (line 23) | class jubjub {
  class Point (line 33) | class Point {
    method constructor (line 37) | constructor(x: FQ, y: FQ) {
    method generate (line 42) | static generate() {
    method mul (line 49) | mul(scaler: BigNumber) {
    method add (line 68) | add(other: Point) {
    method infinity (line 93) | static infinity() {

FILE: lib/loopring/permutation.ts
  class PoseidonParams (line 23) | class PoseidonParams {
    method constructor (line 34) | constructor(
  class permunation (line 68) | class permunation {
    method H (line 69) | static H(arg: string) {
    method H_Bigint (line 89) | static H_Bigint(arg: BigNumber) {
    method poseidon_constants (line 108) | static poseidon_constants(p: BigNumber, seed: string, n: number) {
    method poseidon_matrix (line 122) | static poseidon_matrix(p: BigNumber, seed: string, t: number) {
    method poseidon_sbox (line 144) | static poseidon_sbox(state: [BigNumber], i: number, params: PoseidonPa...
    method poseidon_mix (line 173) | static poseidon_mix(state: [BigNumber], M: [[BigNumber]], p: BigNumber) {
    method poseidon (line 218) | static poseidon(inputs: [BigNumber], params: PoseidonParams) {

FILE: lib/loopring/poseidon/EDDSAUtil.ts
  class EDDSAUtil (line 7) | class EDDSAUtil {
    method sign (line 9) | static sign(PrivateKey: string | undefined, hash: any) {
    method formatted (line 27) | static formatted(hexString: string) {
    method generateKeyPair (line 40) | static generateKeyPair(seed: any) {
    method pack (line 64) | static pack(publicKeyX: string, publicKeyY: string) {

FILE: lib/loopring/poseidon/babyJub.ts
  class babyJub (line 6) | class babyJub {
    method packPoint (line 8) | static packPoint(P0: BigNumber, P1: BigNumber) {
    method lt (line 17) | static lt(a: BigNumber, b: BigNumber) {
    method gt (line 35) | static gt(a: BigNumber, b: BigNumber) {

FILE: lib/loopring/poseidon/eddsa.ts
  class Signature (line 36) | class Signature {
    method constructor (line 40) | constructor(R: Point, s: FQ) {
    method toStr (line 45) | toStr() {
  class SignedMessage (line 50) | class SignedMessage {
    method constructor (line 55) | constructor(A: Point, sig: Signature, msg: BigNumber) {
    method toStr (line 61) | toStr() {
  class SignatureScheme (line 68) | class SignatureScheme {
    method to_bytes (line 69) | static to_bytes(arg: BigNumber) {
    method prehash_message (line 93) | static prehash_message(M: BigNumber) {
    method hash_secret_python (line 109) | static hash_secret_python(k: FQ, arg: BigNumber) {
    method B (line 137) | static B() {
    method sign (line 141) | static sign(msg: BigNumber, key: FQ, B: Point) {
    method as_scalar (line 169) | static as_scalar(point: Point) {
    method hash_public (line 173) | static hash_public(R: Point, A: Point, M: BigNumber) {
  function bnToBuf (line 192) | function bnToBuf(bn: string) {
  function bnToBufWithFixedLength (line 210) | function bnToBufWithFixedLength(bn: string, outputLength: number) {
  function bufToBn (line 240) | function bufToBn(buf: any) {
  function bytesToHexString (line 256) | function bytesToHexString(bytes: any) {

FILE: lib/loopring/utils.ts
  constant SNARK_SCALAR_FIELD (line 23) | const SNARK_SCALAR_FIELD = new BigInteger(
  type EddsaKey (line 55) | type EddsaKey = {
  function generateKey (line 66) | function generateKey(sig: string): EddsaKey {
  function convertPublicKey2 (line 138) | function convertPublicKey2(pk: { x: string, y: string }) {
  function getUpdateAccountEcdsaTypedData (line 143) | function getUpdateAccountEcdsaTypedData(data: UpdateAccountRequestV3, ch...
  function getTransferTypedData (line 185) | function getTransferTypedData(
  function get_EddsaSig_Transfer (line 230) | function get_EddsaSig_Transfer(request: OriginTransferRequestV3, eddsaKe...
  function getEdDSASig (line 249) | function getEdDSASig(

FILE: lib/nft/nftBalanceResolver.ts
  class NftBalanceResolver (line 4) | class NftBalanceResolver {
    method getBalance (line 9) | async getBalance({ address, network, contractAddress }: { address: str...

FILE: lib/nft/providers/starknetNftProvider.ts
  constant NFT_ABI (line 6) | const NFT_ABI = [
  class StarknetNftProvider (line 26) | class StarknetNftProvider implements Provider {
    method supportsNetwork (line 27) | supportsNetwork(network: Network): boolean {

FILE: lib/nft/providers/types.ts
  type NftBalanceProps (line 3) | interface NftBalanceProps {
  type Provider (line 9) | interface Provider {

FILE: lib/openLink.ts
  constant TEMP_DATA_ITEM_NAME (line 6) | const TEMP_DATA_ITEM_NAME = "link_temp_data"
  type OpenLinkArgs (line 12) | type OpenLinkArgs = {
  type LinkTempData (line 19) | type LinkTempData = {
  function OpenLink (line 25) | function OpenLink({ link, swapId, query }: OpenLinkArgs): (Window | null) {
  function isMobile (line 36) | function isMobile(opts?: any) {

FILE: lib/resolveChain.ts
  function resolveChain (line 6) | function resolveChain(network: Network) {

FILE: lib/resolveTransports.ts
  type TransportOptions (line 4) | type TransportOptions = {
  constant DEFAULT_RETRY_COUNT (line 10) | const DEFAULT_RETRY_COUNT = 3
  constant DEFAULT_TIMEOUT_MS (line 11) | const DEFAULT_TIMEOUT_MS = 60000
  constant DEFAULT_BATCH (line 12) | const DEFAULT_BATCH = false

FILE: lib/retry.ts
  function retryWithExponentialBackoff (line 1) | async function retryWithExponentialBackoff(fn, maxAttempts = 3, baseDela...
  function retry (line 23) | async function retry(fn, maxAttempts = 3, baseDelayMs = 1000) {

FILE: lib/virtual/core/index.ts
  type ScrollDirection (line 7) | type ScrollDirection = 'forward' | 'backward'
  type ScrollAlignment (line 9) | type ScrollAlignment = 'start' | 'center' | 'end' | 'auto'
  type ScrollBehavior (line 11) | type ScrollBehavior = 'auto' | 'smooth'
  type ScrollToOptions (line 13) | interface ScrollToOptions {
  type ScrollToOffsetOptions (line 18) | type ScrollToOffsetOptions = ScrollToOptions
  type ScrollToIndexOptions (line 20) | type ScrollToIndexOptions = ScrollToOptions
  type Range (line 22) | interface Range {
  type Key (line 29) | type Key = number | string | bigint
  type VirtualItem (line 31) | interface VirtualItem {
  type Rect (line 40) | interface Rect {
  type ObserveOffsetCallBack (line 144) | type ObserveOffsetCallBack = (offset: number, isScrolling: boolean) => void
  type VirtualizerOptions (line 297) | interface VirtualizerOptions<
  class Virtualizer (line 353) | class Virtualizer<
    method constructor (line 414) | constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {
  function calculateRange (line 1095) | function calculateRange({

FILE: lib/virtual/core/utils.ts
  type NoInfer (line 1) | type NoInfer<A extends any> = [A][A extends any ? 0 : never]
  type PartialKeys (line 3) | type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
  function memo (line 5) | function memo<TDeps extends ReadonlyArray<any>, TResult>(
  function notUndefined (line 78) | function notUndefined<T>(value: T | undefined, msg?: string): T {

FILE: lib/virtual/index.tsx
  function useVirtualizerBase (line 19) | function useVirtualizerBase<
  function useVirtualizer (line 56) | function useVirtualizer<
  function useWindowVirtualizer (line 73) | function useWindowVirtualizer<TItemElement extends Element>(

FILE: lib/wallets/bitcoin/getConnections.ts
  type GetConnectionsReturnType (line 6) | type GetConnectionsReturnType = Compute<Connection>[]
  function getConnections (line 10) | function getConnections(config: Config): GetConnectionsReturnType {

FILE: lib/wallets/bitcoin/useAccount.ts
  type UseAccountParameters (line 16) | type UseAccountParameters<config extends Config = Config> =
  type UseAccountReturnType (line 19) | type UseAccountReturnType<config extends Config = Config> =
  function useAccount (line 22) | function useAccount<C extends Config = ResolvedRegister['config']>(

FILE: lib/wallets/bitcoin/useBitcoin.ts
  function useBitcoin (line 19) | function useBitcoin(): WalletProvider {
  type ResolveWalletProps (line 156) | type ResolveWalletProps = {

FILE: lib/wallets/bitcoin/useSyncExternalStoreWithTracked.ts
  function useSyncExternalStoreWithTracked (line 10) | function useSyncExternalStoreWithTracked<

FILE: lib/wallets/connectors/browserInjected/index.ts
  function browserInjected (line 4) | function browserInjected() {

FILE: lib/wallets/connectors/explicitInjectedProviderDetected.ts
  function explicitInjectedProviderDetected (line 2) | function explicitInjectedProviderDetected() {
  type Evaluate (line 10) | type Evaluate<type> = { [key in keyof type]: type[key] } & unknown;
  type WalletProvider (line 12) | type WalletProvider = Evaluate<
  type WindowProvider (line 32) | type WindowProvider = {
  type WalletProviderFlags (line 39) | type WalletProviderFlags =

FILE: lib/wallets/connectors/resolveConnectors/walletConnect.ts
  type WalletConnectConnector (line 23) | type WalletConnectConnector = Connector & {
  type EthereumProviderOptions (line 28) | type EthereumProviderOptions = Parameters<(typeof EthereumProvider)['ini...
  type WalletConnectParameters (line 30) | type WalletConnectParameters = Compute<
  type Params (line 76) | type Params = {
  function walletConnect (line 88) | function walletConnect(parameters: Params) {
  function getResolveUri (line 487) | function getResolveUri(

FILE: lib/wallets/connectors/types.ts
  type LSConnector (line 3) | type LSConnector = Connector & {

FILE: lib/wallets/connectors/useSyncProviders/EthereumProviderTypes.d.ts
  type EIP6963ProviderInfo (line 4) | interface EIP6963ProviderInfo {
  type EIP1193Provider (line 12) | interface EIP1193Provider {
  type EIP6963ProviderDetail (line 22) | interface EIP6963ProviderDetail {
  type EIP6963AnnounceProviderEvent (line 28) | type EIP6963AnnounceProviderEvent = {

FILE: lib/wallets/connectors/useSyncProviders/store.ts
  type WindowEventMap (line 2) | interface WindowEventMap {
  function onAnnouncement (line 14) | function onAnnouncement(event: EIP6963AnnounceProviderEvent) {

FILE: lib/wallets/connectors/utils/isMobile.ts
  function isAndroid (line 2) | function isAndroid(): boolean {
  function isSmallIOS (line 8) | function isSmallIOS(): boolean {
  function isLargeIOS (line 14) | function isLargeIOS(): boolean {
  function isIOS (line 22) | function isIOS(): boolean {
  function isMobile (line 26) | function isMobile(): boolean {

FILE: lib/wallets/evm/constants.ts
  constant HIDDEN_WALLETCONNECT_ID (line 9) | const HIDDEN_WALLETCONNECT_ID = 'hiddenWalletConnect'

FILE: lib/wallets/evm/useEVM.ts
  constant EVM_NS (line 42) | const EVM_NS = 'eip155'
  type DynamicWalletMetadata (line 44) | type DynamicWalletMetadata = DynamicWcMetadata
  method onDisplayUri (line 58) | onDisplayUri(listener) {
  function useEVM (line 103) | function useEVM(): WalletProvider {
  type ResolveWalletProps (line 443) | type ResolveWalletProps = {
  function attemptGetAccount (line 553) | async function attemptGetAccount(config: Parameters<typeof getAccount>[0...
  function dedupePreferInjected (line 565) | function dedupePreferInjected(arr: Connector<CreateConnectorFn>[]) {

FILE: lib/wallets/fuel/Bako.ts
  class BAKO_STATE (line 3) | class BAKO_STATE {
  class BakoRequestAPI (line 8) | class BakoRequestAPI {
    method constructor (line 11) | constructor(baseUrl: string) {
    method get (line 15) | async get(pathname: string) {
    method delete (line 38) | async delete(pathname: string) {

FILE: lib/wallets/fuel/useFuel.ts
  function useFuel (line 31) | function useFuel(): WalletProvider {
  type ResolveWalletProps (line 223) | type ResolveWalletProps = {

FILE: lib/wallets/paradex/Authorize/Ethereum.ts
  function AuhorizeEthereum (line 5) | async function AuhorizeEthereum(ethersSigner: providers.JsonRpcSigner) {

FILE: lib/wallets/paradex/Authorize/Starknet.ts
  function AuthorizeStarknet (line 4) | async function AuthorizeStarknet(starknetAccount: AccountInterface) {

FILE: lib/wallets/paradex/lib/account.ts
  type Account (line 9) | interface Account extends Starknet.Account {}
  type FromEthSignerParams (line 11) | interface FromEthSignerParams {
  function fromEthSigner (line 21) | async function fromEthSigner({
  type FromStarknetAccountParams (line 40) | interface FromStarknetAccountParams {
  function fromStarknetAccount (line 53) | async function fromStarknetAccount({
  type GenerateAccountAddressParams (line 81) | interface GenerateAccountAddressParams {
  function generateAccountAddress (line 93) | function generateAccountAddress({

FILE: lib/wallets/paradex/lib/config.ts
  type RawBridgedTokenConfig (line 9) | interface RawBridgedTokenConfig {
  type RawParadexConfig (line 19) | interface RawParadexConfig {
  type BridgedTokenConfig (line 35) | interface BridgedTokenConfig {
  type ParadexConfig (line 45) | interface ParadexConfig {
  type ParadexEnvironment (line 58) | type ParadexEnvironment = 'testnet' | 'prod';
  function fetchConfig (line 64) | async function fetchConfig(
  function assertParadexEnvironment (line 83) | function assertParadexEnvironment(
  function getParadexApiUrl (line 91) | function getParadexApiUrl(environment: ParadexEnvironment): string {
  function buildConfig (line 95) | function buildConfig(rawConfig: RawParadexConfig): ParadexConfig {
  function getStarknetChainId (line 124) | function getStarknetChainId(rawConfig: RawParadexConfig): string {

FILE: lib/wallets/paradex/lib/constants.ts
  constant ETHEREUM_MAINNET_CHAIN_ID (line 1) | const ETHEREUM_MAINNET_CHAIN_ID = '1';
  constant ETHEREUM_TESTNET_CHAIN_ID (line 2) | const ETHEREUM_TESTNET_CHAIN_ID = '11155111';
  constant STARKNET_MAINNET_CHAIN_ID (line 4) | const STARKNET_MAINNET_CHAIN_ID = 'SN_MAIN';
  constant STARKNET_TESTNET_CHAIN_ID (line 5) | const STARKNET_TESTNET_CHAIN_ID = 'SN_SEPOLIA';
  constant LOCAL_STORAGE_KEY (line 7) | const LOCAL_STORAGE_KEY = 'ls-paradex-accounts';

FILE: lib/wallets/paradex/lib/ethereum-signer.ts
  type Hex (line 3) | type Hex = `0x${string}`;
  type TypedData (line 5) | interface TypedData {
  type EthereumSigner (line 22) | interface EthereumSigner {
  function ethersSignerAdapter (line 26) | function ethersSignerAdapter(
  function buildEthereumStarkKeyTypedData (line 44) | function buildEthereumStarkKeyTypedData(

FILE: lib/wallets/paradex/lib/paraclear-provider.ts
  class DefaultProvider (line 5) | class DefaultProvider extends Starknet.RpcProvider {
    method constructor (line 6) | constructor(config: ParadexConfig) {
  type ParaclearProvider (line 16) | type ParaclearProvider = DefaultProvider;

FILE: lib/wallets/paradex/lib/paraclear.ts
  constant MAX_FEE (line 9) | const MAX_FEE = BigNumber('5e17');
  type GetBalanceParams (line 11) | interface GetBalanceParams {
  type GetBalanceResult (line 25) | interface GetBalanceResult {
  function getTokenBalance (line 37) | async function getTokenBalance(
  type GetSocializedLossFactorParams (line 76) | interface GetSocializedLossFactorParams {
  type GetSocializedLossFactorResult (line 81) | interface GetSocializedLossFactorResult {
  function getSocializedLossFactor (line 92) | async function getSocializedLossFactor(
  type GetReceivableAmountParams (line 121) | interface GetReceivableAmountParams {
  type GetReceivableAmountResult (line 137) | interface GetReceivableAmountResult {
  function getReceivableAmount (line 166) | async function getReceivableAmount(
  type WithdrawParams (line 202) | interface WithdrawParams {
  type TransactionResult (line 233) | interface TransactionResult {
  function withdraw (line 250) | async function withdraw(
  function fromChainSize (line 284) | function fromChainSize(size: BigNumber, decimals: number): BigNumber {
  function toChainSize (line 288) | function toChainSize(size: string, decimals: number): BigNumber {
  function intNoise (line 298) | function intNoise(max: number): number {

FILE: lib/wallets/paradex/lib/starknet-account-support.ts
  type SignatureFormat (line 3) | type SignatureFormat =
  type CheckResult (line 24) | interface CheckResult {
  class AccountSupport (line 29) | class AccountSupport {
    method constructor (line 32) | constructor(
    method testClassHash (line 41) | private testClassHash(classHash: string): boolean {
    method getFormat (line 45) | private async getFormat(): Promise<SignatureFormat> {
    method check (line 198) | async check(): Promise<CheckResult> {
    method getSeedFromSignature (line 266) | getSeedFromSignature(signature: Starknet.Signature): string {

FILE: lib/wallets/paradex/lib/starknet-signer.ts
  function buildStarknetStarkKeyTypedData (line 10) | function buildStarknetStarkKeyTypedData(
  type StarknetKeypair (line 34) | type StarknetKeypair = [string, string];
  function getStarkKeypairFromStarknetSignature (line 42) | async function getStarkKeypairFromStarknetSignature(
  function getAccountSupport (line 55) | async function getAccountSupport(
  function getPublicProvider (line 88) | function getPublicProvider(chainId: string, nodeUrl: string): Starknet.P...
  function getAccountClassHash (line 94) | async function getAccountClassHash(
  function buildAccountContract (line 109) | async function buildAccountContract(

FILE: lib/wallets/paradex/lib/types.ts
  type Hex (line 3) | type Hex = `0x${string}`;
  type TypedData (line 5) | interface TypedData {
  type EthereumSigner (line 18) | interface EthereumSigner {

FILE: lib/wallets/paradex/useParadex.ts
  function useParadex (line 39) | function useParadex(): WalletProvider {
  type ResolveWalletsListProps (line 263) | type ResolveWalletsListProps = {
  type ResolveWalletProps (line 285) | type ResolveWalletProps = {

FILE: lib/wallets/solana/SolanaWalletConnectAdapter.ts
  type UniversalProviderType (line 19) | type UniversalProviderType = InstanceType<typeof UniversalProviderClass>
  constant WALLET_CONNECT_ICON (line 35) | const WALLET_CONNECT_ICON =
  type SolanaWalletConnectAdapterConfig (line 40) | type SolanaWalletConnectAdapterConfig = {
  type DisplayUriListener (line 45) | type DisplayUriListener = (uri: string) => void
  class SolanaWalletConnectAdapter (line 47) | class SolanaWalletConnectAdapter extends BaseSignerWalletAdapter {
    method constructor (line 66) | constructor(config: SolanaWalletConnectAdapterConfig) {
    method publicKey (line 78) | get publicKey(): PublicKey | null {
    method connecting (line 82) | get connecting(): boolean {
    method readyState (line 86) | get readyState(): WalletReadyState {
    method onDisplayUri (line 90) | onDisplayUri(listener: DisplayUriListener): () => void {
    method warmup (line 100) | warmup(): void {
    method getProvider (line 106) | private async getProvider(): Promise<UniversalProviderType> {
    method autoConnect (line 140) | async autoConnect(): Promise<void> {
    method connect (line 148) | async connect(): Promise<void> {
    method bindSessionListeners (line 199) | private bindSessionListeners() {
    method publicKeyFromSession (line 206) | private publicKeyFromSession(session: SessionTypes.Struct): PublicKey {
    method disconnect (line 213) | async disconnect(): Promise<void> {
    method signTransaction (line 250) | async signTransaction<T extends Transaction | VersionedTransaction>(tr...
    method signMessage (line 290) | async signMessage(message: Uint8Array): Promise<Uint8Array> {
    method signAndSendTransaction (line 315) | async signAndSendTransaction<T extends Transaction | VersionedTransact...
    method signAllTransactions (line 337) | async signAllTransactions<T extends Transaction | VersionedTransaction...
    method serialize (line 378) | private serialize(transaction: Transaction | VersionedTransaction): st...
    method deserialize (line 382) | private deserialize(serializedTransaction: string, versioned = false):...

FILE: lib/wallets/solana/useSVM.tsx
  constant SOLANA_NS (line 34) | const SOLANA_NS = 'solana'
  constant SOLANA_WC_ADAPTER_NAME (line 35) | const SOLANA_WC_ADAPTER_NAME = 'WalletConnect'
  function useSVM (line 39) | function useSVM(): WalletProvider {
  function resolveSupportedNetworks (line 323) | function resolveSupportedNetworks(supportedNetworks: string[], connector...

FILE: lib/wallets/starknet/useStarknet.ts
  function useStarknet (line 10) | function useStarknet(): WalletProvider {
  type ResolveStarknetWalletProps (line 144) | type ResolveStarknetWalletProps = {
  function resolveStarknetWallet (line 155) | async function resolveStarknetWallet(props: ResolveStarknetWalletProps):...

FILE: lib/wallets/ton/useTON.ts
  function useTON (line 8) | function useTON(): WalletProvider {

FILE: lib/wallets/tron/useTron.ts
  function useTron (line 8) | function useTron(): WalletProvider {

FILE: lib/wallets/utils/sleep.ts
  function sleep (line 1) | function sleep(ms: number): Promise<void> {

FILE: lib/wallets/walletConnect/api.ts
  constant BASE (line 3) | const BASE = 'https://api.web3modal.org'
  type Web3ModalWallet (line 5) | type Web3ModalWallet = {
  type GetWalletsResponse (line 19) | type GetWalletsResponse = {
  type FetchWalletsParams (line 26) | type FetchWalletsParams = {
  constant EVM_CHAINS (line 33) | const EVM_CHAINS = [
  constant SOLANA_CHAINS (line 38) | const SOLANA_CHAINS = [
  function chainsForNamespace (line 43) | function chainsForNamespace(namespace: string): string {
  constant DANGEROUS_URL_PROTOCOLS (line 49) | const DANGEROUS_URL_PROTOCOLS = ['javascript:', 'data:', 'vbscript:', 'f...
  function isValidHttpUrl (line 51) | function isValidHttpUrl(urlStr: string): boolean {
  function isValidWalletLink (line 63) | function isValidWalletLink(urlStr: string): boolean {
  function isValidImageId (line 72) | function isValidImageId(id: string): boolean {
  function walletImageUrl (line 76) | function walletImageUrl(imageId: string): string {
  function fetchWallets (line 83) | async function fetchWallets(params: FetchWalletsParams): Promise<GetWall...

FILE: lib/wallets/walletConnect/buildDeepLink.ts
  type BuildDeepLinkInput (line 11) | type BuildDeepLinkInput = {
  function buildDeepLink (line 25) | function buildDeepLink({ id, mobile }: BuildDeepLinkInput, uri: string):...

FILE: lib/wallets/walletConnect/config.ts
  constant WALLETCONNECT_PROJECT_ID (line 3) | const WALLETCONNECT_PROJECT_ID =
  constant WALLETCONNECT_METADATA (line 6) | const WALLETCONNECT_METADATA = {

FILE: lib/wallets/walletConnect/createRegistryConnector.ts
  type RegistryConnector (line 4) | type RegistryConnector = RegistryAttachedConnector<InternalConnector>

FILE: lib/wallets/walletConnect/dynamicMetadata.ts
  constant STORAGE_KEY (line 3) | const STORAGE_KEY = 'ls_walletconnect_dynamic_metadata'
  type Store (line 5) | type Store = Record<string, Record<string, DynamicWcMetadata>>

FILE: lib/wallets/walletConnect/mapConnectError.ts
  function mapConnectError (line 6) | function mapConnectError(e: unknown): Error {

FILE: lib/wallets/walletConnect/mapWallet.ts
  function slugify (line 6) | function slugify(name: string): string {
  constant SLUG_OVERRIDES (line 16) | const SLUG_OVERRIDES: Record<string, string> = {
  function mapWallet (line 20) | function mapWallet(wallet: Web3ModalWallet): WalletConnectWalletBase {

FILE: lib/wallets/walletConnect/registry.ts
  constant SLUGS_TO_FILTER (line 6) | const SLUGS_TO_FILTER = ['okx-wallet-1', 'ready']
  constant SOLANA_MAINNET_CAIP (line 8) | const SOLANA_MAINNET_CAIP = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
  constant SOLANA_DEPRECATED_MAINNET_CAIP (line 9) | const SOLANA_DEPRECATED_MAINNET_CAIP = 'solana:4sGjMW1sUnHzSxGspuhpqLDx6...
  constant SOLANA_DEVNET_CAIP (line 10) | const SOLANA_DEVNET_CAIP = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1'
  constant SOLANA_DEPRECATED_DEVNET_CAIP (line 11) | const SOLANA_DEPRECATED_DEVNET_CAIP = 'solana:8E9rvCKLFQia2Y35HXjjpWzj8w...
  constant SOLANA_CAIP_IDS (line 15) | const SOLANA_CAIP_IDS = isSandbox
  type ResolveOptions (line 19) | type ResolveOptions = {
  type ResolveResult (line 27) | type ResolveResult = {
  function resolveWalletConnectWallets (line 33) | async function resolveWalletConnectWallets(opts: ResolveOptions = {}): P...

FILE: lib/wallets/walletConnect/subscribeDisplayUri.ts
  type DisplayUriListener (line 3) | type DisplayUriListener = (uri: string) => void
  type DisplayUriSource (line 10) | type DisplayUriSource = {
  type SubscribeDisplayUriParams (line 14) | type SubscribeDisplayUriParams = {
  function subscribeDisplayUri (line 31) | function subscribeDisplayUri(params: SubscribeDisplayUriParams): () => v...

FILE: lib/wallets/walletConnect/types.ts
  type WalletConnectMobile (line 1) | type WalletConnectMobile = {
  type WalletConnectDesktop (line 6) | type WalletConnectDesktop = {
  type WalletConnectWalletBase (line 16) | type WalletConnectWalletBase = {
  type DynamicWcMetadata (line 31) | type DynamicWcMetadata = {
  type QrCodeState (line 43) | type QrCodeState =
  constant WC_REGISTRY_MARKER (line 52) | const WC_REGISTRY_MARKER = Symbol('wcRegistry')
  type RegistryAttachedConnector (line 54) | type RegistryAttachedConnector<T> = T & {

FILE: lib/wallets/walletConnect/useAdditionalConnectors.ts
  type PageCacheEntry (line 6) | type PageCacheEntry = {
  type NamespaceCache (line 16) | type NamespaceCache = Map<string, Map<string, PageCacheEntry>>
  type WalletConnectRequestResult (line 17) | type WalletConnectRequestResult = {
  constant DEFAULT_PAGE_SIZE (line 26) | const DEFAULT_PAGE_SIZE = 40
  constant MAX_CACHED_PAGES_PER_QUERY (line 27) | const MAX_CACHED_PAGES_PER_QUERY = 20
  constant MAX_CACHED_QUERIES_PER_NAMESPACE (line 28) | const MAX_CACHED_QUERIES_PER_NAMESPACE = 50
  function fetchAdditionalConnectorsPage (line 74) | async function fetchAdditionalConnectorsPage(namespace: string, params: ...
  function useAdditionalConnectors (line 122) | function useAdditionalConnectors(namespace: string) {

FILE: next.config.js
  constant REMOTE_PATTERNS (line 18) | const REMOTE_PATTERNS = [
  method rewrites (line 83) | async rewrites() {

FILE: pages/404.tsx
  function Custom404 (line 10) | function Custom404() {

FILE: pages/_app.js
  constant INTERCOM_APP_ID (line 27) | const INTERCOM_APP_ID = 'h5zisg78'
  function App (line 29) | function App({ Component, pageProps }) {

FILE: pages/_document.tsx
  type TrackEvent (line 4) | enum TrackEvent {
  function Document (line 10) | function Document() {

FILE: pages/campaigns/[campaign].tsx
  function RewardsPage (line 10) | function RewardsPage({ settings, themeData, apiKey }: InferGetServerSide...

FILE: pages/campaigns/index.tsx
  function CampaignsPage (line 10) | function CampaignsPage({ settings, themeData, apiKey }: InferGetServerSi...

FILE: pages/index.tsx
  constant SWAP_KEY_PATTERN (line 14) | const SWAP_KEY_PATTERN = /^\/swaps\/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f...
  function Home (line 16) | function Home({ settings, themeData, apiKey }: InferGetServerSidePropsTy...
  function updatePendingCount (line 48) | function updatePendingCount(useSWRNext) {

FILE: pages/nocookies.tsx
  function Salon (line 4) | function Salon() {

FILE: pages/salon.tsx
  function Salon (line 11) | function Salon({ settings, apiKey }: InferGetServerSidePropsType<typeof ...

FILE: pages/transactions.tsx
  function Transactions (line 11) | function Transactions({ settings, themeData, apiKey }: InferGetServerSid...

FILE: stores/balanceStore.ts
  function getKey (line 9) | function getKey(address: string, networkOrName: NetworkWithTokens | stri...
  type Status (line 14) | type Status = 'loading' | 'success' | 'error'
  type BalanceEntry (line 15) | interface BalanceEntry {
  type Options (line 22) | type Options = {
  type BalanceStore (line 29) | interface BalanceStore {
  constant MAX_CONCURRENT (line 52) | const MAX_CONCURRENT = 500
  function processQueue (line 55) | function processQueue() {

FILE: stores/contractAddressStore.ts
  type ContractStatus (line 8) | interface ContractStatus {
  type ConfirmedAddress (line 14) | interface ConfirmedAddress {
  type ContractCheckResult (line 19) | interface ContractCheckResult {
  type ContractAddressState (line 25) | interface ContractAddressState {

FILE: stores/contractWalletsStore.ts
  type WalletState (line 4) | interface WalletState {
  class ContractWalletInfo (line 11) | class ContractWalletInfo {
    method keyDeriver (line 16) | public static keyDeriver(address: string, network_internal_name: strin...

FILE: stores/manualDestAddressesStore.ts
  type ManualDestAddress (line 4) | type ManualDestAddress = {
  type ManualDestAddressesState (line 9) | interface ManualDestAddressesState {

FILE: stores/recentRoutesStore.ts
  type RoutesHistory (line 4) | type RoutesHistory = {
  type RouteItem (line 9) | type RouteItem = {
  type UpdateHistoryArgs (line 15) | type UpdateHistoryArgs = {
  type RecentNetworksState (line 20) | interface RecentNetworksState {

FILE: stores/routeSortingStore.ts
  type SortingOption (line 4) | enum SortingOption {
  type RouteSortingState (line 12) | type RouteSortingState = {

FILE: stores/routeTokenSwitchStore.ts
  type RouteTokenSwitchState (line 3) | type RouteTokenSwitchState = {

FILE: stores/slippageStore.ts
  type SlippageState (line 3) | type SlippageState = {

FILE: stores/starknetWalletStore.ts
  type StarknetAccountMap (line 5) | type StarknetAccountMap = { [key: string]: string }
  type StarknetStoreState (line 7) | interface StarknetStoreState {

FILE: stores/swapTransactionStore.tsx
  type SwapTransaction (line 5) | type SwapTransaction = {
  type SwapTransactionStore (line 12) | type SwapTransactionStore = {
  type SwapDepositHintClickedStore (line 18) | type SwapDepositHintClickedStore = {

FILE: stores/usdModeStore.ts
  type UsdModeState (line 4) | type UsdModeState = {

FILE: stores/walletStore.ts
  type ParadexAccount (line 5) | type ParadexAccount = {
  type WalletState (line 9) | interface WalletState {

FILE: stories/Message.stories.tsx
  type Story (line 49) | type Story = StoryObj<typeof meta>;

FILE: stories/PriceImpact.stories.tsx
  type PriceImpactRelevant (line 15) | type PriceImpactRelevant = {
  type Args (line 45) | type Args = {
  type Story (line 111) | type Story = StoryObj<Args>;

FILE: stories/Process.stories.tsx
  constant DUMMY_TRANSACTION (line 72) | const DUMMY_TRANSACTION = {
  type Story (line 139) | type Story = StoryObj<typeof meta>;

FILE: stories/SwapNotFound.stories.tsx
  type Window (line 9) | interface Window {
  type Story (line 35) | type Story = StoryObj<typeof meta>;
Condensed preview — 728 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,002K chars).
[
  {
    "path": ".claude/agents/pr-review-coordinator.md",
    "chars": 7141,
    "preview": "---\nname: pr-review-coordinator\ndescription: Orchestrates multi-perspective PR reviews. Runs specialized reviewers (perf"
  },
  {
    "path": ".claude/agents/pr-reviewer-architecture.md",
    "chars": 4111,
    "preview": "---\nname: pr-reviewer-architecture\ndescription: Architecture specialist for PR reviews. Analyzes code for design pattern"
  },
  {
    "path": ".claude/agents/pr-reviewer-bugs.md",
    "chars": 6706,
    "preview": "---\nname: pr-reviewer-bugs\ndescription: Bug detection specialist for PR reviews. Analyzes code for edge cases, null chec"
  },
  {
    "path": ".claude/agents/pr-reviewer-performance.md",
    "chars": 4111,
    "preview": "---\nname: pr-reviewer-performance\ndescription: Performance specialist for PR reviews. Analyzes code for N+1 queries, mem"
  },
  {
    "path": ".claude/agents/pr-reviewer-quality.md",
    "chars": 9337,
    "preview": "---\nname: pr-reviewer-quality\ndescription: Code quality specialist for PR reviews. Analyzes code for naming conventions,"
  },
  {
    "path": ".claude/agents/pr-reviewer-react.md",
    "chars": 6607,
    "preview": "---\nname: pr-reviewer-react\ndescription: React specialist for PR reviews. Analyzes code for hooks usage, re-renders, sta"
  },
  {
    "path": ".claude/agents/pr-reviewer-security.md",
    "chars": 5958,
    "preview": "---\nname: pr-reviewer-security\ndescription: Security specialist for PR reviews. Analyzes code for authentication/authori"
  },
  {
    "path": ".claude/agents/pr-reviewer.md",
    "chars": 3784,
    "preview": "---\nname: pr-reviewer\ndescription: PR and branch review specialist. Reviews pull requests or local branches for code qua"
  },
  {
    "path": ".claude/commands/reviewchanges.md",
    "chars": 2543,
    "preview": "# reviewchanges\n\nReview all changes in the current branch compared to the dev branch using specialized subagents.\n\n## Wh"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/SKILL.md",
    "chars": 6012,
    "preview": "---\nname: vercel-react-best-practices\ndescription: React and Next.js performance optimization guidelines from Vercel Eng"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md",
    "chars": 1483,
    "preview": "---\ntitle: Store Event Handlers in Refs\nimpact: LOW\nimpactDescription: stable subscriptions\ntags: advanced, hooks, refs,"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/advanced-use-latest.md",
    "chars": 1197,
    "preview": "---\ntitle: useLatest for Stable Callback Refs\nimpact: LOW\nimpactDescription: prevents effect re-runs\ntags: advanced, hoo"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/async-api-routes.md",
    "chars": 1124,
    "preview": "---\ntitle: Prevent Waterfall Chains in API Routes\nimpact: CRITICAL\nimpactDescription: 2-10× improvement\ntags: api-routes"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/async-defer-await.md",
    "chars": 2028,
    "preview": "---\ntitle: Defer Await Until Needed\nimpact: HIGH\nimpactDescription: avoids blocking unused code paths\ntags: async, await"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/async-dependencies.md",
    "chars": 941,
    "preview": "---\ntitle: Dependency-Based Parallelization\nimpact: CRITICAL\nimpactDescription: 2-10× improvement\ntags: async, paralleli"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/async-parallel.md",
    "chars": 653,
    "preview": "---\ntitle: Promise.all() for Independent Operations\nimpact: CRITICAL\nimpactDescription: 2-10× improvement\ntags: async, p"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md",
    "chars": 2508,
    "preview": "---\ntitle: Strategic Suspense Boundaries\nimpact: HIGH\nimpactDescription: faster initial paint\ntags: async, suspense, str"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md",
    "chars": 2370,
    "preview": "---\ntitle: Avoid Barrel File Imports\nimpact: CRITICAL\nimpactDescription: 200-800ms import cost, slow builds\ntags: bundle"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/bundle-conditional.md",
    "chars": 949,
    "preview": "---\ntitle: Conditional Module Loading\nimpact: HIGH\nimpactDescription: loads large data only when needed\ntags: bundle, co"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md",
    "chars": 920,
    "preview": "---\ntitle: Defer Non-Critical Third-Party Libraries\nimpact: MEDIUM\nimpactDescription: loads after hydration\ntags: bundle"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md",
    "chars": 791,
    "preview": "---\ntitle: Dynamic Imports for Heavy Components\nimpact: CRITICAL\nimpactDescription: directly affects TTI and LCP\ntags: b"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/bundle-preload.md",
    "chars": 1149,
    "preview": "---\ntitle: Preload Based on User Intent\nimpact: MEDIUM\nimpactDescription: reduces perceived latency\ntags: bundle, preloa"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/client-event-listeners.md",
    "chars": 1969,
    "preview": "---\ntitle: Deduplicate Global Event Listeners\nimpact: LOW\nimpactDescription: single listener for N components\ntags: clie"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/client-localstorage-schema.md",
    "chars": 1950,
    "preview": "---\ntitle: Version and Minimize localStorage Data\nimpact: MEDIUM\nimpactDescription: prevents schema conflicts, reduces s"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md",
    "chars": 1644,
    "preview": "---\ntitle: Use Passive Event Listeners for Scrolling Performance\nimpact: MEDIUM\nimpactDescription: eliminates scroll del"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/client-swr-dedup.md",
    "chars": 1159,
    "preview": "---\ntitle: Use SWR for Automatic Deduplication\nimpact: MEDIUM-HIGH\nimpactDescription: automatic deduplication\ntags: clie"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-batch-dom-css.md",
    "chars": 1631,
    "preview": "---\ntitle: Batch DOM CSS Changes\nimpact: MEDIUM\nimpactDescription: reduces reflows/repaints\ntags: javascript, dom, css, "
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-cache-function-results.md",
    "chars": 1949,
    "preview": "---\ntitle: Cache Repeated Function Calls\nimpact: MEDIUM\nimpactDescription: avoid redundant computation\ntags: javascript,"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-cache-property-access.md",
    "chars": 531,
    "preview": "---\ntitle: Cache Property Access in Loops\nimpact: LOW-MEDIUM\nimpactDescription: reduces lookups\ntags: javascript, loops,"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-cache-storage.md",
    "chars": 1651,
    "preview": "---\ntitle: Cache Storage API Calls\nimpact: LOW-MEDIUM\nimpactDescription: reduces expensive I/O\ntags: javascript, localSt"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-combine-iterations.md",
    "chars": 753,
    "preview": "---\ntitle: Combine Multiple Array Iterations\nimpact: LOW-MEDIUM\nimpactDescription: reduces iterations\ntags: javascript, "
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-early-exit.md",
    "chars": 1133,
    "preview": "---\ntitle: Early Return from Functions\nimpact: LOW-MEDIUM\nimpactDescription: avoids unnecessary computation\ntags: javasc"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-hoist-regexp.md",
    "chars": 1028,
    "preview": "---\ntitle: Hoist RegExp Creation\nimpact: LOW-MEDIUM\nimpactDescription: avoids recreation\ntags: javascript, regexp, optim"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-index-maps.md",
    "chars": 834,
    "preview": "---\ntitle: Build Index Maps for Repeated Lookups\nimpact: LOW-MEDIUM\nimpactDescription: 1M ops to 2K ops\ntags: javascript"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-length-check-first.md",
    "chars": 1747,
    "preview": "---\ntitle: Early Length Check for Array Comparisons\nimpact: MEDIUM-HIGH\nimpactDescription: avoids expensive operations w"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-min-max-loop.md",
    "chars": 2290,
    "preview": "---\ntitle: Use Loop for Min/Max Instead of Sort\nimpact: LOW\nimpactDescription: O(n) instead of O(n log n)\ntags: javascri"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-set-map-lookups.md",
    "chars": 532,
    "preview": "---\ntitle: Use Set/Map for O(1) Lookups\nimpact: LOW-MEDIUM\nimpactDescription: O(n) to O(1)\ntags: javascript, set, map, d"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md",
    "chars": 1782,
    "preview": "---\ntitle: Use toSorted() Instead of sort() for Immutability\nimpact: MEDIUM-HIGH\nimpactDescription: prevents mutation bu"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rendering-activity.md",
    "chars": 564,
    "preview": "---\ntitle: Use Activity Component for Show/Hide\nimpact: MEDIUM\nimpactDescription: preserves state/DOM\ntags: rendering, a"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md",
    "chars": 1185,
    "preview": "---\ntitle: Animate SVG Wrapper Instead of SVG Element\nimpact: LOW\nimpactDescription: enables hardware acceleration\ntags:"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rendering-conditional-render.md",
    "chars": 980,
    "preview": "---\ntitle: Use Explicit Conditional Rendering\nimpact: LOW\nimpactDescription: prevents rendering 0 or NaN\ntags: rendering"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rendering-content-visibility.md",
    "chars": 814,
    "preview": "---\ntitle: CSS content-visibility for Long Lists\nimpact: HIGH\nimpactDescription: faster initial render\ntags: rendering, "
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md",
    "chars": 1039,
    "preview": "---\ntitle: Hoist Static JSX Elements\nimpact: LOW\nimpactDescription: avoids re-creation\ntags: rendering, jsx, static, opt"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md",
    "chars": 2308,
    "preview": "---\ntitle: Prevent Hydration Mismatch Without Flickering\nimpact: MEDIUM\nimpactDescription: avoids visual flicker and hyd"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rendering-svg-precision.md",
    "chars": 588,
    "preview": "---\ntitle: Optimize SVG Precision\nimpact: LOW\nimpactDescription: reduces file size\ntags: rendering, svg, optimization, s"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-defer-reads.md",
    "chars": 973,
    "preview": "---\ntitle: Defer State Reads to Usage Point\nimpact: MEDIUM\nimpactDescription: avoids unnecessary subscriptions\ntags: rer"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-dependencies.md",
    "chars": 824,
    "preview": "---\ntitle: Narrow Effect Dependencies\nimpact: LOW\nimpactDescription: minimizes effect re-runs\ntags: rerender, useEffect,"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-derived-state.md",
    "chars": 728,
    "preview": "---\ntitle: Subscribe to Derived State\nimpact: MEDIUM\nimpactDescription: reduces re-render frequency\ntags: rerender, deri"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md",
    "chars": 2958,
    "preview": "---\ntitle: Use Functional setState Updates\nimpact: MEDIUM\nimpactDescription: prevents stale closures and unnecessary cal"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md",
    "chars": 2016,
    "preview": "---\ntitle: Use Lazy State Initialization\nimpact: MEDIUM\nimpactDescription: wasted computation on every render\ntags: reac"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-memo.md",
    "chars": 1148,
    "preview": "---\ntitle: Extract to Memoized Components\nimpact: MEDIUM\nimpactDescription: enables early returns\ntags: rerender, memo, "
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md",
    "chars": 1018,
    "preview": "---\ntitle: Do not wrap a simple expression with a primitive result type in useMemo\nimpact: LOW-MEDIUM\nimpactDescription:"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/rerender-transitions.md",
    "chars": 1055,
    "preview": "---\ntitle: Use Transitions for Non-Urgent Updates\nimpact: MEDIUM\nimpactDescription: maintains UI responsiveness\ntags: re"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/server-after-nonblocking.md",
    "chars": 2012,
    "preview": "---\ntitle: Use after() for Non-Blocking Operations\nimpact: MEDIUM\nimpactDescription: faster response times\ntags: server,"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/server-auth-actions.md",
    "chars": 2647,
    "preview": "---\ntitle: Authenticate Server Actions Like API Routes\nimpact: CRITICAL\nimpactDescription: prevents unauthorized access "
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/server-cache-lru.md",
    "chars": 1353,
    "preview": "---\ntitle: Cross-Request LRU Caching\nimpact: HIGH\nimpactDescription: caches across requests\ntags: server, cache, lru, cr"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/server-cache-react.md",
    "chars": 2228,
    "preview": "---\ntitle: Per-Request Deduplication with React.cache()\nimpact: MEDIUM\nimpactDescription: deduplicates within request\nta"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/server-dedup-props.md",
    "chars": 2053,
    "preview": "---\ntitle: Avoid Duplicate Serialization in RSC Props\nimpact: LOW\nimpactDescription: reduces network payload by avoiding"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/server-parallel-fetching.md",
    "chars": 1554,
    "preview": "---\ntitle: Parallel Data Fetching with Component Composition\nimpact: CRITICAL\nimpactDescription: eliminates server-side "
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/server-serialization.md",
    "chars": 996,
    "preview": "---\ntitle: Minimize Serialization at RSC Boundaries\nimpact: HIGH\nimpactDescription: reduces data transfer size\ntags: ser"
  },
  {
    "path": ".claude/skills/vercel-react-best-practices/rules/unused-detection.md",
    "chars": 7777,
    "preview": "---\ntitle: Unused Code Detection\nimpact: MEDIUM\nimpactDescription: reduces bundle size, improves maintainability, preven"
  },
  {
    "path": ".eslintrc.json",
    "chars": 381,
    "preview": "{\n  \"extends\": [\n    \"next/core-web-vitals\",\n    \"plugin:storybook/recommended\"\n  ],\n  \"plugins\": [\n    \"no-conditional-"
  },
  {
    "path": ".github/workflows/chromatic.yml",
    "chars": 758,
    "preview": "# .github/workflows/chromatic.yml\n\n# Workflow name\nname: 'Chromatic'\n\n# Event for the workflow\non: push\n\n# List of jobs\n"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 1536,
    "preview": "name: Storybook PR Preview\n\non:\n  pull_request:\n    types: [opened, synchronize, reopened]\n    branches: [\"**\"]\n\npermiss"
  },
  {
    "path": ".github/workflows/rebase-main-sandbox.yml",
    "chars": 537,
    "preview": "name: Main to main-sandbox\non: \n  push:\n    branches: [main]\npermissions:\n  contents: write\njobs:\n  rebase-main-sandbox:"
  },
  {
    "path": ".gitignore",
    "chars": 558,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n*node_modules\n/.pn"
  },
  {
    "path": ".storybook/main.ts",
    "chars": 1472,
    "preview": "import { createRequire } from \"node:module\";\nimport type { StorybookConfig } from \"@storybook/nextjs\";\nimport path, { di"
  },
  {
    "path": ".storybook/manager.js",
    "chars": 139,
    "preview": "import { addons } from 'storybook/manager-api';\nimport { themes } from 'storybook/theming';\n\naddons.setConfig({\n    them"
  },
  {
    "path": ".storybook/preview.ts",
    "chars": 760,
    "preview": "import type { Preview } from \"@storybook/nextjs\";\nimport \"../styles/globals.css\";\nimport { themes } from 'storybook/them"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 863,
    "preview": "{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"Next.js: debug server-side\",\n      \"type\": \"node-term"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 68,
    "preview": "{\n    \"files.associations\": {\n        \"*.css\": \"tailwindcss\"\n    }\n}"
  },
  {
    "path": "AGENTS.md",
    "chars": 5343,
    "preview": "# AGENTS.md - Project Instructions for OpenAI Codex\n\nThis file provides instructions for OpenAI Codex users to leverage "
  },
  {
    "path": "CLAUDE.md",
    "chars": 5609,
    "preview": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## "
  },
  {
    "path": "Models/ApiError.ts",
    "chars": 992,
    "preview": "export type ApiError = {\n    code: LSAPIKnownErrorCode | string,\n    message: string;\n    metadata: {\n        AvailableT"
  },
  {
    "path": "Models/ApiResponse.ts",
    "chars": 238,
    "preview": "import { ApiError } from \"./ApiError\";\n\nexport class EmptyApiResponse {\n    constructor(error?: ApiError) {\n        this"
  },
  {
    "path": "Models/Balance.ts",
    "chars": 852,
    "preview": "import { Network, Token } from \"./Network\"\nimport { Wallet } from \"./WalletProvider\"\nimport { NodeErrorCategory } from \""
  },
  {
    "path": "Models/BalanceProvider.ts",
    "chars": 1673,
    "preview": "import posthog from \"posthog-js\";\nimport { TokenBalance } from \"./Balance\";\nimport { Network, NetworkWithTokens, Token }"
  },
  {
    "path": "Models/Exchange.ts",
    "chars": 407,
    "preview": "import { Network, Token } from \"./Network\";\n\nexport class Exchange {\n    display_name: string;\n    name: string;\n    log"
  },
  {
    "path": "Models/LayerSwapAppSettings.ts",
    "chars": 619,
    "preview": "import { NetworkWithTokens, NetworkRoute } from \"./Network\";\nimport { Exchange } from \"./Exchange\";\nimport { LayerSwapSe"
  },
  {
    "path": "Models/LayerSwapAuth.ts",
    "chars": 124,
    "preview": "export class AuthGetCodeResponse {\n    data: {\n        next: Date,\n        already_sent: boolean\n    };\n    error: strin"
  },
  {
    "path": "Models/LayerSwapSettings.ts",
    "chars": 280,
    "preview": "import { NetworkWithTokens, NetworkRoute } from \"./Network\";\nimport { Exchange } from \"./Exchange\";\n\nexport class LayerS"
  },
  {
    "path": "Models/Network.ts",
    "chars": 1575,
    "preview": "import { Refuel } from \"../lib/apiClients/layerSwapApiClient\";\n\nexport enum NetworkType {\n    EVM = \"evm\",\n    Starknet "
  },
  {
    "path": "Models/Partner.ts",
    "chars": 130,
    "preview": "export class Partner {\n    display_name: string;\n    logo: string;\n    is_wallet: boolean;\n    id: number;\n    client_id"
  },
  {
    "path": "Models/QueryParams.ts",
    "chars": 1374,
    "preview": "\nexport class PersistantQueryParams {\n    from?: string = \"\";\n    to?: string = \"\";\n    fromExchange?: string = \"\";\n    "
  },
  {
    "path": "Models/RangeError.ts",
    "chars": 172,
    "preview": "export enum SwapFailReasons {\n    RECEIVED_LESS_THAN_VALID_RANGE = \"received_less_than_valid_range\",\n    RECEIVED_MORE_T"
  },
  {
    "path": "Models/Route.ts",
    "chars": 771,
    "preview": "import { Exchange } from \"./Exchange\";\nimport { NetworkRouteToken, NetworkRoute } from \"./Network\";\n\nexport type Network"
  },
  {
    "path": "Models/SwapStatus.ts",
    "chars": 376,
    "preview": "export enum SwapStatus {\n    Created = 'created',\n    \n    UserTransferPending= 'user_transfer_pending',\n    UserTransfe"
  },
  {
    "path": "Models/Theme.ts",
    "chars": 8773,
    "preview": "import { HTMLAttributes } from \"react\"\n\nexport type ThemeData = {\n    buttonTextColor?: string,\n    logo?: string,\n    t"
  },
  {
    "path": "Models/WalletConnectWallet.ts",
    "chars": 530,
    "preview": "import { InternalConnector } from \"./WalletProvider\";\n\nexport type WalletConnectWallet = {\n    id: string;\n    name: str"
  },
  {
    "path": "Models/WalletProvider.ts",
    "chars": 2786,
    "preview": "import { WalletAccount } from 'starknet';\nimport { StarknetWindowObject } from 'starknetkit';\n\nexport type InternalConne"
  },
  {
    "path": "Models/Wizard.ts",
    "chars": 2033,
    "preview": "import { FC } from \"react\"\n\nexport type FormSteps = \"SwapForm\" | \"OffRampExchangeOAuth\" | \"ExchangeOAuth\" | \"ExchangeApi"
  },
  {
    "path": "README.md",
    "chars": 370,
    "preview": "\n<br />\n<div align=\"left\">\n  <h1 align=\"left\">UI for Layerswap web application</h1>\n</div>\n \nThis repository contains im"
  },
  {
    "path": "components/AddressIcon/colors.mjs",
    "chars": 296,
    "preview": "export default [\n    '#01888C', // teal\n    '#FC7500', // bright orange\n    '#034F5D', // dark teal\n    '#F73F01', // or"
  },
  {
    "path": "components/AddressIcon/index.tsx",
    "chars": 945,
    "preview": "'use client'\nimport Jazzicon from \"./jazzicon.mjs\";\nimport { FC, useEffect, useRef } from \"react\";\n\ntype Props = {\n    a"
  },
  {
    "path": "components/AddressIcon/jazzicon/colors.js",
    "chars": 298,
    "preview": "module.exports = [\n    '#01888C', // teal\n    '#FC7500', // bright orange\n    '#034F5D', // dark teal\n    '#F73F01', // "
  },
  {
    "path": "components/AddressIcon/jazzicon/index.js",
    "chars": 2336,
    "preview": "var MersenneTwister = require('./mersenne-twister');\nvar paperGen = require('./paper')\nvar Color = require('color')\nvar "
  },
  {
    "path": "components/AddressIcon/jazzicon/mersenne-twister.js",
    "chars": 8035,
    "preview": "\n/*\n  https://github.com/banksean wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace\n  so it's better e"
  },
  {
    "path": "components/AddressIcon/jazzicon/paper.js",
    "chars": 475,
    "preview": "function newPaper(diameter, color) {\n  var container = document.createElement('div')\n  container.style.borderRadius = '5"
  },
  {
    "path": "components/AddressIcon/jazzicon.mjs",
    "chars": 2339,
    "preview": "import MersenneTwister from './mersenne-twister.mjs';\nimport paperGen from './paper.mjs';\nimport Color from 'color';\nimp"
  },
  {
    "path": "components/AddressIcon/mersenne-twister.mjs",
    "chars": 5959,
    "preview": "/*\n  https://github.com/banksean wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace\n  so it's better en"
  },
  {
    "path": "components/AddressIcon/paper.mjs",
    "chars": 473,
    "preview": "function newPaper(diameter, color) {\n  var container = document.createElement('div')\n  container.style.borderRadius = '5"
  },
  {
    "path": "components/AvatarGroup.tsx",
    "chars": 681,
    "preview": "import { FC } from 'react'\nimport { ImageWithFallback } from './Common/ImageWithFallback';\ntype Props = {\n  imageUrls: s"
  },
  {
    "path": "components/Campaigns/Details/Leaderboard.tsx",
    "chars": 8882,
    "preview": "import { FC, useMemo, useState } from \"react\"\nimport LayerSwapApiClient, { Campaign, Leaderboard, Reward } from \"../../."
  },
  {
    "path": "components/Campaigns/Details/Rewards.tsx",
    "chars": 11437,
    "preview": "import { FC } from \"react\"\nimport BackgroundField from \"@/components/backgroundField\";\nimport { Clock } from \"lucide-rea"
  },
  {
    "path": "components/Campaigns/Details/index.tsx",
    "chars": 4735,
    "preview": "import { useRouter } from \"next/router\"\nimport { FC, useCallback } from \"react\"\nimport { Gift } from \"lucide-react\"\nimpo"
  },
  {
    "path": "components/Campaigns/index.tsx",
    "chars": 5326,
    "preview": "import { Gift } from \"lucide-react\";\nimport { FC } from \"react\";\nimport { ApiResponse } from \"../../Models/ApiResponse\";"
  },
  {
    "path": "components/Carousel.tsx",
    "chars": 2611,
    "preview": "import React, { forwardRef, useCallback, useImperativeHandle, useState } from \"react\";\nimport { useSwipeable } from \"rea"
  },
  {
    "path": "components/ColorSchema.tsx",
    "chars": 3282,
    "preview": "import { FC } from \"react\";\nimport { THEME_COLORS, ThemeData } from \"../Models/Theme\";\n\ntype Props = {\n    themeData?: T"
  },
  {
    "path": "components/Common/AnimatedValue.tsx",
    "chars": 876,
    "preview": "import { AnimatedNumber } from '@/lib/AnimatedNumber';\nimport { FC, useMemo } from 'react';\n\ntype AnimatedValueProps = {"
  },
  {
    "path": "components/Common/AverageCompletionTime.tsx",
    "chars": 784,
    "preview": "import { FC } from \"react\";\n\ntype AverageCompletionTimeProps = {\n    avgCompletionTime: string | undefined\n    className"
  },
  {
    "path": "components/Common/ConnectWalletButton.tsx",
    "chars": 3049,
    "preview": "import { RefreshCw } from \"lucide-react\";\nimport { ResolveConnectorIcon } from \"../icons/ConnectorIcons\";\nimport { FC, u"
  },
  {
    "path": "components/Common/CountDownTimer.tsx",
    "chars": 3088,
    "preview": "import { FC, useEffect, useState } from \"react\";\nimport { SwapStatus } from \"@/Models/SwapStatus\";\nimport { SwapDetails,"
  },
  {
    "path": "components/Common/FormattedAverageCompletionTime.tsx",
    "chars": 790,
    "preview": "import { FC } from \"react\";\n\ntype AverageCompletionTimeProps = {\n    avgCompletionTime: string | undefined\n}\n\nconst Form"
  },
  {
    "path": "components/Common/FormattedDate.tsx",
    "chars": 365,
    "preview": "const FormattedDate = ({ date }: { date: string }) => {\n    const swapDate = new Date(date);\n    const yyyy = swapDate.g"
  },
  {
    "path": "components/Common/ImageWithFallback.tsx",
    "chars": 809,
    "preview": "import Image, { ImageProps } from \"next/image\";\nimport React, { forwardRef, useCallback, useEffect, useState } from \"rea"
  },
  {
    "path": "components/Common/LinkWithIcon.tsx",
    "chars": 563,
    "preview": "import { ExternalLink } from 'lucide-react';\nimport Link from 'next/link';\nimport React, { FC } from 'react';\n\ninterface"
  },
  {
    "path": "components/Common/NumFlowWithFallback.tsx",
    "chars": 1291,
    "preview": "import { ComponentProps, FC, useMemo, useSyncExternalStore } from \"react\";\nimport NumberFlow from \"@number-flow/react\";\n"
  },
  {
    "path": "components/Common/ReactPortal.tsx",
    "chars": 809,
    "preview": "import { FC, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\n\ntype Props = {\n    w"
  },
  {
    "path": "components/Common/TypingEffect.tsx",
    "chars": 1653,
    "preview": "import { motion, useInView } from \"framer-motion\"\nimport { useEffect, useRef } from \"react\"\n\ntype TypingEffectProps = {\n"
  },
  {
    "path": "components/ConnectNetwork.tsx",
    "chars": 1361,
    "preview": "import SubmitButton from './buttons/submitButton';\nimport { Link } from 'lucide-react';\nimport { FC } from 'react';\n\ntyp"
  },
  {
    "path": "components/ContactSupport.tsx",
    "chars": 359,
    "preview": "import { FC } from \"react\"\nimport { useIntercom } from \"react-use-intercom\"\n\nconst ContactSupport: FC<{ children?: React"
  },
  {
    "path": "components/DTOs/SwapConfirmationFormValues.ts",
    "chars": 73,
    "preview": "export interface SwapConfirmationFormValues {\n    RightWallet: boolean;\n}"
  },
  {
    "path": "components/DTOs/SwapFormValues.ts",
    "chars": 611,
    "preview": "import { NetworkRoute, NetworkRouteToken } from \"@/Models/Network\";\nimport { Exchange } from \"@/Models/Exchange\";\n\nexpor"
  },
  {
    "path": "components/ErrorFallback.tsx",
    "chars": 4894,
    "preview": "import { useCallback, useEffect } from \"react\";\nimport { useIntercom } from \"react-use-intercom\";\nimport { Home, RotateC"
  },
  {
    "path": "components/FeeDetails/DepositMethod/index.tsx",
    "chars": 5885,
    "preview": "import { useFormikContext } from \"formik\";\nimport React, { FC, useEffect, useRef } from \"react\";\nimport { Network } from"
  },
  {
    "path": "components/FeeDetails/Rate.tsx",
    "chars": 1334,
    "preview": "import { useState } from \"react\"\nimport { ArrowRight } from \"lucide-react\"\nimport { truncateDecimals } from \"../utils/Ro"
  },
  {
    "path": "components/FeeDetails/ReceiveAmounts.tsx",
    "chars": 2530,
    "preview": "import { FC } from \"react\";\nimport { Token } from \"../../Models/Network\";\nimport { truncateDecimals } from \"../utils/Rou"
  },
  {
    "path": "components/FeeDetails/Refuel.tsx",
    "chars": 4080,
    "preview": "import ToggleButton from \"../buttons/toggleButton\"\nimport { useFormikContext } from \"formik\";\nimport { SwapFormValues } "
  },
  {
    "path": "components/FeeDetails/RefuelModal.tsx",
    "chars": 4705,
    "preview": "import { SwapFormValues } from '../DTOs/SwapFormValues';\nimport { Dispatch, FC, SetStateAction } from 'react';\nimport Mo"
  },
  {
    "path": "components/FeeDetails/Slippage.tsx",
    "chars": 11987,
    "preview": "import { SwapQuote } from \"@/lib/apiClients/layerSwapApiClient\"\nimport { SwapValues } from \".\"\nimport { Info, Pencil } f"
  },
  {
    "path": "components/FeeDetails/SwapQuote/DetailedEstimates.tsx",
    "chars": 9913,
    "preview": "import { FC, useMemo } from 'react'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../shadcn/tooltip'\nimpor"
  },
  {
    "path": "components/FeeDetails/SwapQuote/SummaryRow.tsx",
    "chars": 5690,
    "preview": "import { FC, useMemo } from 'react'\nimport { ChevronDown } from 'lucide-react'\nimport AddressIcon from '../../AddressIco"
  },
  {
    "path": "components/FeeDetails/SwapQuote/index.tsx",
    "chars": 3585,
    "preview": "import { FC, useState } from 'react'\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../.."
  },
  {
    "path": "components/FeeDetails/index.tsx",
    "chars": 7829,
    "preview": "import { SwapFormValues } from '../DTOs/SwapFormValues';\nimport ResizablePanel from '../ResizablePanel';\nimport { FC, us"
  },
  {
    "path": "components/HeaderWithMenu/index.tsx",
    "chars": 1891,
    "preview": "import IconButton from \"../buttons/iconButton\"\nimport GoHomeButton from \"../utils/GoHome\"\nimport { ArrowLeft } from 'luc"
  },
  {
    "path": "components/Input/Address/AddressPicker/AddressBook.tsx",
    "chars": 3835,
    "preview": "import { Command, CommandGroup, CommandItem, CommandList } from \"@/components/shadcn/command\";\nimport { Address } from \""
  },
  {
    "path": "components/Input/Address/AddressPicker/AddressButton.tsx",
    "chars": 819,
    "preview": "import { FC } from \"react\"\nimport { AddressItem } from \".\";\nimport { Partner } from \"@/Models/Partner\";\nimport { Network"
  },
  {
    "path": "components/Input/Address/AddressPicker/AddressWithIcon.tsx",
    "chars": 17357,
    "preview": "import { FC, MouseEventHandler, ReactNode, SVGProps, useCallback, useMemo, useState } from \"react\"\nimport { AddressGroup"
  },
  {
    "path": "components/Input/Address/AddressPicker/ConnectedWallets.tsx",
    "chars": 5765,
    "preview": "\nimport { ChevronDown, Plus, RefreshCw } from \"lucide-react\";\nimport { Network } from \"@/Models/Network\";\nimport { FC, u"
  },
  {
    "path": "components/Input/Address/AddressPicker/ManualAddressInput.tsx",
    "chars": 5411,
    "preview": "import { ChangeEvent, FC, useCallback, useState } from \"react\";\nimport { SwapFormValues } from \"@/components/DTOs/SwapFo"
  },
  {
    "path": "components/Input/Address/AddressPicker/index.tsx",
    "chars": 13230,
    "preview": "import { useFormikContext } from \"formik\";\nimport { FC, forwardRef, useCallback, useEffect, useMemo, useRef, useState } "
  },
  {
    "path": "components/Input/Address/ContractAddressNote.tsx",
    "chars": 2128,
    "preview": "import { FC, useState, useEffect } from \"react\"\nimport AddressIcon from \"@/components/AddressIcon\"\nimport { SwapFormValu"
  },
  {
    "path": "components/Input/Address/UrlAddressNote.tsx",
    "chars": 2971,
    "preview": "import { FC, useMemo } from \"react\"\nimport { ExternalLink } from \"lucide-react\"\nimport CopyButton from \"@/components/but"
  },
  {
    "path": "components/Input/Address/index.tsx",
    "chars": 742,
    "preview": "import { useState } from \"react\"\nimport { Partner } from \"@/Models/Partner\"\nimport AddressPicker, { AddressTriggerProps "
  },
  {
    "path": "components/Input/Amount/Balance.tsx",
    "chars": 4715,
    "preview": "import { SwapFormValues } from \"@/components/DTOs/SwapFormValues\";\nimport { truncateDecimals } from \"@/components/utils/"
  },
  {
    "path": "components/Input/Amount/ExchangeAmountField.tsx",
    "chars": 4449,
    "preview": "import { useFormikContext } from \"formik\";\nimport { forwardRef, useEffect, useMemo, useRef } from \"react\";\nimport { Swap"
  },
  {
    "path": "components/Input/Amount/ExchangeReceiveAmount.tsx",
    "chars": 1876,
    "preview": "import { FC } from \"react\";\nimport { Token } from \"@/Models/Network\";\nimport { Quote } from \"@/lib/apiClients/layerSwapA"
  },
  {
    "path": "components/Input/Amount/MinMax.tsx",
    "chars": 7561,
    "preview": "import { useFormikContext } from \"formik\";\nimport { SwapFormValues } from \"@/components/DTOs/SwapFormValues\";\nimport use"
  },
  {
    "path": "components/Input/Amount/PriceImpact.tsx",
    "chars": 5471,
    "preview": "import { FC, useMemo } from \"react\";\nimport { Triangle } from \"lucide-react\";\nimport { Tooltip, TooltipArrow, TooltipCon"
  },
  {
    "path": "components/Input/Amount/ReceiveAmount.tsx",
    "chars": 5370,
    "preview": "import { FC, useEffect, useMemo, useRef, useState } from \"react\";\nimport { Token } from \"@/Models/Network\";\nimport { Quo"
  },
  {
    "path": "components/Input/Amount/helpers.ts",
    "chars": 1185,
    "preview": "import { TokenBalance } from \"@/Models/Balance\"\nimport { Token } from \"@/Models/Network\"\n\n\ntype ResoleMaxAllowedAmountPr"
  },
  {
    "path": "components/Input/Amount/index.tsx",
    "chars": 8921,
    "preview": "import { useFormikContext } from \"formik\";\nimport { forwardRef, useEffect, useMemo, useRef } from \"react\";\nimport { Swap"
  },
  {
    "path": "components/Input/CexPicker.tsx",
    "chars": 8036,
    "preview": "import { useFormikContext } from \"formik\";\nimport { FC, useCallback, useEffect, useMemo, useState } from \"react\";\nimport"
  },
  {
    "path": "components/Input/DestinationPicker.tsx",
    "chars": 2942,
    "preview": "import { PlusIcon } from \"lucide-react\";\nimport RoutePicker from \"./RoutePicker\";\nimport Address from \"./Address\";\nimpor"
  },
  {
    "path": "components/Input/DestinationWalletPicker.tsx",
    "chars": 3325,
    "preview": "import { Address } from \"@/lib/address\";\nimport { ChevronDown, PlusIcon } from \"lucide-react\";\nimport { AddressGroup, Ad"
  },
  {
    "path": "components/Input/NumericInput.tsx",
    "chars": 4194,
    "preview": "import { useField, useFormikContext } from \"formik\";\nimport { ChangeEvent, FC, forwardRef } from \"react\";\nimport { SwapF"
  },
  {
    "path": "components/Input/RoutePicker/Content.tsx",
    "chars": 8107,
    "preview": "import { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { NetworkElement, RowElement } fro"
  },
  {
    "path": "components/Input/RoutePicker/RouteSearch.tsx",
    "chars": 1496,
    "preview": "import { FC, useMemo } from \"react\";\nimport { SearchComponent } from \"../Search\";\nimport { RowElement } from \"@/Models/R"
  },
  {
    "path": "components/Input/RoutePicker/RouteSortingMenu.tsx",
    "chars": 4880,
    "preview": "import { FC, useState } from \"react\";\nimport { useRouteSortingStore, SortingOption } from \"@/stores/routeSortingStore\";\n"
  },
  {
    "path": "components/Input/RoutePicker/RouteTokenSwitch.tsx",
    "chars": 2631,
    "preview": "import { FC } from \"react\";\nimport { motion } from \"framer-motion\";\nimport TokenIcon from \"@/components/icons/TokenIcon\""
  },
  {
    "path": "components/Input/RoutePicker/RouterPickerWalletConnect.tsx",
    "chars": 7072,
    "preview": "import { FC, useMemo, useState } from \"react\";\nimport { useConnectModal } from \"@/components/WalletModal\";\nimport { Sele"
  },
  {
    "path": "components/Input/RoutePicker/Routes.tsx",
    "chars": 17081,
    "preview": "import { NetworkRoute, NetworkRouteToken } from \"@/Models/Network\";\nimport { SwapDirection } from \"@/components/DTOs/Swa"
  },
  {
    "path": "components/Input/RoutePicker/Rows/CollapsableHeader.tsx",
    "chars": 924,
    "preview": "import { SwapDirection } from \"@/components/DTOs/SwapFormValues\";\nimport { GroupedTokenElement, NetworkElement } from \"@"
  },
  {
    "path": "components/Input/RoutePicker/Rows/CollapsibleRow.tsx",
    "chars": 5777,
    "preview": "import { RefObject, useMemo, useRef, useState, memo, useCallback } from \"react\";\nimport { AccordionContent, AccordionIte"
  },
  {
    "path": "components/Input/RoutePicker/Rows/StickyHeader.tsx",
    "chars": 2395,
    "preview": "import { useEffect } from \"react\";\nimport ReactPortal from \"@/components/Common/ReactPortal\";\nimport { CollapsableHeader"
  },
  {
    "path": "components/Input/RoutePicker/Rows/SuggestionsHeader.tsx",
    "chars": 786,
    "preview": "import { useBalanceStore } from \"@/stores/balanceStore\"\n\nconst SuggestionsHeader = () => {\n    const isLoading = useBala"
  },
  {
    "path": "components/Input/RoutePicker/Rows/TitleRow.tsx",
    "chars": 1092,
    "preview": "import { TitleElement } from \"@/Models/Route\";\nimport SuggestionsHeader from \"./SuggestionsHeader\";\nimport RouteTokenSwi"
  },
  {
    "path": "components/Input/RoutePicker/Rows/index.tsx",
    "chars": 4249,
    "preview": "import { RefObject } from \"react\";\nimport { RowElement } from \"@/Models/Route\";\nimport { SwapDirection } from \"@/compone"
  },
  {
    "path": "components/Input/RoutePicker/TokenTitleDetails.tsx",
    "chars": 7229,
    "preview": "import { NetworkRoute, NetworkRouteToken } from \"@/Models/Network\";\nimport { Info } from \"lucide-react\";\nimport { Extend"
  },
  {
    "path": "components/Input/RoutePicker/index.tsx",
    "chars": 5051,
    "preview": "import { useFormikContext } from \"formik\";\nimport { FC, useCallback, useEffect, useRef, useState } from \"react\";\nimport "
  },
  {
    "path": "components/Input/Search.tsx",
    "chars": 4598,
    "preview": "import useWindowDimensions from \"@/hooks/useWindowDimensions\";\nimport { DetailedHTMLProps, InputHTMLAttributes, useEffec"
  },
  {
    "path": "components/Input/SourcePicker.tsx",
    "chars": 3601,
    "preview": "import SourceWalletPicker from \"./SourceWalletPicker\";\nimport RoutePicker from \"./RoutePicker\";\nimport AmountField from "
  },
  {
    "path": "components/Input/SourceWalletPicker.tsx",
    "chars": 12854,
    "preview": "import { useFormikContext } from \"formik\";\nimport { SwapFormValues } from \"../DTOs/SwapFormValues\";\nimport { Dispatch, F"
  },
  {
    "path": "components/Input/TransferCEX.tsx",
    "chars": 3553,
    "preview": "import { FC } from \"react\";\nimport { SwapFormValues } from \"@/components/DTOs/SwapFormValues\";\nimport { useFormikContext"
  },
  {
    "path": "components/LayerswapMenu/Menu.tsx",
    "chars": 4661,
    "preview": "import { ChevronRight, ExternalLink } from \"lucide-react\"\nimport LinkWrapper from \"../LinkWraapper\"\nimport { ReactNode }"
  },
  {
    "path": "components/LayerswapMenu/MenuList.tsx",
    "chars": 6399,
    "preview": "import { BookOpen, Gift, Map, Home, ScrollText, LibraryIcon, Shield, Users, MessageSquarePlus } from \"lucide-react\";\nimp"
  },
  {
    "path": "components/LayerswapMenu/index.tsx",
    "chars": 4486,
    "preview": "import { MenuIcon, ChevronLeft } from \"lucide-react\";\nimport { FC } from \"react\";\nimport IconButton from \"../buttons/ico"
  },
  {
    "path": "components/LinkWraapper.tsx",
    "chars": 1002,
    "preview": "import Link, { LinkProps } from \"next/link\";\nimport { useRouter } from \"next/router\";\nimport { FC } from \"react\";\nimport"
  },
  {
    "path": "components/LoadingCard.tsx",
    "chars": 960,
    "preview": "import { FC } from \"react\"\n\ntype Props = {\n    name: string\n}\nconst LoadingCard: FC<Props> = ({ name }) => {\n    return "
  },
  {
    "path": "components/MessageComponent.tsx",
    "chars": 2605,
    "preview": "import CancelIcon from \"./icons/CancelIcon\";\nimport DelayIcon from \"./icons/DelayIcon\";\nimport FailIcon from \"./icons/Fa"
  },
  {
    "path": "components/NavigatableList/NavigatableItem.tsx",
    "chars": 5144,
    "preview": "import React, { forwardRef, ReactNode, useEffect, useContext, useCallback, memo, useRef } from 'react';\nimport { useNavi"
  },
  {
    "path": "components/NavigatableList/NavigatableList.tsx",
    "chars": 7195,
    "preview": "import React, { ReactNode, useMemo, useRef, useEffect, useState } from 'react';\nimport { useSyncExternalStore } from 're"
  },
  {
    "path": "components/NavigatableList/context.ts",
    "chars": 2515,
    "preview": "import React from 'react';\n\n// Structured index type - eliminates string parsing\nexport type FocusedIndex = \n    | { par"
  },
  {
    "path": "components/NavigatableList/hooks.ts",
    "chars": 2457,
    "preview": "import { useEffect, useRef, useCallback } from 'react';\nimport { useNavigatableListUpdate, FocusedIndex } from './contex"
  },
  {
    "path": "components/NavigatableList/index.tsx",
    "chars": 262,
    "preview": "export { default } from './NavigatableList';\nexport { default as NavigatableItem } from './NavigatableItem';\nexport * fr"
  },
  {
    "path": "components/NoCookies.tsx",
    "chars": 2718,
    "preview": "import { useEffect, useState } from \"react\";\nimport MessageComponent from \"./MessageComponent\";\nimport inIframe from \"./"
  },
  {
    "path": "components/ProgressBar.tsx",
    "chars": 872,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\"\nimport { clas"
  },
  {
    "path": "components/QRCodeWallet.tsx",
    "chars": 1934,
    "preview": "import { FC, useState } from \"react\"\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { classNames } from \"./utils/class"
  },
  {
    "path": "components/ReserveGasNote.tsx",
    "chars": 2237,
    "preview": "import { Tooltip, TooltipContent, TooltipTrigger } from \"@/components/shadcn/tooltip\";\nimport InfoIcon from \"@/component"
  },
  {
    "path": "components/ResizablePanel.tsx",
    "chars": 726,
    "preview": "import { useMeasure } from \"@uidotdev/usehooks\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { React"
  },
  {
    "path": "components/Sceletons.tsx",
    "chars": 13965,
    "preview": "import { ChevronRight, Clock } from \"lucide-react\"\nimport BackgroundField from \"./backgroundField\"\nimport { classNames }"
  },
  {
    "path": "components/Select/Command/CommandSelectWrapper.tsx",
    "chars": 4146,
    "preview": "import { useCallback, useState } from 'react'\nimport { ChevronDown } from 'lucide-react'\nimport { ISelectMenuItem, Selec"
  },
  {
    "path": "components/Select/Command/commandSelect.tsx",
    "chars": 5297,
    "preview": "import { ISelectMenuItem } from '../Shared/Props/selectMenuItem'\nimport {\n    CommandEmpty,\n    CommandGroup,\n    Comman"
  },
  {
    "path": "components/Select/Popover/PopoverSelect.tsx",
    "chars": 1110,
    "preview": "import { SelectProps } from '../Shared/Props/SelectProps'\nimport { CommandItem, CommandList, CommandWrapper } from '../."
  },
  {
    "path": "components/Select/Popover/PopoverSelectWrapper.tsx",
    "chars": 6851,
    "preview": "import { useCallback, useState } from 'react'\nimport { ChevronDown } from 'lucide-react'\nimport { ISelectMenuItem, Selec"
  },
  {
    "path": "components/Select/Selector/Index.tsx",
    "chars": 1142,
    "preview": "import { forwardRef, ReactNode } from \"react\";\nimport { Modal, ModalContent, ModalTrigger, useModalState } from \"@/compo"
  },
  {
    "path": "components/Select/Selector/SelectItem.tsx",
    "chars": 3017,
    "preview": "import { ImageWithFallback } from '@/components/Common/ImageWithFallback';\nimport clsx from 'clsx';\nimport { ReactNode }"
  },
  {
    "path": "components/Select/Shared/Props/SelectProps.tsx",
    "chars": 209,
    "preview": "import { ISelectMenuItem } from '../../Shared/Props/selectMenuItem'\n\nexport interface SelectProps {\n    values: ISelectM"
  },
  {
    "path": "components/Select/Shared/Props/selectMenuItem.tsx",
    "chars": 1482,
    "preview": "export class SelectMenuItem<T> implements ISelectMenuItem {\n    id: string;\n    name: string;\n    order: number;\n    img"
  },
  {
    "path": "components/Select/Shared/SelectItem.tsx",
    "chars": 1536,
    "preview": "import { ImageWithFallback } from \"@/components/Common/ImageWithFallback\";\nimport { ISelectMenuItem } from \"./Props/sele"
  }
]

// ... and 528 more files (download for full content)

About this extraction

This page contains the full source code of the layerswap/layerswapapp GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 728 files (2.7 MB), approximately 750.4k tokens, and a symbol index with 1561 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!