aegis-swap-widget 0.2.0 → 0.3.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +120 -2
  2. package/DESIGN.md +77 -0
  3. package/README.md +249 -4
  4. package/dist/aegis-swap-widget.js +2295 -2458
  5. package/dist/components/icons.d.ts +9 -2
  6. package/dist/core.d.ts +15 -0
  7. package/dist/core.js +66 -0
  8. package/dist/errors.d.ts +1 -0
  9. package/dist/hooks/useChangeEmitter.d.ts +25 -0
  10. package/dist/hooks/useLifecycleToast.d.ts +16 -0
  11. package/dist/hooks/usePoolChangeEmitter.d.ts +1 -0
  12. package/dist/hooks/useResolvedTheme.d.ts +1 -0
  13. package/dist/hooks/useStatusChangeEmitter.d.ts +2 -0
  14. package/dist/hooks/useSubmitSwap.d.ts +10 -1
  15. package/dist/hooks/useTokenAllowance.d.ts +3 -0
  16. package/dist/hooks/useValueRefresh.d.ts +1 -0
  17. package/dist/index.d.ts +9 -7
  18. package/dist/metadata.d.ts +8 -0
  19. package/dist/permit.d.ts +7 -0
  20. package/dist/polling-BI4pZg8Z.js +1252 -0
  21. package/dist/polling.d.ts +1 -0
  22. package/dist/styles.css +1 -1
  23. package/dist/swap/authorizePermit.d.ts +30 -0
  24. package/dist/swap/executeSwapTransaction.d.ts +37 -0
  25. package/dist/swap/types.d.ts +7 -0
  26. package/dist/toast/ToastItem.d.ts +33 -0
  27. package/dist/toast/Toaster.d.ts +31 -0
  28. package/dist/toast/layout.d.ts +21 -0
  29. package/dist/toast/state.d.ts +69 -0
  30. package/dist/toast/swipe.d.ts +23 -0
  31. package/dist/toast/timer.d.ts +16 -0
  32. package/dist/toast/toast.d.ts +28 -0
  33. package/dist/toast/useDocumentVisible.d.ts +6 -0
  34. package/dist/toast/useToastTimer.d.ts +13 -0
  35. package/dist/transactionProgress.d.ts +25 -1
  36. package/dist/widget/AegisDirectSwapWidget.d.ts +17 -1
  37. package/dist/widget/AmountField.d.ts +4 -1
  38. package/dist/widget/ExecutionDetails.d.ts +1 -3
  39. package/dist/widget/NetworkSelector.d.ts +5 -2
  40. package/dist/widget/ProgressRail.d.ts +23 -0
  41. package/dist/widget/types.d.ts +81 -18
  42. package/dist/widget/useSwapController.d.ts +89 -0
  43. package/dist/widget/viewState.d.ts +1 -0
  44. package/package.json +7 -2
  45. package/dist/hooks/useScrollAnchor.d.ts +0 -12
@@ -1,6 +1,6 @@
1
1
  import type { AegisSwapMarket, AegisSwapToken } from '../config';
