@lifi/widget 4.7.1 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/AmountInput/AmountInput.style.d.ts.map +1 -1
- package/dist/esm/components/Card/Card.d.ts.map +1 -1
- package/dist/esm/components/Card/CardIconButton.d.ts.map +1 -1
- package/dist/esm/components/ContractComponent/ItemPrice.d.ts.map +1 -1
- package/dist/esm/components/ListItem/ListItemButton.d.ts.map +1 -1
- package/dist/esm/components/ListItemButton.d.ts.map +1 -1
- package/dist/esm/components/Token/Token.d.ts.map +1 -1
- package/dist/esm/components/TokenList/types.d.ts.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
- package/dist/esm/hooks/useAvailableChains.js +21 -38
- package/dist/esm/hooks/useAvailableChains.js.map +1 -1
- package/dist/esm/hooks/useFromTokenSufficiency.js +3 -3
- package/dist/esm/hooks/useFromTokenSufficiency.js.map +1 -1
- package/dist/esm/hooks/useGasRecommendation.js +3 -3
- package/dist/esm/hooks/useGasRecommendation.js.map +1 -1
- package/dist/esm/hooks/useGasSufficiency.js +3 -3
- package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
- package/dist/esm/hooks/useIsBatchingSupported.js +2 -2
- package/dist/esm/hooks/useIsBatchingSupported.js.map +1 -1
- package/dist/esm/hooks/useRouteExecution.js +6 -6
- package/dist/esm/hooks/useRouteExecution.js.map +1 -1
- package/dist/esm/hooks/useRoutes.js +7 -7
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useTokenBalance.js +4 -4
- package/dist/esm/hooks/useTokenBalance.js.map +1 -1
- package/dist/esm/hooks/useTokenBalancesQueries.js +3 -3
- package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
- package/dist/esm/hooks/useTokenSearch.js +3 -3
- package/dist/esm/hooks/useTokenSearch.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +14 -14
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/hooks/useTools.d.ts.map +1 -1
- package/dist/esm/hooks/useTools.js +26 -27
- package/dist/esm/hooks/useTools.js.map +1 -1
- package/dist/esm/hooks/useTransactionDetails.js +2 -2
- package/dist/esm/hooks/useTransactionDetails.js.map +1 -1
- package/dist/esm/hooks/useTransactionHistory.js +3 -3
- package/dist/esm/hooks/useTransactionHistory.js.map +1 -1
- package/dist/esm/index.d.ts +5 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/pages/RoutesPage/RoutesPage.style.d.ts.map +1 -1
- package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js +9 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/types.d.ts +2 -0
- package/dist/esm/providers/WidgetProvider/types.d.ts.map +1 -1
- package/dist/esm/queries/getChains.d.ts +38 -0
- package/dist/esm/queries/getChains.d.ts.map +1 -0
- package/dist/esm/queries/getChains.js +51 -0
- package/dist/esm/queries/getChains.js.map +1 -0
- package/dist/esm/queries/getTools.d.ts +26 -0
- package/dist/esm/queries/getTools.d.ts.map +1 -0
- package/dist/esm/queries/getTools.js +30 -0
- package/dist/esm/queries/getTools.js.map +1 -0
- package/dist/esm/queries/index.d.ts +4 -0
- package/dist/esm/queries/index.js +3 -0
- package/dist/esm/queries/types.d.ts +25 -0
- package/dist/esm/queries/types.d.ts.map +1 -0
- package/dist/esm/shared.d.ts +2 -1
- package/dist/esm/shared.js +2 -1
- package/dist/esm/stores/StoreProvider.d.ts.map +1 -1
- package/dist/esm/stores/StoreProvider.js +16 -17
- package/dist/esm/stores/StoreProvider.js.map +1 -1
- package/dist/esm/stores/header/useHeaderStore.d.ts +1 -1
- package/dist/esm/stores/header/useHeaderStore.d.ts.map +1 -1
- package/dist/esm/stores/header/useHeaderStore.js.map +1 -1
- package/dist/esm/themes/createTheme.d.ts.map +1 -1
- package/dist/esm/types/events.d.ts.map +1 -1
- package/dist/esm/types/token.d.ts.map +1 -1
- package/dist/esm/types/widget.d.ts +30 -0
- package/dist/esm/types/widget.d.ts.map +1 -1
- package/dist/esm/types/widget.js.map +1 -1
- package/dist/esm/utils/queries.js.map +1 -1
- package/dist/esm/utils/scopeKeys.d.ts +6 -0
- package/dist/esm/utils/scopeKeys.d.ts.map +1 -0
- package/dist/esm/utils/scopeKeys.js +8 -0
- package/dist/esm/utils/scopeKeys.js.map +1 -0
- package/package.json +12 -4
- package/src/config/version.ts +1 -1
- package/src/hooks/useAvailableChains.test.tsx +170 -0
- package/src/hooks/useAvailableChains.ts +29 -47
- package/src/hooks/useFromTokenSufficiency.ts +2 -2
- package/src/hooks/useGasRecommendation.ts +2 -2
- package/src/hooks/useGasSufficiency.ts +2 -2
- package/src/hooks/useIsBatchingSupported.ts +2 -2
- package/src/hooks/useRouteExecution.ts +5 -5
- package/src/hooks/useRoutes.ts +6 -6
- package/src/hooks/useTokenBalance.ts +4 -4
- package/src/hooks/useTokenBalancesQueries.ts +3 -3
- package/src/hooks/useTokenSearch.ts +7 -3
- package/src/hooks/useTokens.ts +13 -14
- package/src/hooks/useTools.sharedEntry.test.tsx +155 -0
- package/src/hooks/useTools.ts +42 -37
- package/src/hooks/useTransactionDetails.ts +3 -3
- package/src/hooks/useTransactionHistory.ts +2 -2
- package/src/index.ts +2 -1
- package/src/providers/WidgetProvider/WidgetProvider.test.tsx +73 -0
- package/src/providers/WidgetProvider/WidgetProvider.tsx +13 -0
- package/src/providers/WidgetProvider/types.ts +2 -0
- package/src/queries/getChains.ts +93 -0
- package/src/queries/getTools.ts +62 -0
- package/src/queries/index.ts +30 -0
- package/src/queries/sharedCache.test.tsx +223 -0
- package/src/queries/types.ts +38 -0
- package/src/shared.ts +1 -0
- package/src/stores/StoreProvider.test.tsx +107 -0
- package/src/stores/StoreProvider.tsx +8 -6
- package/src/stores/header/useHeaderStore.tsx +3 -4
- package/src/types/widget.ts +30 -0
- package/src/utils/queries.ts +1 -0
- package/src/utils/scopeKeys.ts +18 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget.d.ts","names":[],"sources":["../../../src/types/widget.ts"],"mappings":";;;;;;;;;YAoCY;;YAGA;YACA,yDAKR;YACQ;YACA;EACV,YAAY;;YAEF;iBACK;;;;;;EAMf,QAAQ,YAAY;EACpB;IAAW,MAAM;;;;;;;YAOP,wBAAwB;;YAExB;YAOA,mBAAmB,2BAA2B;YAE9C,aAAa;iBACR;;;;;EAKf;;YAEU,wBAAwB,QAClC,KACE,WAAW;YAeH;EACV;IACE;MACE,SAAS;;IAEX;MACE,SAAS;;;EAGb,QAAQ,QAAQ;EAChB,aAAa;EACb,aAAa;EACb,YAAY;EACZ,kBAAkB;EAClB,wBAAwB;EACxB,SAAS;EACT,aAAa;;iBAGE;EACf;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EACA;EACA;;;;;EAKA;EACA;;;;;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;EAMA;EACA;;;;;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;;YAGU;EACV;EACA;;;;;;;;;EASA;;iBAGe;EACf,wBAAwB,eAAe;EACvC,WAAW,OAAO;;;;;;;;;EASlB;;;;;EAKA;;iBAGe,wBACP,KACN;EAQF,eAAe,KACb;EAGF,mBAAmB,KAAK;;iBAGT;EACf;EACA;;iBAGe;EACf,WAAW;EACX,SAAS;EACT,WAAW;EACX,SAAS;EACT;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;;;;;EAKA;;;;;EAKA;;;;EAIA,sBAAsB;;;;;;;;;EAStB,cAAc,QAAQ,qBAAqB;;iBAG5B;EACf;EACA;EACA,WAAW;EACX;;iBAGe,UAAU;EACzB,QAAQ;EACR,OAAO;;YAGG;iBACK;EACf,QAAQ,IAAI;EACZ,OAAO,IAAI;;YAGD;EACV,OAAO;EACP,KAAK;IACH;YAEQ,eAAe;EACzB,OAAO,UAAU;EACjB,KAAK,UAAU;IACb,UAAU;YAEF;EACV,QAAQ,UAAU;IAChB;YAEQ;EACV,WAAW;EACX,UAAU;EACV,UAAU;EACV,WAAW;IACT,eAAe;YAEP;EACV,UAAU;IACR,UAAU;YAEF;iBAEK;EACf;EACA,KAAK,QAAQ;;iBAGE;EACf,OAAO;EAEP,UAAU;EACV,YAAY;EACZ;EACA;EACA;EACA;;;;;;;;EAQA,SAAS,OAAO;;YAGN;EAGN;EACA;EACA;;YAGM,kBACV,OAAO,kBAAkB,yBACtB;iBAEY;EACf;EACA;EACA;EACA;EACA,YAAY;EACZ,cAAc;EACd;EACA;EACA;EACA;EAEA,YAAY;EAEZ,gBAAgB;EAChB,oBAAoB;EACpB,6BAA6B;EAC7B,2BAA2B;EAC3B,eAAe;EACf;EACA;EACA,YAAY;EACZ;EAEA,gBAAgB;EAChB;EAEA,UAAU;EACV,OAAO;EACP,cAAc;;;;;;;EAOd,kBAAkB;EAElB,aAAa;EACb,QAAQ;EAER,aAAa;EACb,WAAW;EACX,aAAa;EACb,YAAY;;;;;;;EAOZ;EACA;EAEA,eAAe;EACf,YAAY;EAEZ;
|
|
1
|
+
{"version":3,"file":"widget.d.ts","names":[],"sources":["../../../src/types/widget.ts"],"mappings":";;;;;;;;;YAoCY;;YAGA;YACA,yDAKR;YACQ;YACA;EACV,YAAY;;YAEF;iBACK;;;;;;EAMf,QAAQ,YAAY;EACpB;IAAW,MAAM;;;;;;;YAOP,wBAAwB;;YAExB;YAOA,mBAAmB,2BAA2B;YAE9C,aAAa;iBACR;;;;;EAKf;;YAEU,wBAAwB,QAClC,KACE,WAAW;YAeH;EACV;IACE;MACE,SAAS;;IAEX;MACE,SAAS;;;EAGb,QAAQ,QAAQ;EAChB,aAAa;EACb,aAAa;EACb,YAAY;EACZ,kBAAkB;EAClB,wBAAwB;EACxB,SAAS;EACT,aAAa;;iBAGE;EACf;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EACA;EACA;;;;;EAKA;EACA;;;;;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;EAMA;EACA;;;;;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;;YAGU;EACV;EACA;;;;;;;;;EASA;;iBAGe;EACf,wBAAwB,eAAe;EACvC,WAAW,OAAO;;;;;;;;;EASlB;;;;;EAKA;;iBAGe,wBACP,KACN;EAQF,eAAe,KACb;EAGF,mBAAmB,KAAK;;iBAGT;EACf;EACA;;iBAGe;EACf,WAAW;EACX,SAAS;EACT,WAAW;EACX,SAAS;EACT;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;;;;;EAKA;;;;;EAKA;;;;EAIA,sBAAsB;;;;;;;;;EAStB,cAAc,QAAQ,qBAAqB;;iBAG5B;EACf;EACA;EACA,WAAW;EACX;;iBAGe,UAAU;EACzB,QAAQ;EACR,OAAO;;YAGG;iBACK;EACf,QAAQ,IAAI;EACZ,OAAO,IAAI;;YAGD;EACV,OAAO;EACP,KAAK;IACH;YAEQ,eAAe;EACzB,OAAO,UAAU;EACjB,KAAK,UAAU;IACb,UAAU;YAEF;EACV,QAAQ,UAAU;IAChB;YAEQ;EACV,WAAW;EACX,UAAU;EACV,UAAU;EACV,WAAW;IACT,eAAe;YAEP;EACV,UAAU;IACR,UAAU;YAEF;iBAEK;EACf;EACA,KAAK,QAAQ;;iBAGE;EACf,OAAO;EAEP,UAAU;EACV,YAAY;EACZ;EACA;EACA;EACA;;;;;;;;EAQA,SAAS,OAAO;;YAGN;EAGN;EACA;EACA;;YAGM,kBACV,OAAO,kBAAkB,yBACtB;iBAEY;EACf;EACA;EACA;EACA;EACA,YAAY;EACZ,cAAc;EACd;EACA;EACA;EACA;EAEA,YAAY;EAEZ,gBAAgB;EAChB,oBAAoB;EACpB,6BAA6B;EAC7B,2BAA2B;EAC3B,eAAe;EACf;EACA;EACA,YAAY;EACZ;EAEA,gBAAgB;EAChB;EAEA,UAAU;EACV,OAAO;EACP,cAAc;;;;;;;EAOd,kBAAkB;EAElB,aAAa;EACb,QAAQ;EAER,aAAa;EACb,WAAW;EACX,aAAa;EACb,YAAY;;;;;;;EAOZ;EACA;EAEA,eAAe;EACf,YAAY;EAEZ;;;;;EAKA;;;;;;;;;;;;EAYA;;;;;;;;;;;;;;EAcA;EAEA,UAAU;EACV,YAAY;EACZ,SAAS;EACT,SAAS;EACT,YAAY;EACZ,oBAAoB;EACpB,eAAe,eAAe,iBAC5B,QAAQ,mBAAmB;EAC7B,YAAY;;;;EAKZ,cAAc;;iBAGC;EACf;;iBAGe,oBACP,KAAK;EACb;EACA;EACA,YAAY;;YAGF,mBAAmB;YAEnB,yBAAyB,UAAU,YAC7C,KAAK,GACL,OAAO,YAAY,IACnB,UAAU;YAGA;EACV,eAAe;;YAGL,UAAU,UAAU;iBAEf;EACf,UAAU;;iBAGK,0BAA0B;EACzC,QAAQ;;iBAGO;EACf,SAAS,QAAQ;;YAGP,cAAc,oBACxB,eACA,2BACA;iBAEe,0BAA0B;EACzC,aAAa,UAAU;EACvB;;;;EAIA;;oBAGU;EACV;EACA;EACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget.js","names":[],"sources":["../../../src/types/widget.ts"],"sourcesContent":["import type {\n BaseToken,\n ChainType,\n ContractCall,\n ExecutionOptions,\n ExtendedChain,\n Order,\n Route,\n RouteOptions,\n SDKConfig,\n StaticToken,\n Token,\n} from '@lifi/sdk'\nimport type { WalletMenuOpenArgs } from '@lifi/wallet-management'\nimport type { WidgetProviderProps } from '@lifi/widget-provider'\nimport type {\n Components,\n PaletteMode,\n PaletteOptions,\n Shape,\n SxProps,\n Theme,\n} from '@mui/material'\nimport type { TypographyVariantsOptions } from '@mui/material/styles'\nimport type {\n CSSProperties,\n PropsWithChildren,\n ReactNode,\n RefObject,\n} from 'react'\nimport type {\n LanguageKey,\n LanguageResources,\n} from '../providers/I18nProvider/types.js'\nimport type { DefaultFieldValues } from '../stores/form/types.js'\n\nexport type WidgetVariant = 'compact' | 'wide' | 'drawer'\n\n/** @internal Not part of the public API. */\nexport type InternalWidgetMode = 'limit'\nexport type WidgetMode =\n | 'default'\n | 'split'\n | 'custom'\n | 'refuel'\n | InternalWidgetMode\nexport type SplitMode = 'bridge' | 'swap'\nexport type SplitModeOptions = {\n defaultTab: SplitMode\n}\nexport type CustomMode = 'checkout' | 'deposit'\nexport interface ModeOptions {\n /**\n * Configure split mode behavior:\n * - 'bridge' | 'swap': Single mode without tabs\n * - { defaultTab: 'bridge' | 'swap' }: Tabs mode with configurable default tab\n */\n split?: SplitMode | SplitModeOptions\n custom?: { type: CustomMode }\n}\n\n/**\n * Identity of a header navigation tab. Each key maps to a widget variant, mode and\n * (optionally) mode options; labels are resolved from the key.\n */\nexport type SplitNavigationTabKey = SplitMode\n/** @internal Not part of the public API. */\nexport type InternalNavigationTabKey =\n | 'default'\n | 'private'\n | 'refuel'\n | 'swap-advanced'\n | 'bridge-advanced'\n | 'limit'\nexport type NavigationTabKey = InternalNavigationTabKey | SplitNavigationTabKey\n\nexport type Appearance = PaletteMode | 'system'\nexport interface NavigationProps {\n /**\n * If given, uses a negative margin to counteract the padding on sides for navigation elements like icon buttons.\n * @default true\n */\n edge?: boolean\n}\nexport type WidgetThemeComponents = Partial<\n Pick<\n Components<Theme>,\n | 'MuiAppBar'\n | 'MuiAvatar'\n | 'MuiButton'\n | 'MuiCard'\n | 'MuiDrawer'\n | 'MuiIconButton'\n | 'MuiInputCard'\n | 'MuiNavigationTabs'\n | 'MuiNavigationTab'\n | 'MuiTabs'\n | 'MuiCheckbox'\n >\n>\n\nexport type WidgetTheme = {\n colorSchemes?: {\n light?: {\n palette: PaletteOptions\n }\n dark?: {\n palette: PaletteOptions\n }\n }\n shape?: Partial<Shape>\n typography?: TypographyVariantsOptions\n components?: WidgetThemeComponents\n container?: CSSProperties\n routesContainer?: CSSProperties\n chainSidebarContainer?: CSSProperties\n header?: CSSProperties\n navigation?: NavigationProps\n}\n\nexport interface DisabledUIConfig {\n fromAmount?: boolean\n fromToken?: boolean\n toAddress?: boolean\n toToken?: boolean\n}\n\nexport interface HiddenUIConfig {\n addressBookConnectedWallets?: boolean\n allNetworks?: boolean\n appearance?: boolean\n bridgesSettings?: boolean\n chainSelect?: boolean\n /**\n * Hide the chain sidebar in the `wide` variant. No effect in other variants.\n * @default false\n */\n chainSidebar?: boolean\n contactSupport?: boolean\n /**\n * Hide the drawer close button. Only meaningful when `variant === 'drawer'`.\n * @default false\n */\n drawerCloseButton?: boolean\n fromToken?: boolean\n gasRefuelMessage?: boolean\n hideSmallBalances?: boolean\n history?: boolean\n insufficientGasMessage?: boolean\n integratorStepDetails?: boolean\n language?: boolean\n /**\n * Hide the warning shown when sending to an address with low historical\n * on-chain activity (low transaction count or contract-like behavior).\n * @default false\n */\n lowAddressActivityConfirmation?: boolean\n poweredBy?: boolean\n /**\n * Hide the \"Recent searches\" section in the token select view.\n * @default false\n */\n recentSearches?: boolean\n reverseTokensButton?: boolean\n routeCardPriceImpact?: boolean\n routeTokenDescription?: boolean\n searchTokenInput?: boolean\n toAddress?: boolean\n toToken?: boolean\n walletMenu?: boolean\n}\n\nexport interface RequiredUIConfig {\n accountDeployedMessage?: boolean\n toAddress?: boolean\n}\n\nexport type DefaultUI = {\n transactionDetailsExpanded?: boolean\n navigationHeaderTitleNoWrap?: boolean\n /**\n * Layout for the main form.\n * - `'default'`: the chain/token selectors plus single amount input.\n * - `'cards'`: the redesigned card-based layout — stacked Send/Receive amount\n * cards (`AmountInputCardPair`) with inline token pill selectors and a swap\n * button.\n * @default 'default'\n */\n layout?: 'default' | 'cards'\n}\n\nexport interface WidgetWalletConfig {\n walletEcosystemsOrder?: Record<string, ChainType[]>\n onConnect?(args?: WalletMenuOpenArgs): void\n /**\n * Determines whether the widget should provide partial wallet management functionality.\n *\n * In partial mode, external wallet management will be used for \"opt-out\" providers,\n * while the internal management is applied for any remaining providers that do not opt out.\n * This allows a flexible balance between the integrator's custom wallet menu and the widget's native wallet menu.\n * @default false\n */\n usePartialWalletManagement?: boolean\n /**\n * This option forces the widget to always use internal wallet management ignoring external wallet management contexts\n * @default false\n */\n forceInternalWalletManagement?: boolean\n}\n\nexport interface WidgetSDKConfig\n extends Omit<\n SDKConfig,\n | 'apiKey'\n | 'disableVersionCheck'\n | 'integrator'\n | 'providers'\n | 'routeOptions'\n | 'widgetVersion'\n > {\n routeOptions?: Omit<\n RouteOptions,\n 'bridges' | 'exchanges' | 'fee' | 'referrer' | 'order' | 'slippage'\n >\n executionOptions?: Pick<ExecutionOptions, 'updateTransactionRequestHook'>\n}\n\nexport interface WidgetContractTool {\n name: string\n logoURI: string\n}\n\nexport interface CalculateFeeParams {\n fromChain: ExtendedChain\n toChain: ExtendedChain\n fromToken: Token\n toToken: Token\n fromAddress?: string\n toAddress?: string\n fromAmount?: bigint\n toAmount?: bigint\n slippage?: number\n}\n\nexport interface WidgetFeeConfig {\n name?: string\n logoURI?: string\n fee?: number\n /**\n * Whether to show the fee percentage in the fee details.\n * @default false\n */\n showFeePercentage?: boolean\n /**\n * Whether to show a tooltip with the fee details. Requires `name` or `feeTooltipComponent` to be set.\n * @default false\n */\n showFeeTooltip?: boolean\n /**\n * Custom tooltip component to show with the fee details.\n */\n feeTooltipComponent?: ReactNode\n /**\n * Function to calculate fees before fetching quotes.\n * If provided, this function will be used instead of the `fee` parameter.\n * Only one of `fee` or `calculateFee` should be used.\n *\n * @param params Object containing the fee calculation parameters\n * @returns A promise that resolves to the calculated fee as a number (e.g., 0.03 represents a 3% fee)\n */\n calculateFee?(params: CalculateFeeParams): Promise<number | undefined>\n}\n\nexport interface ToAddress {\n name?: string\n address: string\n chainType: ChainType\n logoURI?: string\n}\n\nexport interface AllowDeny<T> {\n allow?: T[]\n deny?: T[]\n}\n\nexport type AllowDenySetItem = string | number\nexport interface AllowDenySet {\n allow?: Set<AllowDenySetItem>\n deny?: Set<AllowDenySetItem>\n}\n\nexport type AllowDenySets = {\n from?: AllowDenySet\n to?: AllowDenySet\n} & AllowDenySet\n\nexport type AllowDenyItems<T> = {\n from?: AllowDeny<T>\n to?: AllowDeny<T>\n} & AllowDeny<T>\n\nexport type WidgetChains = {\n types?: AllowDeny<ChainType>\n} & AllowDenyItems<number>\n\nexport type WidgetTokens = {\n featured?: StaticToken[]\n include?: Token[]\n popular?: StaticToken[]\n verified?: BaseToken[]\n} & AllowDenyItems<BaseToken>\n\nexport type WidgetLanguages = {\n default?: LanguageKey\n} & AllowDeny<LanguageKey>\n\nexport type PoweredByType = 'default' | 'jumper'\n\nexport interface RouteLabel {\n text: string\n sx?: SxProps<Theme>\n}\n\nexport interface RouteLabelRule {\n label: RouteLabel\n // Matching criteria\n bridges?: AllowDeny<string>\n exchanges?: AllowDeny<string>\n fromChainId?: number[]\n toChainId?: number[]\n fromTokenAddress?: string[]\n toTokenAddress?: string[]\n /**\n * Custom match function evaluated against the route. When provided, its\n * result is AND'd with the other matching criteria — all specified\n * conditions must pass for the label to apply. Use this for matching logic\n * that the built-in fields cannot express (gas costs, step count, route\n * tags, etc.).\n */\n match?: (route: Route) => boolean\n}\n\nexport type ExplorerUrl =\n | string\n | {\n url: string\n txPath?: string\n addressPath?: string\n }\n\nexport type WidgetProvider = (\n props: PropsWithChildren<WidgetProviderProps>\n) => ReactNode\n\nexport interface WidgetConfig {\n fromChain?: number\n toChain?: number\n fromToken?: string\n toToken?: string\n toAddress?: ToAddress\n toAddresses?: ToAddress[]\n fromAmount?: number | string\n minFromAmountUSD?: number\n toAmount?: number | string\n formUpdateKey?: string\n\n providers?: WidgetProvider[]\n\n contractCalls?: ContractCall[]\n contractComponent?: ReactNode\n contractSecondaryComponent?: ReactNode\n contractCompactComponent?: ReactNode\n contractTool?: WidgetContractTool\n integrator: string\n apiKey?: string\n feeConfig?: WidgetFeeConfig\n referrer?: string\n\n routePriority?: Order\n slippage?: number\n\n variant?: WidgetVariant\n mode?: WidgetMode\n modeOptions?: ModeOptions\n /**\n * Header navigation tabs, in order. When set, the widget renders a tab bar\n * and the active tab drives the displayed flow. Each entry is a tab key.\n *\n * @internal Not part of the public API.\n */\n _navigationTabs?: NavigationTabKey[]\n\n appearance?: Appearance\n theme?: WidgetTheme\n\n disabledUI?: DisabledUIConfig\n hiddenUI?: HiddenUIConfig\n requiredUI?: RequiredUIConfig\n defaultUI?: DefaultUI\n /**\n * When true, shows only the recommended route and hides the route\n * selector UI. Distinct from `routePriority`, which sets the SDK\n * ranking order across multiple displayed routes.\n * @default false\n */\n showSingleRoute?: boolean\n useRelayerRoutes?: boolean\n\n walletConfig?: WidgetWalletConfig\n sdkConfig?: WidgetSDKConfig\n\n buildUrl?: boolean\n keyPrefix?: string\n\n bridges?: AllowDeny<string>\n exchanges?: AllowDeny<string>\n chains?: WidgetChains\n tokens?: WidgetTokens\n languages?: WidgetLanguages\n languageResources?: LanguageResources\n explorerUrls?: Record<number, ExplorerUrl[]> &\n Partial<Record<'internal', ExplorerUrl[]>>\n poweredBy?: PoweredByType\n\n /**\n * Custom labels/badges to show on routes based on specified rules\n */\n routeLabels?: RouteLabelRule[]\n}\n\nexport interface FormFieldOptions {\n setUrlSearchParam: boolean\n}\n\nexport interface FieldValues\n extends Omit<DefaultFieldValues, 'fromAmount' | 'toAmount' | 'toAddress'> {\n fromAmount?: number | string\n toAmount?: number | string\n toAddress?: ToAddress | string\n}\n\nexport type FieldNames = keyof FieldValues\n\nexport type SetFieldValueFunction = <K extends FieldNames>(\n key: K,\n value: FieldValues[K],\n options?: FormFieldOptions\n) => void\n\nexport type FormState = {\n setFieldValue: SetFieldValueFunction\n}\n\nexport type FormRef = RefObject<FormState | null>\n\nexport interface FormRefProps {\n formRef?: FormRef\n}\n\nexport interface WidgetConfigProps extends FormRefProps {\n config: WidgetConfig\n}\n\nexport interface WidgetConfigPartialProps {\n config?: Partial<WidgetConfig>\n}\n\nexport type WidgetProps = WidgetDrawerProps &\n WidgetConfig &\n WidgetConfigPartialProps &\n FormRefProps\n\nexport interface WidgetDrawerProps extends WidgetConfigPartialProps {\n elementRef?: RefObject<HTMLDivElement>\n open?: boolean\n /**\n * Make sure to make the onClose callback stable (e.g. using useCallback) to avoid causing re-renders of the entire widget\n */\n onClose?(): void\n}\n\nexport enum ExpansionType {\n Routes = 'routes',\n FromChain = 'fromChain',\n ToChain = 'toChain',\n}\n"],"mappings":";AAieA,IAAY,gBAAL,yBAAA,eAAA;CACL,cAAA,YAAA;CACA,cAAA,eAAA;CACA,cAAA,aAAA;;AACF,EAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"widget.js","names":[],"sources":["../../../src/types/widget.ts"],"sourcesContent":["import type {\n BaseToken,\n ChainType,\n ContractCall,\n ExecutionOptions,\n ExtendedChain,\n Order,\n Route,\n RouteOptions,\n SDKConfig,\n StaticToken,\n Token,\n} from '@lifi/sdk'\nimport type { WalletMenuOpenArgs } from '@lifi/wallet-management'\nimport type { WidgetProviderProps } from '@lifi/widget-provider'\nimport type {\n Components,\n PaletteMode,\n PaletteOptions,\n Shape,\n SxProps,\n Theme,\n} from '@mui/material'\nimport type { TypographyVariantsOptions } from '@mui/material/styles'\nimport type {\n CSSProperties,\n PropsWithChildren,\n ReactNode,\n RefObject,\n} from 'react'\nimport type {\n LanguageKey,\n LanguageResources,\n} from '../providers/I18nProvider/types.js'\nimport type { DefaultFieldValues } from '../stores/form/types.js'\n\nexport type WidgetVariant = 'compact' | 'wide' | 'drawer'\n\n/** @internal Not part of the public API. */\nexport type InternalWidgetMode = 'limit'\nexport type WidgetMode =\n | 'default'\n | 'split'\n | 'custom'\n | 'refuel'\n | InternalWidgetMode\nexport type SplitMode = 'bridge' | 'swap'\nexport type SplitModeOptions = {\n defaultTab: SplitMode\n}\nexport type CustomMode = 'checkout' | 'deposit'\nexport interface ModeOptions {\n /**\n * Configure split mode behavior:\n * - 'bridge' | 'swap': Single mode without tabs\n * - { defaultTab: 'bridge' | 'swap' }: Tabs mode with configurable default tab\n */\n split?: SplitMode | SplitModeOptions\n custom?: { type: CustomMode }\n}\n\n/**\n * Identity of a header navigation tab. Each key maps to a widget variant, mode and\n * (optionally) mode options; labels are resolved from the key.\n */\nexport type SplitNavigationTabKey = SplitMode\n/** @internal Not part of the public API. */\nexport type InternalNavigationTabKey =\n | 'default'\n | 'private'\n | 'refuel'\n | 'swap-advanced'\n | 'bridge-advanced'\n | 'limit'\nexport type NavigationTabKey = InternalNavigationTabKey | SplitNavigationTabKey\n\nexport type Appearance = PaletteMode | 'system'\nexport interface NavigationProps {\n /**\n * If given, uses a negative margin to counteract the padding on sides for navigation elements like icon buttons.\n * @default true\n */\n edge?: boolean\n}\nexport type WidgetThemeComponents = Partial<\n Pick<\n Components<Theme>,\n | 'MuiAppBar'\n | 'MuiAvatar'\n | 'MuiButton'\n | 'MuiCard'\n | 'MuiDrawer'\n | 'MuiIconButton'\n | 'MuiInputCard'\n | 'MuiNavigationTabs'\n | 'MuiNavigationTab'\n | 'MuiTabs'\n | 'MuiCheckbox'\n >\n>\n\nexport type WidgetTheme = {\n colorSchemes?: {\n light?: {\n palette: PaletteOptions\n }\n dark?: {\n palette: PaletteOptions\n }\n }\n shape?: Partial<Shape>\n typography?: TypographyVariantsOptions\n components?: WidgetThemeComponents\n container?: CSSProperties\n routesContainer?: CSSProperties\n chainSidebarContainer?: CSSProperties\n header?: CSSProperties\n navigation?: NavigationProps\n}\n\nexport interface DisabledUIConfig {\n fromAmount?: boolean\n fromToken?: boolean\n toAddress?: boolean\n toToken?: boolean\n}\n\nexport interface HiddenUIConfig {\n addressBookConnectedWallets?: boolean\n allNetworks?: boolean\n appearance?: boolean\n bridgesSettings?: boolean\n chainSelect?: boolean\n /**\n * Hide the chain sidebar in the `wide` variant. No effect in other variants.\n * @default false\n */\n chainSidebar?: boolean\n contactSupport?: boolean\n /**\n * Hide the drawer close button. Only meaningful when `variant === 'drawer'`.\n * @default false\n */\n drawerCloseButton?: boolean\n fromToken?: boolean\n gasRefuelMessage?: boolean\n hideSmallBalances?: boolean\n history?: boolean\n insufficientGasMessage?: boolean\n integratorStepDetails?: boolean\n language?: boolean\n /**\n * Hide the warning shown when sending to an address with low historical\n * on-chain activity (low transaction count or contract-like behavior).\n * @default false\n */\n lowAddressActivityConfirmation?: boolean\n poweredBy?: boolean\n /**\n * Hide the \"Recent searches\" section in the token select view.\n * @default false\n */\n recentSearches?: boolean\n reverseTokensButton?: boolean\n routeCardPriceImpact?: boolean\n routeTokenDescription?: boolean\n searchTokenInput?: boolean\n toAddress?: boolean\n toToken?: boolean\n walletMenu?: boolean\n}\n\nexport interface RequiredUIConfig {\n accountDeployedMessage?: boolean\n toAddress?: boolean\n}\n\nexport type DefaultUI = {\n transactionDetailsExpanded?: boolean\n navigationHeaderTitleNoWrap?: boolean\n /**\n * Layout for the main form.\n * - `'default'`: the chain/token selectors plus single amount input.\n * - `'cards'`: the redesigned card-based layout — stacked Send/Receive amount\n * cards (`AmountInputCardPair`) with inline token pill selectors and a swap\n * button.\n * @default 'default'\n */\n layout?: 'default' | 'cards'\n}\n\nexport interface WidgetWalletConfig {\n walletEcosystemsOrder?: Record<string, ChainType[]>\n onConnect?(args?: WalletMenuOpenArgs): void\n /**\n * Determines whether the widget should provide partial wallet management functionality.\n *\n * In partial mode, external wallet management will be used for \"opt-out\" providers,\n * while the internal management is applied for any remaining providers that do not opt out.\n * This allows a flexible balance between the integrator's custom wallet menu and the widget's native wallet menu.\n * @default false\n */\n usePartialWalletManagement?: boolean\n /**\n * This option forces the widget to always use internal wallet management ignoring external wallet management contexts\n * @default false\n */\n forceInternalWalletManagement?: boolean\n}\n\nexport interface WidgetSDKConfig\n extends Omit<\n SDKConfig,\n | 'apiKey'\n | 'disableVersionCheck'\n | 'integrator'\n | 'providers'\n | 'routeOptions'\n | 'widgetVersion'\n > {\n routeOptions?: Omit<\n RouteOptions,\n 'bridges' | 'exchanges' | 'fee' | 'referrer' | 'order' | 'slippage'\n >\n executionOptions?: Pick<ExecutionOptions, 'updateTransactionRequestHook'>\n}\n\nexport interface WidgetContractTool {\n name: string\n logoURI: string\n}\n\nexport interface CalculateFeeParams {\n fromChain: ExtendedChain\n toChain: ExtendedChain\n fromToken: Token\n toToken: Token\n fromAddress?: string\n toAddress?: string\n fromAmount?: bigint\n toAmount?: bigint\n slippage?: number\n}\n\nexport interface WidgetFeeConfig {\n name?: string\n logoURI?: string\n fee?: number\n /**\n * Whether to show the fee percentage in the fee details.\n * @default false\n */\n showFeePercentage?: boolean\n /**\n * Whether to show a tooltip with the fee details. Requires `name` or `feeTooltipComponent` to be set.\n * @default false\n */\n showFeeTooltip?: boolean\n /**\n * Custom tooltip component to show with the fee details.\n */\n feeTooltipComponent?: ReactNode\n /**\n * Function to calculate fees before fetching quotes.\n * If provided, this function will be used instead of the `fee` parameter.\n * Only one of `fee` or `calculateFee` should be used.\n *\n * @param params Object containing the fee calculation parameters\n * @returns A promise that resolves to the calculated fee as a number (e.g., 0.03 represents a 3% fee)\n */\n calculateFee?(params: CalculateFeeParams): Promise<number | undefined>\n}\n\nexport interface ToAddress {\n name?: string\n address: string\n chainType: ChainType\n logoURI?: string\n}\n\nexport interface AllowDeny<T> {\n allow?: T[]\n deny?: T[]\n}\n\nexport type AllowDenySetItem = string | number\nexport interface AllowDenySet {\n allow?: Set<AllowDenySetItem>\n deny?: Set<AllowDenySetItem>\n}\n\nexport type AllowDenySets = {\n from?: AllowDenySet\n to?: AllowDenySet\n} & AllowDenySet\n\nexport type AllowDenyItems<T> = {\n from?: AllowDeny<T>\n to?: AllowDeny<T>\n} & AllowDeny<T>\n\nexport type WidgetChains = {\n types?: AllowDeny<ChainType>\n} & AllowDenyItems<number>\n\nexport type WidgetTokens = {\n featured?: StaticToken[]\n include?: Token[]\n popular?: StaticToken[]\n verified?: BaseToken[]\n} & AllowDenyItems<BaseToken>\n\nexport type WidgetLanguages = {\n default?: LanguageKey\n} & AllowDeny<LanguageKey>\n\nexport type PoweredByType = 'default' | 'jumper'\n\nexport interface RouteLabel {\n text: string\n sx?: SxProps<Theme>\n}\n\nexport interface RouteLabelRule {\n label: RouteLabel\n // Matching criteria\n bridges?: AllowDeny<string>\n exchanges?: AllowDeny<string>\n fromChainId?: number[]\n toChainId?: number[]\n fromTokenAddress?: string[]\n toTokenAddress?: string[]\n /**\n * Custom match function evaluated against the route. When provided, its\n * result is AND'd with the other matching criteria — all specified\n * conditions must pass for the label to apply. Use this for matching logic\n * that the built-in fields cannot express (gas costs, step count, route\n * tags, etc.).\n */\n match?: (route: Route) => boolean\n}\n\nexport type ExplorerUrl =\n | string\n | {\n url: string\n txPath?: string\n addressPath?: string\n }\n\nexport type WidgetProvider = (\n props: PropsWithChildren<WidgetProviderProps>\n) => ReactNode\n\nexport interface WidgetConfig {\n fromChain?: number\n toChain?: number\n fromToken?: string\n toToken?: string\n toAddress?: ToAddress\n toAddresses?: ToAddress[]\n fromAmount?: number | string\n minFromAmountUSD?: number\n toAmount?: number | string\n formUpdateKey?: string\n\n providers?: WidgetProvider[]\n\n contractCalls?: ContractCall[]\n contractComponent?: ReactNode\n contractSecondaryComponent?: ReactNode\n contractCompactComponent?: ReactNode\n contractTool?: WidgetContractTool\n integrator: string\n apiKey?: string\n feeConfig?: WidgetFeeConfig\n referrer?: string\n\n routePriority?: Order\n slippage?: number\n\n variant?: WidgetVariant\n mode?: WidgetMode\n modeOptions?: ModeOptions\n /**\n * Header navigation tabs, in order. When set, the widget renders a tab bar\n * and the active tab drives the displayed flow. Each entry is a tab key.\n *\n * @internal Not part of the public API.\n */\n _navigationTabs?: NavigationTabKey[]\n\n appearance?: Appearance\n theme?: WidgetTheme\n\n disabledUI?: DisabledUIConfig\n hiddenUI?: HiddenUIConfig\n requiredUI?: RequiredUIConfig\n defaultUI?: DefaultUI\n /**\n * When true, shows only the recommended route and hides the route\n * selector UI. Distinct from `routePriority`, which sets the SDK\n * ranking order across multiple displayed routes.\n * @default false\n */\n showSingleRoute?: boolean\n useRelayerRoutes?: boolean\n\n walletConfig?: WidgetWalletConfig\n sdkConfig?: WidgetSDKConfig\n\n buildUrl?: boolean\n /**\n * @deprecated Use `storageScopeKey` for persisted state and `queryScopeKey`\n * for the query cache. Still honoured as the fallback for both.\n */\n keyPrefix?: string\n /**\n * Namespaces the widget's persisted state in `localStorage`: bookmarks,\n * pinned tokens, recent tokens, chain order and route history, as\n * `keyPrefix` does. Use a different value per widget instance that should\n * keep its own state. Settings keep one shared name.\n *\n * It also scopes the widget's other queries (routes, tokens, balances, …),\n * so instances with different values keep their data apart.\n *\n * Falls back to `keyPrefix`, then to the historical `li.fi-*` names.\n */\n storageScopeKey?: string\n /**\n * Scopes the widget's chains and tools queries inside the host's react-query\n * `QueryClient`. Widget instances - and a host app using the\n * `@lifi/widget/queries` factories - that pass the same value\n * share those entries. The other widget queries are scoped by\n * `storageScopeKey`.\n *\n * The keys start with a plain `'chains'` / `'tools'`, as in wagmi, so a host\n * that matches on those roots (for example `setQueriesData({ queryKey:\n * ['chains'] })`) also reaches the widget's entries.\n *\n * Falls back to `keyPrefix`, then to `'li.fi'`.\n */\n queryScopeKey?: string\n\n bridges?: AllowDeny<string>\n exchanges?: AllowDeny<string>\n chains?: WidgetChains\n tokens?: WidgetTokens\n languages?: WidgetLanguages\n languageResources?: LanguageResources\n explorerUrls?: Record<number, ExplorerUrl[]> &\n Partial<Record<'internal', ExplorerUrl[]>>\n poweredBy?: PoweredByType\n\n /**\n * Custom labels/badges to show on routes based on specified rules\n */\n routeLabels?: RouteLabelRule[]\n}\n\nexport interface FormFieldOptions {\n setUrlSearchParam: boolean\n}\n\nexport interface FieldValues\n extends Omit<DefaultFieldValues, 'fromAmount' | 'toAmount' | 'toAddress'> {\n fromAmount?: number | string\n toAmount?: number | string\n toAddress?: ToAddress | string\n}\n\nexport type FieldNames = keyof FieldValues\n\nexport type SetFieldValueFunction = <K extends FieldNames>(\n key: K,\n value: FieldValues[K],\n options?: FormFieldOptions\n) => void\n\nexport type FormState = {\n setFieldValue: SetFieldValueFunction\n}\n\nexport type FormRef = RefObject<FormState | null>\n\nexport interface FormRefProps {\n formRef?: FormRef\n}\n\nexport interface WidgetConfigProps extends FormRefProps {\n config: WidgetConfig\n}\n\nexport interface WidgetConfigPartialProps {\n config?: Partial<WidgetConfig>\n}\n\nexport type WidgetProps = WidgetDrawerProps &\n WidgetConfig &\n WidgetConfigPartialProps &\n FormRefProps\n\nexport interface WidgetDrawerProps extends WidgetConfigPartialProps {\n elementRef?: RefObject<HTMLDivElement>\n open?: boolean\n /**\n * Make sure to make the onClose callback stable (e.g. using useCallback) to avoid causing re-renders of the entire widget\n */\n onClose?(): void\n}\n\nexport enum ExpansionType {\n Routes = 'routes',\n FromChain = 'fromChain',\n ToChain = 'toChain',\n}\n"],"mappings":";AA+fA,IAAY,gBAAL,yBAAA,eAAA;CACL,cAAA,YAAA;CACA,cAAA,eAAA;CACA,cAAA,aAAA;;AACF,EAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.js","names":[],"sources":["../../../src/utils/queries.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"queries.js","names":[],"sources":["../../../src/utils/queries.ts"],"sourcesContent":["// Legacy keys: callers pass the storage scope, so instances stay apart.\nexport const getQueryKey = (key: string, prefix?: string) =>\n `${prefix || 'li.fi'}-widget-${key}`\n"],"mappings":";AACA,MAAa,eAAe,KAAa,WACvC,GAAG,UAAU,QAAQ,UAAU"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { WidgetConfig } from "../types/widget.js";
|
|
2
|
+
//#region src/utils/scopeKeys.d.ts
|
|
3
|
+
type ScopeKeyConfig = Pick<WidgetConfig, "storageScopeKey" | "queryScopeKey" | "keyPrefix">;
|
|
4
|
+
export declare const resolveStorageScopeKey: (config: Partial<ScopeKeyConfig> | undefined) => string | undefined;
|
|
5
|
+
//#endregion
|
|
6
|
+
//# sourceMappingURL=scopeKeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopeKeys.d.ts","names":[],"sources":["../../../src/utils/scopeKeys.ts"],"mappings":";;KAKK,iBAAiB,KACpB;qBAKW,yBACX,QAAQ,QAAQ"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/utils/scopeKeys.ts
|
|
2
|
+
const defaultQueryScopeKey = "li.fi";
|
|
3
|
+
const resolveStorageScopeKey = (config) => config?.storageScopeKey ?? config?.keyPrefix;
|
|
4
|
+
const resolveQueryScopeKey = (config) => config?.queryScopeKey ?? config?.keyPrefix ?? "li.fi";
|
|
5
|
+
//#endregion
|
|
6
|
+
export { defaultQueryScopeKey, resolveQueryScopeKey, resolveStorageScopeKey };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=scopeKeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopeKeys.js","names":[],"sources":["../../../src/utils/scopeKeys.ts"],"sourcesContent":["import type { WidgetConfig } from '../types/widget.js'\n\n// Non-empty, so an unconfigured widget never shares a host's unscoped entries.\nexport const defaultQueryScopeKey = 'li.fi'\n\ntype ScopeKeyConfig = Pick<\n WidgetConfig,\n 'storageScopeKey' | 'queryScopeKey' | 'keyPrefix'\n>\n\n// `undefined` keeps the historical `li.fi-*` store names.\nexport const resolveStorageScopeKey = (\n config: Partial<ScopeKeyConfig> | undefined\n): string | undefined => config?.storageScopeKey ?? config?.keyPrefix\n\nexport const resolveQueryScopeKey = (\n config: Partial<ScopeKeyConfig> | undefined\n): string => config?.queryScopeKey ?? config?.keyPrefix ?? defaultQueryScopeKey\n"],"mappings":";AAGA,MAAa,uBAAuB;AAQpC,MAAa,0BACX,WACuB,QAAQ,mBAAmB,QAAQ;AAE5D,MAAa,wBACX,WACW,QAAQ,iBAAiB,QAAQ,aAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/widget",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.0",
|
|
4
4
|
"description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/index.js",
|
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
"import": "./dist/esm/shared.js",
|
|
22
22
|
"default": "./dist/esm/shared.js"
|
|
23
23
|
},
|
|
24
|
+
"./queries": {
|
|
25
|
+
"types": "./dist/esm/queries/index.d.ts",
|
|
26
|
+
"import": "./dist/esm/queries/index.js",
|
|
27
|
+
"default": "./dist/esm/queries/index.js"
|
|
28
|
+
},
|
|
24
29
|
"./package.json": "./package.json"
|
|
25
30
|
},
|
|
26
31
|
"sideEffects": false,
|
|
@@ -52,9 +57,9 @@
|
|
|
52
57
|
"dependencies": {
|
|
53
58
|
"@emotion/react": "^11.14.0",
|
|
54
59
|
"@emotion/styled": "^11.14.1",
|
|
55
|
-
"@lifi/sdk": "^4.
|
|
56
|
-
"@lifi/wallet-management": "4.3.
|
|
57
|
-
"@lifi/widget-provider": "4.5.
|
|
60
|
+
"@lifi/sdk": "^4.10.0",
|
|
61
|
+
"@lifi/wallet-management": "4.3.1",
|
|
62
|
+
"@lifi/widget-provider": "4.5.1",
|
|
58
63
|
"@mui/icons-material": "^9.4.0",
|
|
59
64
|
"@mui/material": "^9.4.0",
|
|
60
65
|
"@mui/system": "^9.4.0",
|
|
@@ -82,6 +87,9 @@
|
|
|
82
87
|
],
|
|
83
88
|
"shared": [
|
|
84
89
|
"./dist/esm/shared.d.ts"
|
|
90
|
+
],
|
|
91
|
+
"queries": [
|
|
92
|
+
"./dist/esm/queries/index.d.ts"
|
|
85
93
|
]
|
|
86
94
|
}
|
|
87
95
|
},
|
package/src/config/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget'
|
|
2
|
-
export const version = '4.
|
|
2
|
+
export const version = '4.8.0'
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/** @vitest-environment happy-dom */
|
|
2
|
+
|
|
3
|
+
import type * as LifiSdk from '@lifi/sdk'
|
|
4
|
+
import { ChainType, type ExtendedChain, type SDKClient } from '@lifi/sdk'
|
|
5
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
6
|
+
import { act } from 'react'
|
|
7
|
+
import { createRoot, type Root } from 'react-dom/client'
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
9
|
+
import type { WidgetConfig } from '../types/widget.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The chains entry is shared with the host app through
|
|
13
|
+
* `getChainsQueryOptions`, keyed by the client's API base, the requested chain
|
|
14
|
+
* types and the widget's `queryScopeKey`. The widget's own SDK client still
|
|
15
|
+
* gets the chains, whoever filled the entry.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const API_URL = 'https://api.example/v1'
|
|
19
|
+
|
|
20
|
+
const mocks = vi.hoisted(() => ({
|
|
21
|
+
getChains: vi.fn(),
|
|
22
|
+
setChains: vi.fn(),
|
|
23
|
+
}))
|
|
24
|
+
|
|
25
|
+
vi.mock('@lifi/sdk', async (importOriginal) => ({
|
|
26
|
+
...(await importOriginal<typeof LifiSdk>()),
|
|
27
|
+
getChains: mocks.getChains,
|
|
28
|
+
}))
|
|
29
|
+
|
|
30
|
+
let widgetConfig: Partial<WidgetConfig> = {}
|
|
31
|
+
|
|
32
|
+
vi.mock('../providers/WidgetProvider/WidgetProvider.js', () => ({
|
|
33
|
+
useWidgetConfig: () => widgetConfig,
|
|
34
|
+
}))
|
|
35
|
+
|
|
36
|
+
const client = {
|
|
37
|
+
config: { apiUrl: API_URL },
|
|
38
|
+
setChains: mocks.setChains,
|
|
39
|
+
} as unknown as SDKClient
|
|
40
|
+
vi.mock('../providers/SDKClientProvider.js', () => ({
|
|
41
|
+
useSDKClient: () => client,
|
|
42
|
+
}))
|
|
43
|
+
|
|
44
|
+
import { getChainsQueryKey } from '../queries/getChains.js'
|
|
45
|
+
import { useAvailableChains } from './useAvailableChains.js'
|
|
46
|
+
|
|
47
|
+
const CHAINS = [{ id: 1, name: 'Ethereum' }] as ExtendedChain[]
|
|
48
|
+
|
|
49
|
+
let root: Root
|
|
50
|
+
let queryClient: QueryClient
|
|
51
|
+
let externalConfig: WidgetConfig | undefined
|
|
52
|
+
|
|
53
|
+
const Probe = () => {
|
|
54
|
+
useAvailableChains(undefined, externalConfig)
|
|
55
|
+
return null
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const render = async () => {
|
|
59
|
+
await act(async () => {
|
|
60
|
+
root.render(
|
|
61
|
+
<QueryClientProvider client={queryClient}>
|
|
62
|
+
<Probe />
|
|
63
|
+
</QueryClientProvider>
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const evmKey = getChainsQueryKey({
|
|
69
|
+
apiUrl: API_URL,
|
|
70
|
+
chainTypes: [ChainType.EVM],
|
|
71
|
+
scopeKey: 'host',
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('useAvailableChains', () => {
|
|
75
|
+
beforeEach(() => {
|
|
76
|
+
vi.clearAllMocks()
|
|
77
|
+
mocks.getChains.mockResolvedValue(CHAINS)
|
|
78
|
+
widgetConfig = {
|
|
79
|
+
queryScopeKey: 'host',
|
|
80
|
+
chains: { types: { allow: [ChainType.EVM] } },
|
|
81
|
+
}
|
|
82
|
+
externalConfig = undefined
|
|
83
|
+
queryClient = new QueryClient({
|
|
84
|
+
defaultOptions: { queries: { retry: false } },
|
|
85
|
+
})
|
|
86
|
+
const container = document.createElement('div')
|
|
87
|
+
document.body.appendChild(container)
|
|
88
|
+
root = createRoot(container)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
afterEach(async () => {
|
|
92
|
+
await act(async () => root.unmount())
|
|
93
|
+
queryClient.clear()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('fetches the allowed chain types under the widget scope and hands them to the client', async () => {
|
|
97
|
+
await render()
|
|
98
|
+
|
|
99
|
+
await vi.waitFor(() => {
|
|
100
|
+
expect(mocks.setChains).toHaveBeenCalledWith(CHAINS)
|
|
101
|
+
})
|
|
102
|
+
expect(mocks.getChains).toHaveBeenCalledWith(client, {
|
|
103
|
+
chainTypes: [ChainType.EVM],
|
|
104
|
+
})
|
|
105
|
+
expect(queryClient.getQueryData(evmKey)).toBe(CHAINS)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('reads an entry the host filled, and still hands the chains to the client', async () => {
|
|
109
|
+
queryClient.setQueryData(evmKey, CHAINS)
|
|
110
|
+
|
|
111
|
+
await render()
|
|
112
|
+
|
|
113
|
+
await vi.waitFor(() => {
|
|
114
|
+
expect(mocks.setChains).toHaveBeenCalledWith(CHAINS)
|
|
115
|
+
})
|
|
116
|
+
expect(mocks.getChains).not.toHaveBeenCalled()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('hands the chains to the client again after a refetch with equal data', async () => {
|
|
120
|
+
// Structural sharing keeps the data reference on an equal refetch. The
|
|
121
|
+
// client's own chain storage expires, so every fetch must refresh it.
|
|
122
|
+
await render()
|
|
123
|
+
await vi.waitFor(() => {
|
|
124
|
+
expect(mocks.setChains).toHaveBeenCalledTimes(1)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
await act(async () => {
|
|
128
|
+
await queryClient.refetchQueries({ queryKey: evmKey })
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
await vi.waitFor(() => {
|
|
132
|
+
expect(mocks.setChains).toHaveBeenCalledTimes(2)
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('refreshes the chains every five minutes', async () => {
|
|
137
|
+
await render()
|
|
138
|
+
await vi.waitFor(() => {
|
|
139
|
+
expect(queryClient.getQueryData(evmKey)).toBe(CHAINS)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const [observer] = queryClient
|
|
143
|
+
.getQueryCache()
|
|
144
|
+
.find({ queryKey: evmKey })!.observers
|
|
145
|
+
expect(observer.options.refetchInterval).toBe(300_000)
|
|
146
|
+
expect(observer.options.staleTime).toBe(300_000)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('uses the API base and scope of an external widget config', async () => {
|
|
150
|
+
externalConfig = {
|
|
151
|
+
integrator: 'partner',
|
|
152
|
+
keyPrefix: 'partner',
|
|
153
|
+
sdkConfig: { apiUrl: 'https://partner.example/v1' },
|
|
154
|
+
chains: { types: { allow: [ChainType.SVM] } },
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
await render()
|
|
158
|
+
|
|
159
|
+
const partnerKey = getChainsQueryKey({
|
|
160
|
+
apiUrl: 'https://partner.example/v1',
|
|
161
|
+
chainTypes: [ChainType.SVM],
|
|
162
|
+
scopeKey: 'partner',
|
|
163
|
+
})
|
|
164
|
+
await vi.waitFor(() => {
|
|
165
|
+
expect(queryClient.getQueryData(partnerKey)).toBe(CHAINS)
|
|
166
|
+
})
|
|
167
|
+
// The external config's own client, not the widget's.
|
|
168
|
+
expect(mocks.getChains.mock.calls[0][0]).not.toBe(client)
|
|
169
|
+
})
|
|
170
|
+
})
|
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
import type { ExtendedChain } from '@lifi/sdk'
|
|
2
|
-
import {
|
|
1
|
+
import type { ChainType, ExtendedChain } from '@lifi/sdk'
|
|
2
|
+
import { createClient } from '@lifi/sdk'
|
|
3
3
|
import { useQuery } from '@tanstack/react-query'
|
|
4
4
|
import { useCallback, useEffect, useMemo } from 'react'
|
|
5
5
|
import { useSDKClient } from '../providers/SDKClientProvider.js'
|
|
6
6
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
7
|
+
import {
|
|
8
|
+
getChainsQueryOptions,
|
|
9
|
+
supportedChainTypes,
|
|
10
|
+
} from '../queries/getChains.js'
|
|
7
11
|
import type { WidgetConfig } from '../types/widget.js'
|
|
8
12
|
import { getConfigItemSets, isItemAllowedForSets } from '../utils/item.js'
|
|
9
|
-
import {
|
|
13
|
+
import { resolveQueryScopeKey } from '../utils/scopeKeys.js'
|
|
10
14
|
|
|
11
15
|
type GetChainById = (
|
|
12
16
|
chainId?: number,
|
|
13
17
|
chains?: ExtendedChain[]
|
|
14
18
|
) => ExtendedChain | undefined
|
|
15
19
|
|
|
16
|
-
const
|
|
17
|
-
ChainType.EVM,
|
|
18
|
-
ChainType.SVM,
|
|
19
|
-
ChainType.UTXO,
|
|
20
|
-
ChainType.MVM,
|
|
21
|
-
ChainType.TVM,
|
|
22
|
-
ChainType.STL,
|
|
23
|
-
]
|
|
20
|
+
const refetchInterval = 300_000
|
|
24
21
|
|
|
25
22
|
export const useAvailableChains = (
|
|
26
23
|
chainTypes?: ChainType[],
|
|
@@ -30,7 +27,7 @@ export const useAvailableChains = (
|
|
|
30
27
|
getChainById: GetChainById
|
|
31
28
|
isLoading: boolean
|
|
32
29
|
} => {
|
|
33
|
-
const { chains: internalChains,
|
|
30
|
+
const { chains: internalChains, queryScopeKey: internalQueryScopeKey } =
|
|
34
31
|
useWidgetConfig()
|
|
35
32
|
const internalClient = useSDKClient()
|
|
36
33
|
|
|
@@ -46,46 +43,31 @@ export const useAvailableChains = (
|
|
|
46
43
|
}, [widgetConfig])
|
|
47
44
|
|
|
48
45
|
// Overwrite widget config if passed as param
|
|
49
|
-
const
|
|
46
|
+
const client = externalClient ?? internalClient
|
|
50
47
|
const chains = widgetConfig?.chains ?? internalChains
|
|
48
|
+
const queryScopeKey = widgetConfig
|
|
49
|
+
? resolveQueryScopeKey(widgetConfig)
|
|
50
|
+
: internalQueryScopeKey
|
|
51
51
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
chainTypesConfig,
|
|
65
|
-
(chains) => new Set(chains)
|
|
66
|
-
)
|
|
67
|
-
const chainTypesRequest = supportedChainTypes.filter((chainType) =>
|
|
68
|
-
isItemAllowedForSets(chainType, chainsConfigSets)
|
|
69
|
-
)
|
|
70
|
-
const client = externalClient ?? internalClient
|
|
71
|
-
const availableChains = await getChains(client, {
|
|
72
|
-
chainTypes: chainTypes || chainTypesRequest,
|
|
73
|
-
})
|
|
74
|
-
client.setChains(availableChains)
|
|
75
|
-
return availableChains
|
|
76
|
-
},
|
|
77
|
-
refetchInterval: 300_000,
|
|
78
|
-
staleTime: 300_000,
|
|
79
|
-
})
|
|
52
|
+
const typeSets = getConfigItemSets(chains?.types, (types) => new Set(types))
|
|
53
|
+
const requestedTypes =
|
|
54
|
+
chainTypes ??
|
|
55
|
+
supportedChainTypes.filter((type) => isItemAllowedForSets(type, typeSets))
|
|
56
|
+
|
|
57
|
+
const { data, dataUpdatedAt, isLoading } = useQuery(
|
|
58
|
+
getChainsQueryOptions(client, {
|
|
59
|
+
chainTypes: requestedTypes,
|
|
60
|
+
scopeKey: queryScopeKey,
|
|
61
|
+
query: { refetchInterval, staleTime: refetchInterval },
|
|
62
|
+
})
|
|
63
|
+
)
|
|
80
64
|
|
|
81
|
-
//
|
|
82
|
-
// - the query result came from cache (external call populated it first)
|
|
83
|
-
// - the client was recreated due to config changes (stale closure in queryFn)
|
|
65
|
+
// A host may fill the entry; key on dataUpdatedAt, as a refetch keeps data.
|
|
84
66
|
useEffect(() => {
|
|
85
|
-
if (data &&
|
|
86
|
-
|
|
67
|
+
if (data && dataUpdatedAt) {
|
|
68
|
+
client.setChains(data)
|
|
87
69
|
}
|
|
88
|
-
}, [data,
|
|
70
|
+
}, [data, dataUpdatedAt, client])
|
|
89
71
|
|
|
90
72
|
const getChainById: GetChainById = useCallback(
|
|
91
73
|
(chainId?: number, chains: ExtendedChain[] | undefined = data) => {
|
|
@@ -22,7 +22,7 @@ export const useFromTokenSufficiency = (
|
|
|
22
22
|
'fromToken',
|
|
23
23
|
'fromAmount'
|
|
24
24
|
)
|
|
25
|
-
const {
|
|
25
|
+
const { storageScopeKey } = useWidgetConfig()
|
|
26
26
|
const sdkClient = useSDKClient()
|
|
27
27
|
|
|
28
28
|
let chainId = fromChainId
|
|
@@ -42,7 +42,7 @@ export const useFromTokenSufficiency = (
|
|
|
42
42
|
|
|
43
43
|
const { data: insufficientFromToken, isLoading } = useQuery({
|
|
44
44
|
queryKey: [
|
|
45
|
-
getQueryKey('from-token-sufficiency-check',
|
|
45
|
+
getQueryKey('from-token-sufficiency-check', storageScopeKey),
|
|
46
46
|
account.address,
|
|
47
47
|
chainId,
|
|
48
48
|
tokenAddress,
|
|
@@ -14,7 +14,7 @@ export const useGasRecommendation = (
|
|
|
14
14
|
fromToken?: string
|
|
15
15
|
): UseQueryResult<Awaited<ReturnType<typeof getGasRecommendation>> | null> => {
|
|
16
16
|
const { chains } = useAvailableChains()
|
|
17
|
-
const {
|
|
17
|
+
const { storageScopeKey, hiddenUI } = useWidgetConfig()
|
|
18
18
|
const sdkClient = useSDKClient()
|
|
19
19
|
|
|
20
20
|
const checkRecommendationLiFuel =
|
|
@@ -28,7 +28,7 @@ export const useGasRecommendation = (
|
|
|
28
28
|
|
|
29
29
|
return useQuery({
|
|
30
30
|
queryKey: [
|
|
31
|
-
getQueryKey('gas-recommendation',
|
|
31
|
+
getQueryKey('gas-recommendation', storageScopeKey),
|
|
32
32
|
toChainId,
|
|
33
33
|
fromChain,
|
|
34
34
|
fromToken,
|
|
@@ -32,7 +32,7 @@ export const useGasSufficiency = (
|
|
|
32
32
|
const { account: EVMAccount, accounts } = useAccount({
|
|
33
33
|
chainType: ChainType.EVM,
|
|
34
34
|
})
|
|
35
|
-
const {
|
|
35
|
+
const { storageScopeKey, hiddenUI } = useWidgetConfig()
|
|
36
36
|
const sdkClient = useSDKClient()
|
|
37
37
|
|
|
38
38
|
const { relevantAccounts, relevantAccountsQueryKey } = useMemo(() => {
|
|
@@ -67,7 +67,7 @@ export const useGasSufficiency = (
|
|
|
67
67
|
|
|
68
68
|
const { data: insufficientGas, isLoading } = useQuery<GasSufficiency[]>({
|
|
69
69
|
queryKey: [
|
|
70
|
-
getQueryKey('gas-sufficiency-check',
|
|
70
|
+
getQueryKey('gas-sufficiency-check', storageScopeKey),
|
|
71
71
|
relevantAccountsQueryKey,
|
|
72
72
|
route?.id,
|
|
73
73
|
isContractAddress,
|
|
@@ -13,7 +13,7 @@ export function useIsBatchingSupported(
|
|
|
13
13
|
isBatchingSupported: boolean | undefined
|
|
14
14
|
isBatchingSupportedLoading: boolean
|
|
15
15
|
} {
|
|
16
|
-
const {
|
|
16
|
+
const { storageScopeKey } = useWidgetConfig()
|
|
17
17
|
const sdkClient = useSDKClient()
|
|
18
18
|
const { isBatchingSupported } = useEthereumContext()
|
|
19
19
|
|
|
@@ -22,7 +22,7 @@ export function useIsBatchingSupported(
|
|
|
22
22
|
)
|
|
23
23
|
const { data, isLoading } = useQuery({
|
|
24
24
|
queryKey: [
|
|
25
|
-
getQueryKey('isBatchingSupported',
|
|
25
|
+
getQueryKey('isBatchingSupported', storageScopeKey),
|
|
26
26
|
chain?.id,
|
|
27
27
|
address,
|
|
28
28
|
],
|
|
@@ -43,7 +43,7 @@ export const useRouteExecution = ({
|
|
|
43
43
|
const queryClient = useQueryClient()
|
|
44
44
|
const { account } = useAccount()
|
|
45
45
|
const resumedAfterMount = useRef(false)
|
|
46
|
-
const {
|
|
46
|
+
const { storageScopeKey } = useWidgetConfig()
|
|
47
47
|
const sdkClient = useSDKClient()
|
|
48
48
|
const emitter = useWidgetEvents()
|
|
49
49
|
const routeExecutionStoreContext = useRouteExecutionStoreContext()
|
|
@@ -84,16 +84,16 @@ export const useRouteExecution = ({
|
|
|
84
84
|
if (executionCompleted || executionFailed) {
|
|
85
85
|
const invalidateKeys = [
|
|
86
86
|
[
|
|
87
|
-
getQueryKey('token-balances',
|
|
87
|
+
getQueryKey('token-balances', storageScopeKey),
|
|
88
88
|
clonedUpdatedRoute.fromAddress,
|
|
89
89
|
clonedUpdatedRoute.fromChainId,
|
|
90
90
|
],
|
|
91
91
|
[
|
|
92
|
-
getQueryKey('token-balances',
|
|
92
|
+
getQueryKey('token-balances', storageScopeKey),
|
|
93
93
|
clonedUpdatedRoute.toAddress,
|
|
94
94
|
clonedUpdatedRoute.toChainId,
|
|
95
95
|
],
|
|
96
|
-
[getQueryKey('transaction-history',
|
|
96
|
+
[getQueryKey('transaction-history', storageScopeKey)],
|
|
97
97
|
]
|
|
98
98
|
for (const key of invalidateKeys) {
|
|
99
99
|
queryClient.invalidateQueries(
|
|
@@ -133,7 +133,7 @@ export const useRouteExecution = ({
|
|
|
133
133
|
throw new Error('Execution route not found.')
|
|
134
134
|
}
|
|
135
135
|
queryClient.removeQueries({
|
|
136
|
-
queryKey: [getQueryKey('routes',
|
|
136
|
+
queryKey: [getQueryKey('routes', storageScopeKey)],
|
|
137
137
|
exact: false,
|
|
138
138
|
})
|
|
139
139
|
return executeRoute(sdkClient, routeExecution.route, {
|
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -82,7 +82,7 @@ export const useRoutes = ({
|
|
|
82
82
|
exchanges,
|
|
83
83
|
feeConfig,
|
|
84
84
|
useRelayerRoutes,
|
|
85
|
-
|
|
85
|
+
storageScopeKey,
|
|
86
86
|
} = useWidgetConfig()
|
|
87
87
|
const sdkClient = useSDKClient()
|
|
88
88
|
const setExecutableRoute = useSetExecutableRoute()
|
|
@@ -214,7 +214,7 @@ export const useRoutes = ({
|
|
|
214
214
|
const queryKey = useMemo(
|
|
215
215
|
() =>
|
|
216
216
|
[
|
|
217
|
-
getQueryKey('routes',
|
|
217
|
+
getQueryKey('routes', storageScopeKey),
|
|
218
218
|
effectiveFromAddress,
|
|
219
219
|
fromChain?.id as number,
|
|
220
220
|
fromToken?.address as string,
|
|
@@ -244,7 +244,7 @@ export const useRoutes = ({
|
|
|
244
244
|
observableRoute?.id,
|
|
245
245
|
] as const,
|
|
246
246
|
[
|
|
247
|
-
|
|
247
|
+
storageScopeKey,
|
|
248
248
|
effectiveFromAddress,
|
|
249
249
|
fromChain?.id,
|
|
250
250
|
fromToken?.address,
|
|
@@ -550,14 +550,14 @@ export const useRoutes = ({
|
|
|
550
550
|
;[fromToken, toToken].forEach((token) => {
|
|
551
551
|
// Update main tokens cache (verified)
|
|
552
552
|
queryClient.setQueriesData<TokensByChain>(
|
|
553
|
-
{ queryKey: [getQueryKey('tokens',
|
|
553
|
+
{ queryKey: [getQueryKey('tokens', storageScopeKey)] },
|
|
554
554
|
(data) => updateTokenInCache(data, token)
|
|
555
555
|
)
|
|
556
556
|
|
|
557
557
|
// Update search tokens cache (unverified) - matches any search query
|
|
558
558
|
queryClient.setQueriesData<TokensByChain>(
|
|
559
559
|
{
|
|
560
|
-
queryKey: [getQueryKey('tokens-search',
|
|
560
|
+
queryKey: [getQueryKey('tokens-search', storageScopeKey)],
|
|
561
561
|
exact: false,
|
|
562
562
|
},
|
|
563
563
|
(data) => updateTokenInCache(data, token)
|
|
@@ -566,7 +566,7 @@ export const useRoutes = ({
|
|
|
566
566
|
queryClient.setQueriesData<Token[]>(
|
|
567
567
|
{
|
|
568
568
|
queryKey: [
|
|
569
|
-
getQueryKey('token-balances',
|
|
569
|
+
getQueryKey('token-balances', storageScopeKey),
|
|
570
570
|
fromAddress,
|
|
571
571
|
token.chainId,
|
|
572
572
|
],
|
|
@@ -23,18 +23,18 @@ export const useTokenBalance = (
|
|
|
23
23
|
getTokenBalancesWithRetry: typeof getTokenBalancesWithRetry
|
|
24
24
|
} => {
|
|
25
25
|
const queryClient = useQueryClient()
|
|
26
|
-
const {
|
|
26
|
+
const { storageScopeKey } = useWidgetConfig()
|
|
27
27
|
const sdkClient = useSDKClient()
|
|
28
28
|
|
|
29
29
|
const tokenBalanceQueryKey = useMemo(
|
|
30
30
|
() =>
|
|
31
31
|
[
|
|
32
|
-
getQueryKey('token-balance',
|
|
32
|
+
getQueryKey('token-balance', storageScopeKey),
|
|
33
33
|
accountAddress,
|
|
34
34
|
token?.chainId,
|
|
35
35
|
token?.address,
|
|
36
36
|
] as const,
|
|
37
|
-
[token?.address, token?.chainId, accountAddress,
|
|
37
|
+
[token?.address, token?.chainId, accountAddress, storageScopeKey]
|
|
38
38
|
)
|
|
39
39
|
|
|
40
40
|
const { data, isLoading, refetch } = useQuery({
|
|
@@ -67,7 +67,7 @@ export const useTokenBalance = (
|
|
|
67
67
|
queryClient.setQueriesData<TokenAmount[]>(
|
|
68
68
|
{
|
|
69
69
|
queryKey: [
|
|
70
|
-
getQueryKey('token-balances',
|
|
70
|
+
getQueryKey('token-balances', storageScopeKey),
|
|
71
71
|
accountAddress,
|
|
72
72
|
tokenChainId,
|
|
73
73
|
],
|