Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 14 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pnpm dev # Start widget-playground-vite on port 3000
pnpm dev:next # Start Next.js playground

# Building
pnpm build # Build all packages (libs first, then playgrounds/embedded)
pnpm build # Build all packages in parallel

# Code Quality
pnpm check # Biome lint + format check
Expand All @@ -33,6 +33,18 @@ pnpm --filter @lifi/widget-light test # Run widget-light tests
pnpm knip:check
```

## Build Tooling

- **tsdown** (powered by rolldown) builds all library packages. Config in each package's `tsdown.config.ts`.
- **Vite** builds app packages (`widget-embedded`, `widget-playground-vite`). These are NOT built with tsdown.
- **`isolatedDeclarations: true`** is enabled in root `tsconfig.json`. All exported declarations in library packages must have explicit type annotations:
- Exported functions must have explicit return types (`: JSX.Element`, `: void`, etc.)
- Exported `createContext<T>()` results need `Context<T>` annotation
- Exported `styled(Component)(...)` results need `React.FC<Props>` annotation
- Use proper `import type { Foo } from '...'` — never inline `import('...').Foo` in type positions
- App packages (`widget-embedded`, `widget-playground-vite`, `examples/`) override with `isolatedDeclarations: false` in their tsconfig.
- If `check:types` shows phantom errors after tsconfig changes, delete `.tsbuildinfo` files and retry.

## Architecture

### Package Dependency Graph
Expand Down Expand Up @@ -94,6 +106,7 @@ QueryClient → Settings → WidgetConfig → I18n → Theme → SDK → Wallet
- **widget-light must have zero `dependencies`** — all types are self-contained duplicates. Chain-specific integrations are optional peer deps exposed via subpath exports (`@lifi/widget-light/ethereum`, etc.).
- Package entry points use TypeScript source (`src/index.ts`). The `scripts/formatPackageJson.js` rewrites paths to `dist/esm/` at publish time.
- TypeScript target is ES2020, module resolution is Bundler.
- Library packages use `tsdown` with `unbundle: true` mode. The widget package needs `neverBundle: [/\.json$/]` for i18n JSON files.
- **PR template** at `.github/pull_request_template.md` — always use it when creating PRs via `gh pr create`.
- `packages/widget-embedded/README.md` — main integration guide for widget-light (not a typical package readme).

Expand Down
2 changes: 1 addition & 1 deletion examples/deposit-flow/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"devDependencies": {
"@types/events": "^3.0.3",
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"react-dom": "^19.2.4"
},
"devDependencies": {
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"typescript": "^5.9.3"
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs14-page-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"react-dom": "^19.2.4"
},
"devDependencies": {
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"eslint": "^8",
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs14/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"react-dom": "^19.2.4"
},
"devDependencies": {
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"eslint": "^8",
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs15/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"react-dom": "^19.2.4"
},
"devDependencies": {
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"typescript": "^5.9.3"
Expand Down
3 changes: 2 additions & 1 deletion examples/nft-checkout/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LiFiWidget } from '@lifi/widget'
import { Box, CssBaseline } from '@mui/material'
import type { JSX } from 'react'
import type { NFTNetwork } from './components/NFTOpenSea/index.js'
import {
NFTOpenSea,
Expand All @@ -9,7 +10,7 @@ import {
import { widgetConfig } from './config.js'
import './index.css'

export const App = () => {
export const App = (): JSX.Element => {
const pathnameParams = window.location.pathname.substring(1).split('/')

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import { Seaport } from '@opensea/seaport-js'
import { useQuery } from '@tanstack/react-query'
import { type Connector, useConfig } from 'wagmi'
import { getEthersSigner } from './getEthersSigner.js'
import type { FulfillmentDataResponse, NFTNetwork } from './types.js'
import type { FulfillmentDataResponse, NFTNetwork, OrderV2 } from './types.js'
import { ChainId as OpenSeaChainId } from './types.js'
import { useOpenSeaOrder } from './useOpenSeaOrder.js'

export const useOpenSeaFulfillment = (
network: NFTNetwork,
contractAddress: string,
tokenId: string | number
) => {
): {
data: NFTProps | undefined
isLoading: boolean
order: OrderV2 | undefined
} => {
const { account } = useAccount()
const config = useConfig()
const [recipientAddress] = useFieldValues('toAddress')
Expand Down Expand Up @@ -139,8 +143,8 @@ export const useOpenSeaFulfillment = (
})

return {
data,
data: data,
isLoading: isLoading || isOrderLoading,
order,
order: order,
}
}
2 changes: 1 addition & 1 deletion examples/nft-checkout/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if (!rootElement) {
throw new Error('Failed to find the root element.')
}

export const queryClient = new QueryClient({
export const queryClient: QueryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: true,
Expand Down
3 changes: 2 additions & 1 deletion examples/nft-checkout/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
"outDir": "dist",
"rootDir": "./src",
"composite": true
"composite": true,
"isolatedDeclarations": false
},
"include": ["src"]
}
2 changes: 1 addition & 1 deletion examples/react-router-7/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@lifi/widget": "^3.40.12",
"@react-router/node": "^7.13.2",
"@react-router/serve": "^7.13.2",
"isbot": "^5.1.36",
"isbot": "^5.1.37",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-router": "^7.13.2",
Expand Down
2 changes: 1 addition & 1 deletion examples/remix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@remix-run/node": "^2.17.2",
"@remix-run/react": "^2.17.2",
"@remix-run/serve": "^2.17.2",
"isbot": "^5.1.36",
"isbot": "^5.1.37",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"remix-utils": "^9.3.1"
Expand Down
4 changes: 2 additions & 2 deletions examples/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@tsconfig/svelte": "^5.0.7",
"@types/events": "^3.0.3",
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"svelte": "^5.55.1",
"svelte-check": "^4.4.5",
"svelte-check": "^4.4.6",
"svelte-preprocess": "^6.0.3",
"tslib": "^2.8.1",
"typescript": "^5.9.3",
Expand Down
2 changes: 1 addition & 1 deletion examples/tanstack-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"react-dom": "^19.2.4"
},
"devDependencies": {
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/vite-iframe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"wagmi": "^3.6.0"
},
"devDependencies": {
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"devDependencies": {
"@types/events": "^3.0.3",
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"sideEffects": false,
"type": "module",
"scripts": {
"build": "pnpm -r --parallel --filter './packages/**' --filter !'*-playground-*' --filter !'*-embedded' build && pnpm -r --parallel --filter './packages/**' --filter '*-playground-*' --filter '*-embedded' build",
"build": "pnpm -r --parallel --filter './packages/**' --filter !'*-next' build",
"build:next": "pnpm --filter widget-playground-next build",
"clean": "pnpm -r --parallel --filter './packages/**' clean",
"clean:cache": "pnpm store prune",
"clean:modules": "find . -name \"node_modules\" -type d -prune -exec rm -rf {} +",
Expand Down Expand Up @@ -57,7 +58,7 @@
"@biomejs/biome": "^2.4.9",
"@commitlint/cli": "^20.5.0",
"@commitlint/config-conventional": "^20.5.0",
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"fs-extra": "^11.3.3",
Expand All @@ -66,6 +67,7 @@
"lerna": "^9.0.7",
"lint-staged": "^16.4.0",
"standard-version": "^9.5.0",
"tsdown": "^0.21.7",
"typescript": "^5.9.3"
},
"optionalDependencies": {
Expand Down
8 changes: 3 additions & 5 deletions packages/wallet-management/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
"types": "./src/index.d.ts",
"sideEffects": false,
"scripts": {
"watch": "tsc -w -p ./tsconfig.json",
"build": "pnpm clean && pnpm build:esm && pnpm build:clean",
"build:esm": "tsc --build",
"watch": "tsdown --watch",
"build": "pnpm clean && tsdown",
"build:prerelease": "node ../../scripts/prerelease.js && cpy '../../README.md' .",
"build:postrelease": "node ../../scripts/postrelease.js && rm -rf README.md",
"build:clean": "rm -rf tsconfig.tsbuildinfo ./dist/tsconfig.tsbuildinfo",
"release:build": "pnpm build",
"clean": "pnpm build:clean && rm -rf dist",
"clean": "rm -rf dist",
"check:types": "tsc --noEmit",
"check:circular-deps": "madge --circular $(find ./src -name '*.ts' -o -name '*.tsx')",
"check:circular-deps-graph": "madge --circular $(find ./src -name '*.ts' -o -name '*.tsx') --image graph.svg"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChainId, ChainType } from '@lifi/sdk'
import { isWalletInstalled, useBitcoinContext } from '@lifi/widget-provider'
import type { JSX } from 'react'
import { useLastConnectedAccount } from '../hooks/useAccount.js'
import { useWalletManagementEvents } from '../hooks/useWalletManagementEvents.js'
import { getChainTypeIcon } from '../icons.js'
Expand All @@ -17,7 +18,7 @@ export const BitcoinListItemButton = ({
onConnected,
onConnecting,
onError,
}: WalletListItemButtonProps) => {
}: WalletListItemButtonProps): JSX.Element => {
const emitter = useWalletManagementEvents()
const { connect, disconnect, isConnected } = useBitcoinContext()
const { setLastConnectedAccount } = useLastConnectedAccount()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { WalletTag } from './WalletTag.js'
interface CardListItemButtonProps {
onClick: () => void
title: string
icon: string
icon?: string
tagType?: WalletTagType
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChainType } from '@lifi/sdk'
import { isWalletInstalled, useEthereumContext } from '@lifi/widget-provider'
import type { JSX } from 'react'
import { useLastConnectedAccount } from '../hooks/useAccount.js'
import { useWalletManagementEvents } from '../hooks/useWalletManagementEvents.js'
import { getChainTypeIcon } from '../icons.js'
Expand All @@ -18,7 +19,7 @@ export const EthereumListItemButton = ({
onConnected,
onConnecting,
onError,
}: WalletListItemButtonProps) => {
}: WalletListItemButtonProps): JSX.Element => {
const emitter = useWalletManagementEvents()
const { connect, disconnect, isConnected } = useEthereumContext()
const { setLastConnectedAccount } = useLastConnectedAccount()
Expand Down
6 changes: 5 additions & 1 deletion packages/wallet-management/src/components/ListItemText.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import type { StyledComponent } from '@emotion/styled'
import {
type ListItemTextProps,
listItemTextClasses,
ListItemText as MuiListItemText,
styled,
} from '@mui/material'

export const ListItemText = styled(MuiListItemText)(() => ({
export const ListItemText: StyledComponent<ListItemTextProps> = styled(
MuiListItemText
)(() => ({
[`.${listItemTextClasses.primary}`]: {
fontWeight: 600,
fontSize: 16,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChainId, ChainType } from '@lifi/sdk'
import { useSolanaContext } from '@lifi/widget-provider'
import type { JSX } from 'react'
import { useLastConnectedAccount } from '../hooks/useAccount.js'
import { useWalletManagementEvents } from '../hooks/useWalletManagementEvents.js'
import { getChainTypeIcon } from '../icons.js'
Expand All @@ -15,7 +16,7 @@ export const SolanaListItemButton = ({
onConnected,
onConnecting,
onError,
}: WalletListItemButtonProps) => {
}: WalletListItemButtonProps): JSX.Element => {
const emitter = useWalletManagementEvents()
const { connect, disconnect, isConnected } = useSolanaContext()
const { setLastConnectedAccount } = useLastConnectedAccount()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChainId, ChainType } from '@lifi/sdk'
import { useSuiContext } from '@lifi/widget-provider'
import type { JSX } from 'react'
import { useLastConnectedAccount } from '../hooks/useAccount.js'
import { useWalletManagementEvents } from '../hooks/useWalletManagementEvents.js'
import { getChainTypeIcon } from '../icons.js'
Expand All @@ -15,7 +16,7 @@ export const SuiListItemButton = ({
onConnected,
onConnecting,
onError,
}: WalletListItemButtonProps) => {
}: WalletListItemButtonProps): JSX.Element => {
const emitter = useWalletManagementEvents()
const { connect, disconnect, isConnected } = useSuiContext()
const { setLastConnectedAccount } = useLastConnectedAccount()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Avatar, Box, Typography } from '@mui/material'
import type { JSX } from 'react'
import type { CombinedWallet } from '../hooks/useCombinedWallets.js'

interface WalletInfoDisplayProps {
Expand All @@ -11,7 +12,7 @@ export const WalletInfoDisplay = ({
selectedWallet,
title,
message,
}: WalletInfoDisplayProps) => {
}: WalletInfoDisplayProps): JSX.Element => {
return (
<Box
sx={{
Expand Down
6 changes: 5 additions & 1 deletion packages/wallet-management/src/components/WalletTag.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import type { StyledComponent } from '@emotion/styled'
import type { ChipProps } from '@mui/material'
import { Chip as MuiChip, styled } from '@mui/material'
import { WalletTagType } from '../types/walletTagType.js'

interface WalletTagProps {
type: WalletTagType
}

export const WalletTag = styled(MuiChip)<WalletTagProps>(({ theme }) => {
export const WalletTag: StyledComponent<ChipProps & WalletTagProps> = styled(
MuiChip
)<WalletTagProps>(({ theme }) => {
return {
height: 24,
px: theme.spacing(1),
Expand Down
Loading