### Install the widget with npm Source: https://github.com/ensobuild/shortcuts-widget/blob/main/widget/README.md Install the @ensofinance/shortcuts-widget package using npm. Requires wagmi and viem as peer dependencies. ```bash npm install @ensofinance/shortcuts-widget ``` -------------------------------- ### Example: tracking a transaction with useTxTracker Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/07-tx-tracker.md Example usage of `useTxTracker`. `bridgeProtocol` is omitted for same-chain swaps. The `onConfirmed` callback logs the confirmed block number. ```tsx const { track } = useTxTracker(); track({ hash: "0xabc…123", chainId: SupportedChainId.MAINNET, bridgeProtocol: undefined, // omit for same-chain swaps message: `Bridged ${amount} ETH`, onConfirmed: (receipt) => { console.log("confirmed block", receipt.blockNumber); }, }); ``` -------------------------------- ### useTokenBalance example Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/05-wallet-hooks.md Example usage of `useTokenBalance` to get a balance and compare it against a denormalized amount. ```tsx const balance = useTokenBalance("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", 1); const enough = +balance >= denormalizeValue(amount, 6); ``` -------------------------------- ### Basic usage of SwapWidget Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/01-widget.md Minimal setup for the SwapWidget component. Requires an API key and renders the widget with sharing enabled and adaptive layout. ```tsx import React from "react"; import SwapWidget from "@ensofinance/shortcuts-widget"; const App = () => { return (
); }; export default App; ``` -------------------------------- ### Module-level EnsoClient singleton (sovereign example) Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md The module-level `do` counter is set to `null` (ensure when EnzoClient singleton is reset). ```tsx // widget/src/util/enso.tsx:43 let ensoClient: EnsoClient | null = null; ``` -------------------------------- ### useEnsoToken example with array of addresses Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Example usage of useEnsoToken with an array of addresses. The returned tokens array contains objects with address, decimals, logoURI, and underlyingTokens properties. ```tsx const { tokens, isLoading } = useEnsoToken({ address: ["0xa0b8...48", "0x2260...c599"], priorityChainId: SupportedChainId.MAINNET, enabled: true, }); // tokens[i].address, tokens[i].decimals, tokens[i].logoURI, tokens[i].underlyingTokens ``` -------------------------------- ### useApproveIfNecessary usage example Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/05-wallet-hooks.md Shows how to call the hook and conditionally render an Approve button. The button is shown only when approve is truthy, and uses approve.isPending for loading state and approve.write for the click handler. ```tsx const approve = useApproveIfNecessary( tokenIn, approveData.data?.spender, // from useEnsoApprove amountIn ); // UI: approve && ``` -------------------------------- ### useEnsoData example usage Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Example call to useEnsoData with a USDC to ETH swap, 0.5% slippage, a 5 basis point fee to socialReceiver, and an onSuccess callback that logs the transaction hash and amountIn. The hook returns { ...routerData, sendTransaction } where sendTransaction is from useExtendedSendTransaction. ```tsx const { data: routerData, isLoading, error, sendTransaction } = useEnsoData( denormalizeValue("1.5", usdc.decimals), "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH 50, // 0.5% slippage undefined, { fee: 5, feeReceiver: socialReceiver }, (hash, details) => { console.log("sent", hash, "amountIn", details?.amountIn); } ); ``` -------------------------------- ### Creating an error toast with toaster.create Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/09-ui-primitives.md Example usage of the toaster singleton to create an error toast, used by useExtendedSendTransaction. Shows importing the toaster and calling create with title, description, and type. ```tsx import { toaster } from "@/components/ui/toaster"; toaster.create({ title: "Error", description: error?.cause?.shortMessage || error.message, type: "error", }); ``` -------------------------------- ### Formatting pipeline with denormalizeValue, normalizeValue, formatNumber, formatUSD Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/06-common-utils.md Use this pipeline to convert a raw string value to a normalized human-readable number and then format it as a plain number or USD. The example shows the expected outputs for each step: denormalizeValue("1.5", 6) returns "1500000", normalizeValue(raw, 6) returns "1.5", formatNumber(human, true) returns "1.5", and formatUSD(1234.567) returns "$1,234.57". ```tsx import { denormalizeValue, formatNumber, formatUSD, normalizeValue } from "@/util"; const raw = denormalizeValue("1.5", 6); // "1500000" const human = normalizeValue(raw, 6); // "1.5" const label = formatNumber(human, true); // "1.5" const usd = formatUSD(1234.567); // "$1,234.57" ``` -------------------------------- ### Example usage of useExtendedSendTransaction Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/05-wallet-hooks.md Shows how to call the hook with routerData?.tx as args and an onSuccess callback. The sendTransaction function is invoked on user action; on failure, the widget library shows the 'Error' toast automatically. ```tsx const { sendTransaction, isPending } = useExtendedSendTransaction({ args: routerData?.tx, onSuccess: (hash) => console.log("mined/queued", hash), }); // user action: sendTransaction(); // on failure the widget library itself shows the "Error" toast; no try/catch needed ``` -------------------------------- ### initEnsoClient - initialize the Enso SDK client Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Creates the `EnsoClient` with the provided API key and optional base URL, then adds a request interceptor that attaches the custom header `x-enso-widget` to all requests. Returns the client as a module-level singleton, so on the required API key before it can be made. ```tsx export const initEnsoClient = (apiKey: string, baseUrl?: string) => { ensoClient = new EnsoClient({ ...(baseUrl && { baseURL: baseUrl }), apiKey, }); // Add custom header to all requests // @ts-expect-error accessing private axios client ensoClient.client.interceptors.request.use((config) => { config.headers["x-enso-widget"] = "shortcuts"; return config; }); }; ``` -------------------------------- ### Basic SwapWidget implementation Source: https://github.com/ensobuild/shortcuts-widget/blob/main/README.md Minimal usage of the SwapWidget component with an API key and optional configuration. Requires an Enso API key from developers.enso.build. ```tsx import React from "react"; import SwapWidget from "@ensofinance/shortcuts-widget"; const App = () => { return (
); }; export default App; ``` -------------------------------- ### Toaster singleton and Toaster component with live placement Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/09-ui-primitives.md Creates a module-level toaster singleton with Chakra's createToaster and exports a Toaster component that updates the placement live from the notificationPlacement prop. Toasts render a spinner for type === "loading" and include title, description, action, and close trigger based on toast.meta?.closable. ```tsx export const toaster: ReturnType = createToaster({ placement: "bottom-end", pauseOnPageIdle: true, }); export const Toaster = ({ portalRef, placement, }: { portalRef?: React.RefObject; placement?: Placement; }) => { useEffect(() => { if (placement) { toaster.attrs.placement = placement; } }, [placement]); ... }; ``` -------------------------------- ### InputGroupProps interface and InputGroup component Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/09-ui-primitives.md Defines the InputGroup component props and its forwardRef implementation. It clones the single child input and adds padding when start/end elements exist, with the start element set to pointerEvents="none". ```tsx export interface InputGroupProps extends BoxProps { startElementProps?: InputElementProps endElementProps?: InputElementProps startElement?: React.ReactNode endElement?: React.ReactNode children: React.ReactElement startOffset?: InputElementProps["paddingStart"] endOffset?: InputElementProps["paddingEnd"] } export const InputGroup = React.forwardRef(...); ``` -------------------------------- ### Widget usage with useMemo and render Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/10-demo-app.md Builds widget props via `useMemo`, conditionally adding chainId, tokenIn, tokenOut, outChainId, outProject, obligateSelection, baseUrl from state. Renders ``. ```tsx const widgetProps = useMemo(() => { const props: ComponentProps = { fontFamily: "'Favorit Mono', monospace;", apiKey: EnsoApiKey, onChange: handleStateChange, indicateRoute: true, }; // conditionally adds chainId, tokenIn, tokenOut, outChainId, outProject, // obligateSelection, baseUrl from state return props; }, [state, handleStateChange]); // render: ``` -------------------------------- ### initEnsoClient Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Initializes the Enso client with an API key and optional base URL. Adds a custom header to all subsequent requests. ```APIDOC ## initEnsoClient ### Description Initializes the Enso client with an API key and optional base URL. Adds a custom header to all subsequent requests. ### Method Function ### Signature ```tsx export const initEnsoClient = (apiKey: string, baseUrl?: string) => { ensoClient = new EnsoClient({ ...(baseUrl && { baseURL: baseUrl }), apiKey, }); // Add custom header to all requests // @ts-expect-error accessing private axios client ensoClient.client.interceptors.request.use((config) => { config.headers["x-enso-widget"] = "shortcuts"; return config; }); }; ``` ### Parameters - **apiKey** (string) - Required - Enso API key - **baseUrl** (string) - Optional - Overrides the SDK base URL; only spread into the constructor when truthy ### Returns `void` ### Side Effects Every subsequent Enso request carries the HTTP header `x-enso-widget: shortcuts`. Called automatically by `Widget` on mount when `apiKey` is set (`index.tsx:144-148`). ``` -------------------------------- ### Imperative state seeding with useStore.setState (pattern from widget/index.tsx:90-99) Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/03-store.md Shows how to imperatively set store fields using setState, as done by the Widget entry point. ```tsx // pattern from widget/index.tsx:90-99 useStore.setState({ obligatedChainId: 1 }); useStore.setState({ tokenOutChainId: 137 }); ``` -------------------------------- ### useEnsoBalances Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Hook to fetch the user's balances across protocols via the Enso client. ```APIDOC ## useEnsoBalances ### Description Fetches the user's balances across protocols using the Enso client. Returns a `useQuery` result that is disabled until a valid wallet address is available. ### Method Hook ### Endpoint `useEnsoBalances(priorityChainId?)` ### Parameters #### Parameters - **priorityChainId** (`SupportedChainId`) - Optional - Chain to fetch balances for. Defaults to `usePriorityChainId()`. ### Returns Returns `useQuery` result with `data` = `getBalances({ useEoa: true, chainId, eoaAddress })` — wrapped positions and balances across protocols. Disabled while no wallet address is valid. ### Example ```tsx export const useEnsoBalances = (priorityChainId?: SupportedChainId) => { const { address } = useAccount(); const chainId = usePriorityChainId(priorityChainId); return useQuery({ queryKey: ["enso-balances", chainId, address], queryFn: () => ensoClient.getBalances({ useEoa: true, chainId, eoaAddress: address }), enabled: isAddress(address), }); }; ``` ``` -------------------------------- ### Routing constants: SWAP_LIMITS, SWAP_REDIRECT_TOKENS, LP_REDIRECT_TOKENS, ONEINCH_ONLY_TOKENS, PRICE_IMPACT_WARN_THRESHOLD, DEFAULT_SLIPPAGE Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/02-constants.md Defines constants for swap routing limits and redirects. SWAP_LIMITS sets max notional per output token; SWAP_REDIRECT_TOKENS triggers a blocked notification with a Uniswap swap URL; LP_REDIRECT_TOKENS maps tokens to a Uniswap V2 LP deploy URL; ONEINCH_ONLY_TOKENS forces routing through 1inch by setting ignoreAggregators; PRICE_IMPACT_WARN_THRESHOLD is 200 basis points; DEFAULT_SLIPPAGE is 25 basis points. ```tsx export const SWAP_LIMITS: Record = { ["0x09def5abc67e967d54e8233a4b5ebbc1b3fbe34b"]: 100000, // WABTC limit }; export const SWAP_REDIRECT_TOKENS: Address[] = ["0x09def5abc67e967d54e8233a4b5ebbc1b3fbe34b"]; // WABTC export const LP_REDIRECT_TOKENS: Record = { ["0x42a094364bbdca0efac8af2cf7d6b9ec885ee554"]: "https://app.uniswap.org/positions/create/v2?currencyA=0x09DEF5...¤cyB=...&chain=ethereum", // WABTC LP deploy }; export const ONEINCH_ONLY_TOKENS = [ "0xcf21354360fdae8edad02c0529e55cb3e71c36c9", "0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3", ]; export const PRICE_IMPACT_WARN_THRESHOLD = 200; // basis points export const DEFAULT_SLIPPAGE = 25; // 0.25% ``` -------------------------------- ### Vercel configuration for /widget rewrites Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/10-demo-app.md Configures Vercel to serve all routes under `/widget/*` from the app root, preserving query strings for shareable URLs. ```json { "trailingSlash": false, "rewrites": [ { "source": "/widget/:path*", "destination": "/:path*" } ] } ``` -------------------------------- ### useEnsoToken hook implementation (partial) Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Hook that fetches token data, optionally for multiple addresses. Accepts an array of addresses to batch-fetch. The full implementation is not shown; only the function signature and parameter destructuring are provided. ```tsx export const useEnsoToken = ({ address, priorityChainId, project, protocolSlug, enabled, }: { address?: Address | Address[]; priorityChainId?: SupportedChainId; protocolSlug?: string; project?: string; enabled?: boolean; }) => { ``` -------------------------------- ### themeConfig mechanics: createSystem with defaultConfig Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/configuration.md Used to build the Chakra UI system with custom themeConfig, scoping all styles to the shadow root ':host'. Overrides global CSS with fontFamily, borderRadius, shadow, and border, and sets up light/dark conditions. ```tsx const system = useMemo( () => createSystem(defaultConfig, themeConfig || {}, { cssVarsRoot: varRoot, // ":host" preflight: { scope: varRoot }, conditions: { light: `${varRoot} &, .light &` }, globalCss: { [varRoot]: { ...defaultConfig.globalCss?.html, fontFamily, borderRadius: "xl", shadow: "sm", border: "none", }, }, }), [themeConfig] ); ``` -------------------------------- ### useEnsoPrice hook implementation Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Hook that returns a useQuery for token price data. Requires an address and optional priorityChainId. Data is stale for 30 seconds and refetches every 30 seconds. Used by SwapWidget for USD estimates and BridgingFee for native ETH price. ```tsx export const useEnsoPrice = ( address: Address, priorityChainId?: SupportedChainId ) => { const chainId = usePriorityChainId(priorityChainId); return useQuery({ queryKey: ["enso-token-price", address, chainId], queryFn: () => ensoClient.getPriceData({ address, chainId }), staleTime: 1000 * 30, refetchInterval: 1000 * 30, enabled: chainId && isAddress(address), }); }; ``` -------------------------------- ### Providers graph component Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/10-demo-app.md Defines the provider hierarchy for the demo app: WagmiProvider wraps QueryClientProvider wraps RainbowKitProvider. Uses `config` from `getDefaultConfig` and a plain `new QueryClient()`. ```tsx const Providers = ({ children }: { children: React.ReactNode }) => { return ( {children} ); }; ``` -------------------------------- ### ColorModeProvider, useColorMode, useColorModeValue, ColorModeIcon, and ColorModeButton exports Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/09-ui-primitives.md Shows the ColorModeProvider that wraps ThemeProvider with attribute "class" and disableTransitionOnChange, the useColorMode hook that returns a toggleColorMode function, the useColorModeValue helper, the ColorModeIcon component rendering LuSun or LuMoon, and the ColorModeButton forwardRef component. All on the code snippet. ```tsx export interface ColorModeProviderProps extends ThemeProviderProps {} export function ColorModeProvider(props: ColorModeProviderProps) { return ; } export function useColorMode() { const { resolvedTheme, setTheme } = useTheme(); const toggleColorMode = () => { setTheme(resolvedTheme === "light" ? "dark" : "light"); }; return { colorMode: resolvedTheme, setColorMode: setTheme, toggleColorMode }; } export function useColorModeValue(light: T, dark: T) { ... } export function ColorModeIcon() { ... } // LuSun (light) | LuMoon (dark) export const ColorModeButton = React.forwardRef(...); ``` -------------------------------- ### useApproveIfNecessary hook implementation Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/05-wallet-hooks.md The hook takes tokenIn, target, and amount. It returns undefined for native ETH (ETH_ADDRESS) or when allowance is sufficient. Otherwise, it returns the write contract result with a write function that triggers the approve transaction and tracks the hash via useTxTracker. ```tsx export const useApproveIfNecessary = ( tokenIn: Address, target: Address, amount: string ): UseWriteContractReturnType & { write: () => void; } => { const allowance = useAllowance(tokenIn, target); const approveData = useApprove(tokenIn, target, amount); ... const writeApprove = useWriteContract(); const write = useCallback(() => { writeApprove.writeContract(approveData.args, { onSuccess: successCallback, }); }, [writeApprove, approveData.args, successCallback]); if (tokenIn === ETH_ADDRESS) return undefined; return +allowance < +amount ? { ...writeApprove, write } : undefined; }; ``` -------------------------------- ### Advanced SwapWidget implementation with state Source: https://github.com/ensobuild/shortcuts-widget/blob/main/widget/README.md Advanced usage with token selection state, onChange handler, and additional props like tokenIn, chainId, tokenOut, outChainId, enableShare, and indicateRoute. ```tsx import React, { useState } from "react"; import SwapWidget from "@ensofinance/shortcuts-widget"; const App = () => { const [selectedTokens, setSelectedTokens] = useState(null); const handleChange = (data) => { setSelectedTokens(data); console.log("Widget selection changed:", data); }; return (
); }; export default App; ``` -------------------------------- ### useEnsoToken Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Hook to fetch token data from the Enso SDK, with support for batch fetching and project/protocol filtering. ```APIDOC ## useEnsoToken ### Description Fetches token data from the Enso SDK, optionally for a specific project or protocol. Accepts a single address or an array of addresses for batch fetching. Returns tokens with metadata and static chain token fallback. ### Method Hook ### Endpoint `useEnsoToken({ address, priorityChainId, project, protocolSlug, enabled })` ### Parameters #### Parameters - **address** (`Address | Address[]`) - Optional - Token address(es). Accepts an array to batch-fetch. - **priorityChainId** (`SupportedChainId`) - Optional - Chain context. Defaults to `usePriorityChainId()`. - **project** (`string`) - Optional - Enso project id; when set, returns the project's tokens. - **protocolSlug** (`string`) - Optional - Filters token data by protocol slug. - **enabled** (`boolean`) - Optional - Whether the underlying query runs. Defaults to `Boolean(address || project || protocolSlug)`. ### Returns Returns `{ tokens: Token[], isLoading }`. `tokens` merges SDK results (`includeMetadata: true`) with the static chain token list for logo/name fallback; addresses are lowercased and wrapped as `Address`; `underlyingTokens` are mapped similarly. If the SDK returns no tokens, falls back to the static list match. ### Example — with an array of addresses ```tsx const { tokens, isLoading } = useEnsoToken({ address: ["0xa0b8...48", "0x2260...c599"], priorityChainId: SupportedChainId.MAINNET, enabled: true, }); // tokens[i].address, tokens[i].decimals, tokens[i].logoURI, tokens[i].underlyingTokens ``` ``` -------------------------------- ### Widget Component Props Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/configuration.md Configuration options for the Widget component. All settings are passed as React props. ```APIDOC ## Widget Component Props ### Description Configure the Enso Shortcuts Widget by passing props to the `Widget` component (default import). All configuration is done through React props; there are no config files or global runtime options. ### Props | Prop | Type | Required | Default | Description | |---|---|---|---|---| | `apiKey` | `string` | **yes** | — | Enso API key. Missing → `alert("Provide Enso API key to the widget")`, client never initialized. | | `baseUrl` | `string` | no | SDK default | Enso API base URL override (only forwarded when truthy). | | `themeConfig` | `SystemConfig` (from `@chakra-ui/react`) | no | `{}` | Chakra UI v3 system config merged via `createSystem(defaultConfig, themeConfig || {}, {…})` — see below. | | `fontFamily` | `string` | no | Chakra default | Font stack applied on the `:host` global CSS. | | `chainId` | `number` | no | wagmi account chain | Obligates the input chain; persisted into store key `obligatedChainId`, wallet `switchChain` follows it. | | `outChainId` | `number` | no | `chainId` | Output chain; persisted into store key `tokenOutChainId`. | | `outProject` | `string` | no | — | Restricts output token selection to this Enso project. | | `tokenIn` | `Address` | no | native ETH (chain-dependent) | Pre-selected input token (lowercased internally). | | `tokenOut` | `Address` | no | — | Pre-selected output token (lowercased internally). | | `inTokens` | `{ exclude: Address[] }` | no | — | Input token exclusions; also consulted when deciding the native default. | | `outTokens` | `{ include: Address[]; exclude: Address[] }` | no | — | Output token restrictions (include list or exclusions). | | `inProjects` / `outProjects` | `ProjectFilter` = `{ include: string[]; exclude: string[] }` | no | — | Protocol/project filters per side. | | `referralCode` | `string` | no | — | 16-byte string; enables on-chain request tracking (sent in router params). | | `fee` | `{ fee: number; feeReceiver: Address }` | no | — | Integrator fee: basis points + receiver address. | | `enableShare` | `boolean` | no | `false` | Shows the "Share" clipboard control copying `window.location.href`. | | `obligateSelection` | `boolean` | no | `false` | Locks token selection once chosen. | | `rotateObligated` | `boolean \| ObligatedToken` | no | `ObligatedToken.TokenOut` when obligated | Shows the rotation arrow; chooses obligated side. | | `indicateRoute` | `boolean` | no | `false` | Renders the routing indicator. | | `adaptive` | `boolean` | no | `false` | Container-adaptive width (`{ base: "100%", md: "450px" }`). | | `notificationPlacement` | `Placement` | no | toaster default `"bottom-end"` | Toast placement, one of `top-start \| top \| top-end \| bottom-start \| bottom \| bottom-end`. | | `onChange` | `(newState: WidgetState) => void` | no | — | Fired on selection/route changes with `{ tokenIn, tokenOut, chainId, outChainId }`. | | `onSuccess` | `(hash: string, details?: SuccessDetails) => void` | no | — | Fired after a successful send with tx hash and details. | ### themeConfig mechanics `Widget` builds the Chakra system with (`widget/index.tsx:104-119`): ```tsx const system = useMemo( () => createSystem(defaultConfig, themeConfig || {}, { cssVarsRoot: varRoot, // ":host" preflight: { scope: varRoot }, conditions: { light: `${varRoot} &, .light &` }, globalCss: { [varRoot]: { ...defaultConfig.globalCss?.html, fontFamily, borderRadius: "xl", shadow: "sm", border: "none", }, }, }), [themeConfig] ); ``` Everything is scoped to the shadow root `:host`; the host page styling cannot leak in, and the widget's Chakra tokens are namespaced. All background/border/text colors come from semantic tokens (`bg`, `bg.subtle`, `bg.muted`, `fg`, `fg.muted`, `border.subtle`, `border.emphasized`, …) that can be overridden through `themeConfig.semanticTokens`. ``` -------------------------------- ### Constrained cross-chain swap with callbacks and fee Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/01-widget.md Constrained cross-chain swap configuration with callbacks and fee. Uses named import, sets tokenIn/chainId/tokenOut/outChainId, and includes onChange/onSuccess handlers. Note: onChange is dispatched with { tokenIn?, tokenOut?, chainId?, outChainId? } whenever any of those change (SwapWidget.tsx:147-153). ```tsx import React from "react"; import { SwapWidget } from "@ensofinance/shortcuts-widget"; // named import also works const App = () => { const handleChange = (state) => { console.log("selection", state.chainId, state.outChainId); }; const handleSuccess = (hash, details) => { console.log("tx", hash, details?.amountIn, details?.slippage); }; return ( ); }; ``` -------------------------------- ### Widget Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/01-widget.md The default and named export of the package. A React component that renders the shortcuts widget. Refer to WidgetProps for its complete interface. ```APIDOC ## Widget ### Description The default (and named) export of the package. A React component that renders the shortcuts widget. ### Usage import Widget from 'shortcuts-widget'; // or import { Widget } from 'shortcuts-widget'; ### Props See [WidgetProps](#widgetprops). ### Behavior Notes Refer to the Behavior Notes under [WidgetProps](#widgetprops) for details on context requirements, telemetry, shadow DOM, and chain synchronization. ``` -------------------------------- ### Button component with loading state (button.tsx) Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/09-ui-primitives.md Defines ButtonProps extending ChakraButtonProps with loading and loadingText. The Button forward-ref component renders a centered spinner with children at opacity 0 when loading, or spinner plus loadingText. Disabled is forced when loading. ```tsx interface ButtonLoadingProps { loading?: boolean loadingText?: React.ReactNode } export interface ButtonProps extends ChakraButtonProps, ButtonLoadingProps {} export const Button = React.forwardRef( function Button(props, ref) { ... } ); ``` -------------------------------- ### useApprove Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/05-wallet-hooks.md A React hook that prepares an ERC-20 approve transaction. Returns a human-readable title and the transaction arguments needed for approval. ```APIDOC ## useApprove ### Description Prepares an ERC-20 approve transaction for a given token, spender, and amount. Returns a human-readable title and the transaction arguments. ### Parameters - `token` (Address) - Required - Token to grant spending allowance on. - `target` (Address) - Required - Spender to approve (e.g., router/spender from `useEnsoApprove`). - `amount` (string) - Required - Raw approve amount. ### Returns - `{ title: string, args: { chainId, address, abi, functionName: "approve", args: [target, amount] } }` - An object containing a human-readable transaction description and the transaction arguments. ``` -------------------------------- ### useEnsoApprove hook for token approval check Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Returns a useQuery result (UseQueryResult). The query is disabled for native tokens (== ETH_ADDRESS), zero amounts, or invalid addresses, so data stays undefined in those cases. SwapWidget feeds approveData.data?.spender into useApproveIfNecessary. ```tsx export const useEnsoApprove = (tokenAddress: Address, amount: string) => { const { address } = useAccount(); const chainId = usePriorityChainId(); const isNative = isAddress(tokenAddress) && isAddressEqual(tokenAddress, ETH_ADDRESS); return useQuery({ queryKey: ["enso-approval", tokenAddress, chainId, address, amount], queryFn: () => ensoClient.getApprovalData({ fromAddress: address, tokenAddress, chainId, amount, }), enabled: !isNative && +amount > 0 && isAddress(address) && isAddress(tokenAddress), }); }; ``` -------------------------------- ### useApproveIfNecessary Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/05-wallet-hooks.md Hook that returns an approve transaction writer only when an allowance is insufficient. Returns undefined for native ETH or when allowance is sufficient. ```APIDOC ## useApproveIfNecessary ### Description Conditionally returns an approve transaction writer when the token allowance is less than the required amount. Returns `undefined` for native ETH or when no approval is needed. ### Signature ```tsx const useApproveIfNecessary = ( tokenIn: Address, target: Address, amount: string ): UseWriteContractReturnType & { write: () => void } => { ... }; ``` ### Parameters - **tokenIn** (`Address`) - Required - Input token address; returns `undefined` for native ETH. - **target** (`Address`) - Required - Spender address to approve. - **amount** (`string`) - Required - Raw amount required for the swap. ### Returns - `UseWriteContractReturnType & { write: () => void }` - When an approve transaction is required (`allowance < amount`). - `undefined` - When no approval is needed or `tokenIn` is native ETH. ### Behavior - Checks current allowance using `useAllowance`. - Uses `useApprove` to build the approve transaction data. - The returned `write` function writes the approve contract call and tracks the transaction hash via `useTxTracker`. - `SwapWidget` renders an "Approve" button only when this hook returns a truthy value. ### Example ```tsx const approve = useApproveIfNecessary( tokenIn, approveData.data?.spender, // from useEnsoApprove amountIn ); // UI: approve && ``` ``` -------------------------------- ### ClipboardRoot export Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/09-ui-primitives.md Exports ClipboardRoot as an alias to ChakraClipboard.Root. ```tsx export const ClipboardRoot = ChakraClipboard.Root; ``` -------------------------------- ### useCurrentChainList hook Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/06-common-utils.md Fetches the merged, sorted token list for a chain using useQuery. Data sources depend on the chain, with fallbacks to CoinGecko or 1inch. Tokens are deduplicated by address and sorted by symbol priority. ```tsx export const useCurrentChainList = (priorityChainId?: SupportedChainId) => { const chainId = usePriorityChainId(priorityChainId); return useQuery({ queryKey: ["tokenList", chainId], queryFn: () => getCurrentChainTokens(chainId), enabled: !!chainId, }); }; ``` -------------------------------- ### useEnsoBalances hook implementation Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/04-enso-hooks.md Hook that fetches balances for the current wallet address on a given chain. Returns a useQuery result with data from getBalances({ useEoa: true, chainId, eoaAddress }). The query is disabled when no valid wallet address is connected. ```tsx export const useEnsoBalances = (priorityChainId?: SupportedChainId) => { const { address } = useAccount(); const chainId = usePriorityChainId(priorityChainId); return useQuery({ queryKey: ["enso-balances", chainId, address], queryFn: () => ensoClient.getBalances({ useEoa: true, chainId, eoaAddress: address }), enabled: isAddress(address), }); }; ``` -------------------------------- ### Chain data maps and getChainIconUrl helper Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/02-constants.md Defines constants for chain metadata: CHAINS_ETHERSCAN, CHAINS_NATIVE_TOKENS, CHAINS_WITHOUT_NATIVE, CHAIN_ICON_OVERRIDES, and the getChainIconUrl function. CHAINS_WITHOUT_NATIVE currently includes only TEMPO and drives native-ETH router logic. getChainIconUrl returns an override URL or a Stargate CDN URL. ```tsx export const MOCK_IMAGE_URL = "..."; // constant.ts:224 (fallback token logo) export const CHAINS_ETHERSCAN: Record; // constant.ts:227 export const CHAINS_NATIVE_TOKENS: Partial>; // constant.ts:275 export const CHAINS_WITHOUT_NATIVE: Set = new Set([SupportedChainId.TEMPO]); // constant.ts:304 export const CHAIN_ICON_OVERRIDES: Partial> = { [SupportedChainId.TEMPO]: "https://icons.llamao.fi/icons/chains/rsz_tempo", }; // constant.ts:308 export const getChainIconUrl = (chainId: SupportedChainId) => CHAIN_ICON_OVERRIDES[chainId] ?? `https://icons-ckg.pages.dev/stargate-light/networks/${STARGATE_CHAIN_NAMES[chainId]}.svg`; // constant.ts:312 ``` -------------------------------- ### MAINNET_ZAP_INPUT_TOKENS constant Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/02-constants.md Array of Ethereum-mainnet token addresses allowed as zap-in inputs when the output token is a UNI-V2 LP position. Contains WETH, USDC, WBTC, USDT, beraSTONE, PEPE, DAI, UNI, cbBTC, LINK, LBTC, wstETH, rETH, USDe and ETH_ADDRESS. ```tsx export const MAINNET_ZAP_INPUT_TOKENS: Address[] = [ ... ]; // constant.ts:335 ``` -------------------------------- ### TxTracker component rendering trackers Source: https://github.com/ensobuild/shortcuts-widget/blob/main/_autodocs/api-reference/07-tx-tracker.md React component that renders one internal `Tracker` per pending transaction. Must be mounted inside the Chakra provider tree. ```tsx export const TxTracker = () => { const { txs } = useTrackingStore(); return ( <> {txs.map((tx) => ( ))} ); }; ```