### 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) => (
))}
>
);
};
```