@lifi/widget
Version:
LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.
323 lines (282 loc) • 7.74 kB
text/typescript
import type {
BaseToken,
ChainType,
ContractCall,
Order,
RouteOptions,
SDKConfig,
StaticToken,
Token,
} from '@lifi/sdk'
import type {
Components,
PaletteMode,
PaletteOptions,
Shape,
SxProps,
Theme,
} from '@mui/material'
import type { TypographyOptions } from '@mui/material/styles/createTypography.js'
import type {
CSSProperties,
MutableRefObject,
ReactNode,
RefObject,
} from 'react'
import type {
CoinbaseWalletParameters,
MetaMaskParameters,
WalletConnectParameters,
} from 'wagmi/connectors'
import type {
LanguageKey,
LanguageResources,
} from '../providers/I18nProvider/types.js'
import type { DefaultFieldValues } from '../stores/form/types.js'
export type WidgetVariant = 'compact' | 'wide' | 'drawer'
export type WidgetSubvariant = 'default' | 'split' | 'custom' | 'refuel'
export type SplitSubvariant = 'bridge' | 'swap'
export type CustomSubvariant = 'checkout' | 'deposit'
export interface SubvariantOptions {
split?: SplitSubvariant
custom?: CustomSubvariant
}
export type Appearance = PaletteMode | 'auto'
export interface NavigationProps {
/**
* If given, uses a negative margin to counteract the padding on sides for navigation elements like icon buttons.
* @default true
*/
edge?: boolean
}
export type WidgetThemeComponents = Pick<
Components<Theme>,
| 'MuiAppBar'
| 'MuiAvatar'
| 'MuiButton'
| 'MuiCard'
| 'MuiIconButton'
| 'MuiInputCard'
| 'MuiTabs'
>
export type WidgetTheme = {
palette?: Pick<
PaletteOptions,
'background' | 'grey' | 'primary' | 'secondary' | 'text'
>
shape?: Partial<Shape>
typography?: TypographyOptions
components?: WidgetThemeComponents
container?: CSSProperties
header?: CSSProperties
playground?: CSSProperties
navigation?: NavigationProps
}
export enum DisabledUI {
FromAmount = 'fromAmount',
FromToken = 'fromToken',
ToAddress = 'toAddress',
ToToken = 'toToken',
}
export type DisabledUIType = `${DisabledUI}`
export enum HiddenUI {
Appearance = 'appearance',
DrawerCloseButton = 'drawerCloseButton',
History = 'history',
Language = 'language',
PoweredBy = 'poweredBy',
ToAddress = 'toAddress',
ToToken = 'toToken',
WalletMenu = 'walletMenu',
IntegratorStepDetails = 'integratorStepDetails',
ReverseTokensButton = 'reverseTokensButton',
RouteTokenDescription = 'routeTokenDescription',
}
export type HiddenUIType = `${HiddenUI}`
export enum RequiredUI {
ToAddress = 'toAddress',
}
export type RequiredUIType = `${RequiredUI}`
export interface WidgetWalletConfig {
onConnect?(): void
walletConnect?: WalletConnectParameters
coinbase?: CoinbaseWalletParameters
metaMask?: MetaMaskParameters
/**
* Determines whether the widget should provide partial wallet management functionality.
*
* In partial mode, external wallet management will be used for "opt-out" providers,
* while the internal management is applied for any remaining providers that do not opt out.
* This allows a flexible balance between the integrator’s custom wallet menu and the widget’s native wallet menu.
* @default false
*/
usePartialWalletManagement?: boolean
}
export interface WidgetSDKConfig
extends Omit<
SDKConfig,
| 'apiKey'
| 'disableVersionCheck'
| 'integrator'
| 'routeOptions'
| 'widgetVersion'
> {
routeOptions?: Omit<RouteOptions, 'bridges' | 'exchanges'>
}
export interface WidgetContractTool {
name: string
logoURI: string
}
export interface CalculateFeeParams {
fromChainId: number
toChainId: number
fromTokenAddress: string
toTokenAddress: string
fromAddress?: string
toAddress?: string
fromAmount?: bigint
toAmount?: bigint
slippage?: number
}
export interface WidgetFeeConfig {
name?: string
logoURI?: string
fee?: number
/**
* Function to calculate fees before fetching quotes.
* If provided, this function will be used instead of the `fee` parameter.
* Only one of `fee` or `calculateFee` should be used.
*
* @param params Object containing the fee calculation parameters
* @returns A promise that resolves to the calculated fee as a number (e.g., 0.03 represents a 3% fee)
*/
calculateFee?(params: CalculateFeeParams): Promise<number | undefined>
}
export interface ToAddress {
name?: string
address: string
chainType: ChainType
logoURI?: string
}
export interface AllowDeny<T> {
allow?: T[]
deny?: T[]
}
export type WidgetChains = {
from?: AllowDeny<number>
to?: AllowDeny<number>
types?: AllowDeny<ChainType>
} & AllowDeny<number>
export type WidgetTokens = {
featured?: StaticToken[]
include?: Token[]
popular?: StaticToken[]
} & AllowDeny<BaseToken>
export type WidgetLanguages = {
default?: LanguageKey
} & AllowDeny<LanguageKey>
export type PoweredByType = 'default' | 'jumper'
export interface RouteLabel {
text: string
sx?: SxProps<Theme>
}
export interface RouteLabelRule {
label: RouteLabel
// Matching criteria
bridges?: AllowDeny<string>
exchanges?: AllowDeny<string>
fromChainId?: number[]
toChainId?: number[]
fromTokenAddress?: string[]
toTokenAddress?: string[]
}
export interface WidgetConfig {
fromChain?: number
toChain?: number
fromToken?: string
toToken?: string
toAddress?: ToAddress
toAddresses?: ToAddress[]
fromAmount?: number | string
toAmount?: number | string
formUpdateKey?: string
contractCalls?: ContractCall[]
contractComponent?: ReactNode
contractSecondaryComponent?: ReactNode
contractCompactComponent?: ReactNode
contractTool?: WidgetContractTool
integrator: string
apiKey?: string
fee?: number
feeConfig?: WidgetFeeConfig
referrer?: string
routePriority?: Order
slippage?: number
variant?: WidgetVariant
subvariant?: WidgetSubvariant
subvariantOptions?: SubvariantOptions
appearance?: Appearance
theme?: WidgetTheme
disabledUI?: DisabledUIType[]
hiddenUI?: HiddenUIType[]
requiredUI?: RequiredUIType[]
useRecommendedRoute?: boolean
useRelayerRoutes?: boolean
walletConfig?: WidgetWalletConfig
sdkConfig?: WidgetSDKConfig
buildUrl?: boolean
keyPrefix?: string
bridges?: AllowDeny<string>
exchanges?: AllowDeny<string>
chains?: WidgetChains
tokens?: WidgetTokens
languages?: WidgetLanguages
languageResources?: LanguageResources
explorerUrls?: Record<number, string[]> &
Partial<Record<'internal', string[]>>
poweredBy?: PoweredByType
/**
* Custom labels/badges to show on routes based on specified rules
*/
routeLabels?: RouteLabelRule[]
}
export interface FormFieldOptions {
setUrlSearchParam: boolean
}
export interface FieldValues
extends Omit<DefaultFieldValues, 'fromAmount' | 'toAmount' | 'toAddress'> {
fromAmount?: number | string
toAmount?: number | string
toAddress?: ToAddress | string
}
export type FieldNames = keyof FieldValues
export type SetFieldValueFunction = <K extends FieldNames>(
key: K,
value: FieldValues[K],
options?: FormFieldOptions
) => void
export type FormState = {
setFieldValue: SetFieldValueFunction
}
export type FormRef = MutableRefObject<FormState | null>
export interface FormRefProps {
formRef?: FormRef
}
export interface WidgetConfigProps extends FormRefProps {
config: WidgetConfig
}
export interface WidgetConfigPartialProps {
config?: Partial<WidgetConfig>
}
export type WidgetProps = WidgetDrawerProps &
WidgetConfig &
WidgetConfigPartialProps &
FormRefProps
export interface WidgetDrawerProps extends WidgetConfigPartialProps {
elementRef?: RefObject<HTMLDivElement>
open?: boolean
/**
* Make sure to make the onClose callback stable (e.g. using useCallback) to avoid causing re-renders of the entire widget
*/
onClose?(): void
}