2
- import { type AegisSwapGlobalTokenMetadata } from '../metadata';
3
- export type TokenMetadataByAddress = Record<string, AegisSwapGlobalTokenMetadata>;
2
+ import { type TokenMetadataByAddress } from '../metadata';
3
+ export type { TokenMetadataByAddress } from '../metadata';
4
4
  export declare const TokenIconMark: import("react").NamedExoticComponent<{
5
5
  token: AegisSwapToken;
6
6
  metadataByAddress: TokenMetadataByAddress;
@@ -15,9 +15,16 @@ export declare function AegisLogoMark(): import("react").JSX.Element;
15
15
  export declare function EthereumDiamondMark({ className }: {
16
16
  className: string;
17
17
  }): import("react").JSX.Element;
18
+ export declare function BaseChainMark({ className }: {
19
+ className: string;
20
+ }): import("react").JSX.Element;
18
21
  export declare function SwapDirectionIcon(): import("react").JSX.Element;
19
22
  export declare function ExternalLinkIcon(): import("react").JSX.Element;
20
23
  export declare function CopyIcon(): import("react").JSX.Element;
21
24
  export declare function CheckIcon(): import("react").JSX.Element;
22
25
  export declare function ChevronDownIcon(): import("react").JSX.Element;
23
26
  export declare function SlidersIcon(): import("react").JSX.Element;
27
+ export declare function SpinnerIcon(): import("react").JSX.Element;
28
+ export declare function AlertCircleIcon(): import("react").JSX.Element;
29
+ export declare function InfoIcon(): import("react").JSX.Element;
30
+ export declare function CloseIcon(): import("react").JSX.Element;
package/dist/core.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export { AEGIS_DYNAMIC_FEE_FLAG, AEGIS_SWAP_CHAINS, AEGIS_SWAP_CHAIN_ID, AEGIS_SWAP_DEFAULT_FEE_BPS, AEGIS_SWAP_DEFAULT_FEE_RECIPIENT, AEGIS_SWAP_DEFAULT_METADATA_ENDPOINT, AEGIS_SWAP_DEFAULT_POOL_IDS, AEGIS_SWAP_DEFAULT_RPC_URLS, AEGIS_SWAP_HOOK, AEGIS_SWAP_MAINNET_CHAIN, AEGIS_SWAP_MAINNET_UNISWAP_V4_CONTRACTS, AEGIS_SWAP_MARKETS, AEGIS_SWAP_PERMIT2, AEGIS_SWAP_ROUTER, AEGIS_SWAP_TOKENS, AEGIS_SWAP_V4_QUOTER, UNISWAP_V4_CONTRACTS_BY_CHAIN, createAegisSwapChainConfig, createAegisSwapChains, createAegisSwapMarketsFromPools, createAegisSwapPoolMarket, createAegisSwapUniswapV4Contracts, getExplorerUrl } from './config';
2
+ export type { AegisPoolKey, AegisSwapBuiltInAssetSymbol, AegisSwapBuiltInMarketId, AegisSwapBuiltInTokenSymbol, AegisSwapChainConfig, AegisSwapChainConfigInput, AegisSwapFeeConfig, AegisSwapMarket, AegisSwapPoolConfig, AegisSwapToken, AegisSwapTokenSymbol, AegisSwapUniswapV4Contracts, AegisSwapUniswapV4ContractsInput } from './config';
3
+ export { assertUint128, buildExactInSwapTransaction, buildExactOutSwapTransaction, computePoolId, MAX_UINT128 } from './encoding';
4
+ export type { BuiltSwapTransaction, ExecutionBatch, PermitBatch, PermitDetails, SignedPermitBatch, SwapOutputFee } from './encoding';
5
+ export { fetchDirectSwapQuote, getZeroForOne, outputFeeForQuote, quoteSpendAmount, reconcileSubmitQuote, sameQuote } from './quote';
6
+ export type { DirectSwapQuote, ReconciledSubmitQuote, SwapQuoteMode } from './quote';
7
+ export { approveErc20ToPermit2, approvePermit2ToRouter, buildSignedPermitBatch, DEFAULT_PERMIT_EXPIRATION_SECONDS, MAX_UINT160, MAX_UINT256, PERMIT2_FAR_FUTURE_EXPIRATION, readPermit2RouterAllowance, SWAP_TX_DEADLINE_SECONDS } from './permit';
8
+ export { fetchGlobalTokenMetadata, getIchiIconGuess, resolveTokenIconUrl } from './metadata';
9
+ export type { AegisSwapGlobalTokenMetadata, TokenMetadataByAddress } from './metadata';
10
+ export { createSwapPublicClient, getInjectedProvider, getProviderAccount, getProviderChainId, isEip1193Provider, normalizeAccount, normalizeWalletConnection, requestProviderAccount, subscribeProvider, switchProviderChain } from './wallet';
11
+ export type { AegisSwapProviderResolver, AegisSwapWalletConnection, Eip1193Provider, ProviderChainConfig } from './wallet';
12
+ export { errorMessage, isUserRejectedError } from './errors';
13
+ export { isBusy, transactionProgressView } from './transactionProgress';
14
+ export type { AegisSwapStatusSnapshot, AegisSwapWalletPromptProgress, SubmitStatus, TransactionProgressState, TransactionProgressView } from './transactionProgress';
15
+ export { isDocumentVisible, pollUntil, retryOnError } from './polling';
package/dist/core.js ADDED
@@ -0,0 +1,66 @@
1
+ import { A as e, a as A, b as r, c as _, d as t, e as o, f as S, g as E, h as i, i as I, j as P, k as n, l as c, m as T, n as l, o as u, D as N, M as U, p, q as C, P as G, S as R, U as W, r as d, s as D, t as O, u as F, v as g, w as M, x as m, y as w, z as v, B as L, C as b, E as h, F as V, G as X, H, I as Q, J as f, K as k, L as x, N as B, O as K, Q as j, R as q, T as y, V as z, W as Y, X as Z, Y as J, Z as $, _ as aa, $ as sa, a0 as ea, a1 as Aa, a2 as ra, a3 as _a, a4 as ta, a5 as oa, a6 as Sa, a7 as Ea, a8 as ia } from "./polling-BI4pZg8Z.js";
2
+ export {
3
+ e as AEGIS_DYNAMIC_FEE_FLAG,
4
+ A as AEGIS_SWAP_CHAINS,
5
+ r as AEGIS_SWAP_CHAIN_ID,
6
+ _ as AEGIS_SWAP_DEFAULT_FEE_BPS,
7
+ t as AEGIS_SWAP_DEFAULT_FEE_RECIPIENT,
8
+ o as AEGIS_SWAP_DEFAULT_METADATA_ENDPOINT,
9
+ S as AEGIS_SWAP_DEFAULT_POOL_IDS,
10
+ E as AEGIS_SWAP_DEFAULT_RPC_URLS,
11
+ i as AEGIS_SWAP_HOOK,
12
+ I as AEGIS_SWAP_MAINNET_CHAIN,
13
+ P as AEGIS_SWAP_MAINNET_UNISWAP_V4_CONTRACTS,
14
+ n as AEGIS_SWAP_MARKETS,
15
+ c as AEGIS_SWAP_PERMIT2,
16
+ T as AEGIS_SWAP_ROUTER,
17
+ l as AEGIS_SWAP_TOKENS,
18
+ u as AEGIS_SWAP_V4_QUOTER,
19
+ N as DEFAULT_PERMIT_EXPIRATION_SECONDS,
20
+ U as MAX_UINT128,
21
+ p as MAX_UINT160,
22
+ C as MAX_UINT256,
23
+ G as PERMIT2_FAR_FUTURE_EXPIRATION,
24
+ R as SWAP_TX_DEADLINE_SECONDS,
25
+ W as UNISWAP_V4_CONTRACTS_BY_CHAIN,
26
+ d as approveErc20ToPermit2,
27
+ D as approvePermit2ToRouter,
28
+ O as assertUint128,
29
+ F as buildExactInSwapTransaction,
30
+ g as buildExactOutSwapTransaction,
31
+ M as buildSignedPermitBatch,
32
+ m as computePoolId,
33
+ w as createAegisSwapChainConfig,
34
+ v as createAegisSwapChains,
35
+ L as createAegisSwapMarketsFromPools,
36
+ b as createAegisSwapPoolMarket,
37
+ h as createAegisSwapUniswapV4Contracts,
38
+ V as createSwapPublicClient,
39
+ X as errorMessage,
40
+ H as fetchDirectSwapQuote,
41
+ Q as fetchGlobalTokenMetadata,
42
+ f as getExplorerUrl,
43
+ k as getIchiIconGuess,
44
+ x as getInjectedProvider,
45
+ B as getProviderAccount,
46
+ K as getProviderChainId,
47
+ j as getZeroForOne,
48
+ q as isBusy,
49
+ y as isDocumentVisible,
50
+ z as isEip1193Provider,
51
+ Y as isUserRejectedError,
52
+ Z as normalizeAccount,
53
+ J as normalizeWalletConnection,
54
+ $ as outputFeeForQuote,
55
+ aa as pollUntil,
56
+ sa as quoteSpendAmount,
57
+ ea as readPermit2RouterAllowance,
58
+ Aa as reconcileSubmitQuote,
59
+ ra as requestProviderAccount,
60
+ _a as resolveTokenIconUrl,
61
+ ta as retryOnError,
62
+ oa as sameQuote,
63
+ Sa as subscribeProvider,
64
+ Ea as switchProviderChain,
65
+ ia as transactionProgressView
66
+ };
package/dist/errors.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export declare function isUserRejectedError(error: unknown): boolean;
2
+ export declare const USER_REJECTED_MESSAGE = "Request rejected.";
2
3
  export declare function errorMessage(error: unknown, fallbackMessage: string): string;
@@ -0,0 +1,25 @@
1
+ type ChangeEmitterOptions<T> = {
2
+ /**
3
+ * The value the emitter starts at, so the first render emits nothing — hosts
4
+ * already know the initial value from their own props. Captured once on mount.
5
+ */
6
+ initial: T;
7
+ /** Callback name used in the contained-error warning. */
8
+ label: string;
9
+ /**
10
+ * Equality used to decide whether the value changed. Defaults to `Object.is`
11
+ * (right for primitives); pass `stableEquals` for snapshot objects rebuilt
12
+ * each render.
13
+ */
14
+ equals?: (a: T, b: T) => boolean;
15
+ };
16
+ /**
17
+ * Mirrors a derived value to a host callback, emitting only when it changes.
18
+ *
19
+ * Shared shape for the widget's "notify the host" effects: the callback lives
20
+ * in a ref so inline host arrows don't re-run the effect, the first render is
21
+ * skipped (the ref starts at `initial`), and a throwing host callback is
22
+ * contained so it can't take down the widget mid-swap.
23
+ */
24
+ export declare function useChangeEmitter<T>(callback: ((value: T) => void) | undefined, value: T, { initial, label, equals }: ChangeEmitterOptions<T>): void;
25
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { Hex } from 'viem';
2
+ import { type SubmitStatus, type TransactionProgressView } from '../transactionProgress';
3
+ /**
4
+ * Drives ONE morphing toast per swap attempt off the same progress view the
5
+ * rail renders: loading while pending/mining (label updates morph in place),
6
+ * then success or error in the same card. A retry dismisses the previous
7
+ * attempt's toast and mints a fresh one.
8
+ */
9
+ export declare function useLifecycleToast({ enabled, status, progress, txHash, explorerUrl, successDescription }: {
10
+ enabled: boolean;
11
+ status: SubmitStatus;
12
+ progress: TransactionProgressView | null;
13
+ txHash: Hex | null;
14
+ explorerUrl: string | null;
15
+ successDescription: string | null;
16
+ }): void;
@@ -0,0 +1 @@
1
+ export declare function usePoolChangeEmitter(onPoolChange: ((poolId: string) => void) | undefined, activePoolId: string | undefined): void;
@@ -1,3 +1,4 @@
1
+ /** Widget color theme. `'auto'` follows the OS `prefers-color-scheme`. */
1
2
  export type AegisSwapWidgetTheme = 'dark' | 'light' | 'auto';
2
3
  export type ResolvedThemeMode = 'dark' | 'light';
3
4
  export declare function useResolvedTheme(theme?: AegisSwapWidgetTheme): ResolvedThemeMode;
@@ -0,0 +1,2 @@
1
+ import type { AegisSwapStatusSnapshot } from '../transactionProgress';
2
+ export declare function useStatusChangeEmitter(onStatusChange: ((snapshot: AegisSwapStatusSnapshot) => void) | undefined, snapshot: AegisSwapStatusSnapshot): void;
@@ -4,7 +4,15 @@ import { type DirectSwapQuote, type SwapQuoteMode } from '../quote';
4
4
  import { type SubmitStatus } from '../transactionProgress';
5
5
  import { type Eip1193Provider } from '../wallet';
6
6
  import type { ResolvedWalletConnection } from './useWalletConnection';
7
+ /**
8
+ * ERC-20 → Permit2 approval sizing. `'exact'` approves only the current quote's
9
+ * spend; `'max'` approves an unlimited allowance so future swaps skip approval.
10
+ */
7
11
  export type AegisSwapApprovalMode = 'exact' | 'max';
12
+ /**
13
+ * Swap context attached to `onSubmitted`/`onSuccess` so hosts get
14
+ * analytics-grade data without extra wiring. Amounts are raw base units.
15
+ */
8
16
  export type AegisSwapSubmitDetails = {
9
17
  mode: SwapQuoteMode;
10
18
  inputSymbol: string;
@@ -25,7 +33,7 @@ type ApprovalProgress = {
25
33
  * fee leg selection. A confirmed approval auto-continues into the swap, so a
26
34
  * single click covers approve -> permit -> swap.
27
35
  */
28
- export declare function useSubmitSwap({ publicClient, activeChain, market, inputToken, outputToken, quoteMode, activeAmount, slippageBps, feeConfig, quote, setQuote, owner, getActiveProvider, connectWallet, setWalletChainId, readAllowance, commitAllowance, approvalMode, refreshBalances, onSubmitted, onSuccess, onError }: {
36
+ export declare function useSubmitSwap({ publicClient, activeChain, market, inputToken, outputToken, quoteMode, activeAmount, slippageBps, feeConfig, quote, setQuote, owner, getActiveProvider, connectWallet, setWalletChainId, readAllowance, commitAllowance, approvalMode, refreshBalances, refreshAllowances, onSubmitted, onSuccess, onError }: {
29
37
  publicClient: PublicClient;
30
38
  activeChain: AegisSwapChainConfig;
31
39
  market: AegisSwapMarket | null;
@@ -45,6 +53,7 @@ export declare function useSubmitSwap({ publicClient, activeChain, market, input
45
53
  commitAllowance: (owner: Address, market: AegisSwapMarket, amount: bigint) => void;
46
54
  approvalMode: AegisSwapApprovalMode;
47
55
  refreshBalances: (account: Address) => Promise<void>;
56
+ refreshAllowances: (owner: Address, market: AegisSwapMarket) => Promise<void>;
48
57
  onSubmitted?: (hash: Hex, swap?: AegisSwapSubmitDetails) => void;
49
58
  onSuccess?: (result: {
50
59
  hash: Hex;
@@ -19,6 +19,9 @@ export declare function useTokenAllowance({ publicClient, owner, market, inputTo
19
19
  approvalRequired: boolean;
20
20
  authorizationCheckPending: boolean;
21
21
  authorizationRequired: boolean;
22
+ /** Whether the prompt plan includes a Permit2 authorization (ungated by the approval). */
23
+ authorizationPromptExpected: boolean;
22
24
  readAllowance: (owner: Address, market: AegisSwapMarket) => Promise<bigint>;
23
25
  commitAllowance: (owner: Address, market: AegisSwapMarket, amount: bigint) => void;
26
+ refreshAllowances: (owner: Address, market: AegisSwapMarket) => Promise<void>;
24
27
  };
@@ -0,0 +1 @@
1
+ export declare function useValueRefresh(value: string, enabled: boolean): boolean;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import './styles.css';
2
2
  export { AegisDirectSwapWidget, AegisSwapWidget, default } from './widget/AegisDirectSwapWidget';
3
- export type { AegisDirectSwapWidgetProps, AegisSwapWidgetDirection, AegisSwapWidgetProps, AegisSwapWidgetStyle } from './widget/types';
4
- export { AEGIS_SWAP_CHAINS, AEGIS_SWAP_CHAIN_ID, AEGIS_SWAP_DEFAULT_FEE_BPS, AEGIS_SWAP_DEFAULT_FEE_RECIPIENT, AEGIS_SWAP_DEFAULT_METADATA_ENDPOINT, AEGIS_SWAP_DEFAULT_POOL_IDS, AEGIS_SWAP_DEFAULT_RPC_URLS, AEGIS_DYNAMIC_FEE_FLAG, AEGIS_SWAP_HOOK, AEGIS_SWAP_MARKETS, AEGIS_SWAP_MAINNET_CHAIN, AEGIS_SWAP_MAINNET_UNISWAP_V4_CONTRACTS, AEGIS_SWAP_PERMIT2, AEGIS_SWAP_ROUTER, AEGIS_SWAP_TOKENS, AEGIS_SWAP_V4_QUOTER, UNISWAP_V4_CONTRACTS_BY_CHAIN, createAegisSwapChainConfig, createAegisSwapChains, createAegisSwapPoolMarket, createAegisSwapMarketsFromPools, createAegisSwapUniswapV4Contracts } from './config';
5
- export type { AegisPoolKey, AegisSwapBuiltInAssetSymbol, AegisSwapBuiltInMarketId, AegisSwapBuiltInTokenSymbol, AegisSwapChainConfig, AegisSwapChainConfigInput, AegisSwapMarket, AegisSwapPoolConfig, AegisSwapToken, AegisSwapTokenSymbol, AegisSwapUniswapV4Contracts, AegisSwapUniswapV4ContractsInput } from './config';
6
- export { fetchGlobalTokenMetadata, getIchiIconGuess } from './metadata';
7
- export type { AegisSwapGlobalTokenMetadata } from './metadata';
8
- export type { DirectSwapQuote, SwapQuoteMode } from './quote';
3
+ export type { AegisDirectSwapWidgetProps, AegisSwapNetworkIcon, AegisSwapNetworkOption, AegisSwapStatusSurface, AegisSwapWidgetDirection, AegisSwapWidgetProps, AegisSwapWidgetStyle } from './widget/types';
4
+ export { AegisSwapProgressRail } from './widget/ProgressRail';
5
+ export type { AegisSwapProgressRailProps } from './widget/ProgressRail';
6
+ export { AegisSwapToaster } from './toast/Toaster';
7
+ export type { AegisSwapToasterProps } from './toast/Toaster';
8
+ export { aegisToast } from './toast/toast';
9
+ export type { AegisToastPromiseMessage, AegisToastPromiseMessages } from './toast/toast';
10
+ export type { AegisToastAction, AegisToastOptions, AegisToastPosition, AegisToastType } from './toast/state';
9
11
  export type { AegisSwapWidgetTheme } from './hooks/useResolvedTheme';
10
12
  export type { AegisSwapApprovalMode, AegisSwapSubmitDetails } from './hooks/useSubmitSwap';
11
- export type { AegisSwapProviderResolver, AegisSwapWalletConnection, Eip1193Provider } from './wallet';
13
+ export * from './core';
@@ -1,4 +1,5 @@
1
1
  import { type Address } from 'viem';
2
+ import type { AegisSwapToken } from './config';
2
3
  export type AegisSwapGlobalTokenMetadata = {
3
4
  chainId: number | null;
4
5
  address: string | null;
@@ -9,6 +10,13 @@ export type AegisSwapGlobalTokenMetadata = {
9
10
  iconURL: string | null;
10
11
  };
11
12
  export declare function getIchiIconGuess(symbol: string | null | undefined): string | null;
13
+ export type TokenMetadataByAddress = Record<string, AegisSwapGlobalTokenMetadata>;
14
+ /**
15
+ * Canonical icon-source order for a token: explicit config URL, the metadata
16
+ * service, then the ichi naming guess. Public so hosts rendering their own
17
+ * token marks resolve identically to the widget.
18
+ */
19
+ export declare function resolveTokenIconUrl(token: AegisSwapToken, metadataByAddress: TokenMetadataByAddress): string | null;
12
20
  export declare function fetchGlobalTokenMetadata(args: {
13
21
  endpoint: string;
14
22
  chainId: number;
package/dist/permit.d.ts CHANGED
@@ -43,6 +43,13 @@ export declare function buildSignedPermitBatch(args: {
43
43
  router: Address;
44
44
  token: Address;
45
45
  amount: bigint;
46
+ /**
47
+ * 'max' signs a MAX_UINT160 permit (still expiring in 30 minutes) so quick
48
+ * follow-up swaps reuse it instead of prompting for a new signature each
49
+ * time — Permit2 decrements exact-sized permits to zero on transfer.
50
+ * Defaults to 'exact'.
51
+ */
52
+ sizing?: 'exact' | 'max';
46
53
  /** Pre-started readPermit2RouterAllowance result to overlap with other RPC work. */
47
54
  allowanceRead?: ReturnType<typeof readPermit2RouterAllowance>;
48
55
  }): Promise<SignedPermitBatch | null>;