@liberfi.io/ui-trade 0.1.1 → 0.1.2
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/README.md +250 -5
- package/dist/index.d.mts +216 -3
- package/dist/index.d.ts +216 -3
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _liberfi_io_types from '@liberfi.io/types';
|
|
2
|
+
import { Chain, API, Token, Portfolio } from '@liberfi.io/types';
|
|
2
3
|
import { WalletAdapter } from '@liberfi.io/wallet-connector';
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Input parameters for the `swap()` function returned by {@link useSwap}.
|
|
@@ -50,6 +52,15 @@ interface UseSwapOptions {
|
|
|
50
52
|
/** Called when an error occurs at any phase of the swap flow. */
|
|
51
53
|
onError?: (error: Error, phase: SwapPhase) => void;
|
|
52
54
|
}
|
|
55
|
+
/** Options for the {@link useSwapRoutePolling} hook. */
|
|
56
|
+
interface UseSwapRoutePollingOptions {
|
|
57
|
+
/** Polling interval in ms. Defaults to 12000 (12s). */
|
|
58
|
+
interval?: number;
|
|
59
|
+
/** Pause polling (e.g. during swap execution). */
|
|
60
|
+
paused?: boolean;
|
|
61
|
+
/** Called when a route fetch fails. */
|
|
62
|
+
onError?: (error: Error) => void;
|
|
63
|
+
}
|
|
53
64
|
/** Confirmation status of a tracked transaction. */
|
|
54
65
|
type TxConfirmationStatus = "idle" | "pending" | "confirmed" | "failed";
|
|
55
66
|
/** Options for the {@link useTxConfirmation} hook. */
|
|
@@ -77,6 +88,21 @@ declare function useSwap(options?: UseSwapOptions): {
|
|
|
77
88
|
isSwapping: boolean;
|
|
78
89
|
};
|
|
79
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Hook that polls for swap route quotes at a configurable interval.
|
|
93
|
+
*
|
|
94
|
+
* Built on top of `useSwapRouteQuery` (TanStack Query) — automatically
|
|
95
|
+
* deduplicates requests, caches results, and invalidates when params change.
|
|
96
|
+
*
|
|
97
|
+
* Polling pauses when `paused` is true (e.g. during swap execution) or
|
|
98
|
+
* when required params are missing.
|
|
99
|
+
*/
|
|
100
|
+
declare function useSwapRoutePolling(params: Partial<API.SwapParams>, options?: UseSwapRoutePollingOptions): {
|
|
101
|
+
route: _liberfi_io_types.SwapRoute | undefined;
|
|
102
|
+
isRouting: boolean;
|
|
103
|
+
error: Error | null;
|
|
104
|
+
};
|
|
105
|
+
|
|
80
106
|
interface TrackedTx {
|
|
81
107
|
chain: Chain;
|
|
82
108
|
txHash: string;
|
|
@@ -104,6 +130,193 @@ declare function useTxConfirmation(options?: UseTxConfirmationOptions): {
|
|
|
104
130
|
transactions: Map<string, TrackedTx>;
|
|
105
131
|
};
|
|
106
132
|
|
|
133
|
+
/** Parameters for {@link useSwapScript}. */
|
|
134
|
+
interface UseSwapScriptParams {
|
|
135
|
+
/** Target chain */
|
|
136
|
+
chain: Chain;
|
|
137
|
+
/** Initial from-token address */
|
|
138
|
+
from?: string;
|
|
139
|
+
/** Initial to-token address */
|
|
140
|
+
to?: string;
|
|
141
|
+
/** Called when the swap completes (success or failure) */
|
|
142
|
+
onComplete?: (result: {
|
|
143
|
+
success: boolean;
|
|
144
|
+
txHash?: string;
|
|
145
|
+
}) => void;
|
|
146
|
+
}
|
|
147
|
+
/** Return value of {@link useSwapScript}. */
|
|
148
|
+
interface UseSwapScriptResult {
|
|
149
|
+
/** Currently selected from-token address */
|
|
150
|
+
fromTokenAddress: string;
|
|
151
|
+
/** Currently selected to-token address */
|
|
152
|
+
toTokenAddress: string;
|
|
153
|
+
/** Update the from-token address */
|
|
154
|
+
setFromTokenAddress: (addr: string) => void;
|
|
155
|
+
/** Update the to-token address */
|
|
156
|
+
setToTokenAddress: (addr: string) => void;
|
|
157
|
+
/** From-token metadata (name, symbol, decimals, price, ...) */
|
|
158
|
+
fromToken: Token | null;
|
|
159
|
+
/** To-token metadata */
|
|
160
|
+
toToken: Token | null;
|
|
161
|
+
/** User's from-token balance */
|
|
162
|
+
fromBalance: Portfolio | null;
|
|
163
|
+
/** User's to-token balance */
|
|
164
|
+
toBalance: Portfolio | null;
|
|
165
|
+
/** Human-readable amount entered by the user */
|
|
166
|
+
amount: string | undefined;
|
|
167
|
+
/** Update the amount */
|
|
168
|
+
setAmount: (v: string | undefined) => void;
|
|
169
|
+
/** Set amount to half of the from-token balance */
|
|
170
|
+
setHalfAmount: () => void;
|
|
171
|
+
/** Set amount to the full from-token balance */
|
|
172
|
+
setMaxAmount: () => void;
|
|
173
|
+
/** Amount converted to smallest unit using token decimals */
|
|
174
|
+
amountInDecimals: string | undefined;
|
|
175
|
+
/** Amount converted to USD using token price */
|
|
176
|
+
amountInUsd: string | undefined;
|
|
177
|
+
/** Formatted output amount from the route (human-readable) */
|
|
178
|
+
outputAmount: string | undefined;
|
|
179
|
+
/** Output amount converted to USD using to-token price */
|
|
180
|
+
outputAmountInUsd: string | undefined;
|
|
181
|
+
/** Current swap route quote */
|
|
182
|
+
route: API.SwapRoute | undefined;
|
|
183
|
+
/** Whether a route is currently being fetched */
|
|
184
|
+
isRouting: boolean;
|
|
185
|
+
/** Route fetch error, if any */
|
|
186
|
+
routeError: Error | null;
|
|
187
|
+
/** Execute the swap (route -> sign -> send) */
|
|
188
|
+
swap: () => Promise<void>;
|
|
189
|
+
/** Whether a swap is currently in progress */
|
|
190
|
+
isSwapping: boolean;
|
|
191
|
+
/** Confirmation status of the most recent transaction */
|
|
192
|
+
txStatus: TxConfirmationStatus;
|
|
193
|
+
/** Whether initial data (tokens, balances) is still loading */
|
|
194
|
+
isLoading: boolean;
|
|
195
|
+
}
|
|
196
|
+
/** Props for {@link SwapWidget}. */
|
|
197
|
+
interface SwapWidgetProps {
|
|
198
|
+
/** Target chain */
|
|
199
|
+
chain: Chain;
|
|
200
|
+
/** Initial from-token address */
|
|
201
|
+
from?: string;
|
|
202
|
+
/** Initial to-token address */
|
|
203
|
+
to?: string;
|
|
204
|
+
/** Called when the swap completes (success or failure) */
|
|
205
|
+
onComplete?: (result: {
|
|
206
|
+
success: boolean;
|
|
207
|
+
txHash?: string;
|
|
208
|
+
}) => void;
|
|
209
|
+
/** External style customization */
|
|
210
|
+
className?: string;
|
|
211
|
+
}
|
|
212
|
+
/** Props for {@link SwapUI}. */
|
|
213
|
+
interface SwapUIProps {
|
|
214
|
+
/** From-token metadata */
|
|
215
|
+
fromToken: Token | null;
|
|
216
|
+
/** To-token metadata */
|
|
217
|
+
toToken: Token | null;
|
|
218
|
+
/** User's from-token balance */
|
|
219
|
+
fromBalance: Portfolio | null;
|
|
220
|
+
/** User's to-token balance */
|
|
221
|
+
toBalance: Portfolio | null;
|
|
222
|
+
/** Human-readable amount */
|
|
223
|
+
amount: string | undefined;
|
|
224
|
+
/** Amount in USD */
|
|
225
|
+
amountInUsd: string | undefined;
|
|
226
|
+
/** Amount change handler */
|
|
227
|
+
onAmountChange: (v: string | undefined) => void;
|
|
228
|
+
/** Set amount to half of the from-token balance */
|
|
229
|
+
onHalfAmount?: () => void;
|
|
230
|
+
/** Set amount to the full from-token balance */
|
|
231
|
+
onMaxAmount?: () => void;
|
|
232
|
+
/** Formatted output amount (human-readable) */
|
|
233
|
+
outputAmount: string | undefined;
|
|
234
|
+
/** Output amount in USD */
|
|
235
|
+
outputAmountInUsd: string | undefined;
|
|
236
|
+
/** From-token selection handler */
|
|
237
|
+
onFromTokenSelect: (addr: string) => void;
|
|
238
|
+
/** To-token selection handler */
|
|
239
|
+
onToTokenSelect: (addr: string) => void;
|
|
240
|
+
/** Current swap route quote */
|
|
241
|
+
route: API.SwapRoute | undefined;
|
|
242
|
+
/** Whether a route is being fetched */
|
|
243
|
+
isRouting: boolean;
|
|
244
|
+
/** Route error */
|
|
245
|
+
routeError: Error | null;
|
|
246
|
+
/** Open preview modal before swap */
|
|
247
|
+
onPreview: () => void;
|
|
248
|
+
/** Whether a swap is in progress */
|
|
249
|
+
isSwapping: boolean;
|
|
250
|
+
/** External style customization */
|
|
251
|
+
className?: string;
|
|
252
|
+
}
|
|
253
|
+
/** Props for {@link SwapPreviewModal}. */
|
|
254
|
+
interface SwapPreviewModalProps {
|
|
255
|
+
/** Whether the modal is open */
|
|
256
|
+
isOpen: boolean;
|
|
257
|
+
/** Modal open/close change handler */
|
|
258
|
+
onOpenChange: (isOpen: boolean) => void;
|
|
259
|
+
/** From-token metadata */
|
|
260
|
+
fromToken: Token | null;
|
|
261
|
+
/** To-token metadata */
|
|
262
|
+
toToken: Token | null;
|
|
263
|
+
/** User's from-token balance */
|
|
264
|
+
fromBalance: Portfolio | null;
|
|
265
|
+
/** Input amount (human-readable) */
|
|
266
|
+
inputAmount: string | undefined;
|
|
267
|
+
/** Input amount in USD */
|
|
268
|
+
inputAmountInUsd: string | undefined;
|
|
269
|
+
/** Output amount (human-readable) */
|
|
270
|
+
outputAmount: string | undefined;
|
|
271
|
+
/** Output amount in USD */
|
|
272
|
+
outputAmountInUsd: string | undefined;
|
|
273
|
+
/** Current swap route */
|
|
274
|
+
route: API.SwapRoute | undefined;
|
|
275
|
+
/** Whether a route is being fetched */
|
|
276
|
+
isRouting: boolean;
|
|
277
|
+
/** Route error */
|
|
278
|
+
routeError: Error | null;
|
|
279
|
+
/** Confirm swap handler */
|
|
280
|
+
onConfirm: () => void;
|
|
281
|
+
/** Whether a swap is in progress */
|
|
282
|
+
isSwapping: boolean;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Script hook that encapsulates all data fetching and state management
|
|
287
|
+
* for the swap form.
|
|
288
|
+
*
|
|
289
|
+
* Pure TypeScript — no JSX, no UI imports.
|
|
290
|
+
*/
|
|
291
|
+
declare function useSwapScript(params: UseSwapScriptParams): UseSwapScriptResult;
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Swap widget — thin orchestration layer.
|
|
295
|
+
*
|
|
296
|
+
* Calls `useSwapScript` to fetch all data, renders `SwapUI` for the form
|
|
297
|
+
* and `SwapPreviewModal` for pre-swap confirmation.
|
|
298
|
+
*
|
|
299
|
+
* For custom UIs, use `useSwapScript` directly with your own presentation.
|
|
300
|
+
*/
|
|
301
|
+
declare function SwapWidget({ chain, from, to, onComplete, className, }: SwapWidgetProps): react_jsx_runtime.JSX.Element;
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Pure presentational component for the swap form.
|
|
305
|
+
*
|
|
306
|
+
* Receives all data and callbacks via props — no API calls, no subscriptions.
|
|
307
|
+
* Consumers can replace this component entirely while reusing `useSwapScript`.
|
|
308
|
+
*/
|
|
309
|
+
declare function SwapUI({ fromToken, toToken, fromBalance, toBalance, amount, amountInUsd, onAmountChange, onHalfAmount, onMaxAmount, outputAmount, outputAmountInUsd, onFromTokenSelect, onToTokenSelect, route, isRouting, routeError, onPreview, isSwapping, className, }: SwapUIProps): react_jsx_runtime.JSX.Element;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Modal that previews swap details before confirmation.
|
|
313
|
+
*
|
|
314
|
+
* Pure presentational — all data and callbacks received via props.
|
|
315
|
+
* Shows from/to token cards, expandable route plan details,
|
|
316
|
+
* and a confirm button.
|
|
317
|
+
*/
|
|
318
|
+
declare function SwapPreviewModal({ isOpen, onOpenChange, fromToken, toToken, fromBalance, inputAmount, inputAmountInUsd, outputAmount, outputAmountInUsd, route, isRouting, routeError, onConfirm, isSwapping, }: SwapPreviewModalProps): react_jsx_runtime.JSX.Element;
|
|
319
|
+
|
|
107
320
|
declare global {
|
|
108
321
|
interface Window {
|
|
109
322
|
__LIBERFI_VERSION__?: {
|
|
@@ -111,6 +324,6 @@ declare global {
|
|
|
111
324
|
};
|
|
112
325
|
}
|
|
113
326
|
}
|
|
114
|
-
declare const _default: "0.1.
|
|
327
|
+
declare const _default: "0.1.2";
|
|
115
328
|
|
|
116
|
-
export { type SwapInput, type SwapPhase, type SwapResult, type TxConfirmationStatus, type UseSwapOptions, type UseTxConfirmationOptions, useSwap, useTxConfirmation, _default as version };
|
|
329
|
+
export { type SwapInput, type SwapPhase, SwapPreviewModal, type SwapPreviewModalProps, type SwapResult, SwapUI, type SwapUIProps, SwapWidget, type SwapWidgetProps, type TxConfirmationStatus, type UseSwapOptions, type UseSwapRoutePollingOptions, type UseSwapScriptParams, type UseSwapScriptResult, type UseTxConfirmationOptions, useSwap, useSwapRoutePolling, useSwapScript, useTxConfirmation, _default as version };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
'use strict';var react$1=require('react'),react=require('@liberfi.io/react'),types=require('@liberfi.io/types');function I(p){let o=atob(p),i=new Uint8Array(o.length);for(let s=0;s<o.length;s++)i[s]=o.charCodeAt(s);return i}function R(p){let o="";for(let i=0;i<p.length;i++)o+=String.fromCharCode(p[i]);return btoa(o)}function k(p){let{client:o}=react.useDexClient(),[i,s]=react$1.useState(false),u=react$1.useRef(p);u.current=p;let l=react$1.useCallback(async w=>{let{wallet:d,chain:m,...t}=w;s(true);try{let e;try{e=await o.swapRoute({chain:m,userAddress:d.address,input:t.input,output:t.output,mode:t.mode??types.API.SwapMode.EXACT_IN,amount:t.amount,slippage:t.slippage,priorityFee:t.priorityFee,tipFee:t.tipFee,isAntiMev:t.isAntiMev,permit:t.permit,deadline:t.deadline});}catch(n){let f=n instanceof Error?n:new Error(String(n));throw u.current?.onError?.(f,"route"),f}let a;try{let n=I(e.serializedTx);a=await d.signTransaction(n);}catch(n){let f=n instanceof Error?n:new Error(String(n));throw u.current?.onError?.(f,"sign"),f}let r;try{let n=R(a);r=await o.sendTx({chain:m,serializedTx:n});}catch(n){let f=n instanceof Error?n:new Error(String(n));throw u.current?.onError?.(f,"send"),f}let c={txHash:r.txHash,extra:r.extra};return u.current?.onSubmitted?.(c),c}finally{s(false);}},[o]);return react$1.useMemo(()=>({swap:l,isSwapping:i}),[l,i])}var F=6e4;function V(p){let{client:o}=react.useDexClient(),[i,s]=react$1.useState(()=>new Map),u=react$1.useRef(p);u.current=p;let l=react$1.useCallback((t,e)=>{s(a=>{let r=a.get(t);if(!r||r.status===e)return a;let c=new Map(a);return c.set(t,{...r,status:e}),c});},[]),w=react$1.useCallback((t,e)=>{s(r=>{if(r.has(e))return r;let c=new Map(r);return c.set(e,{chain:t,txHash:e,status:"pending"}),c});let a=u.current?.timeout??F;o.checkTxSuccess(t,e,a).then(r=>{if(r)l(e,"confirmed"),u.current?.onConfirmed?.(e);else {let c=new Error("Transaction failed on-chain");l(e,"failed"),u.current?.onFailed?.(e,c);}}).catch(r=>{let c=r instanceof Error?r:new Error(String(r));l(e,"failed"),u.current?.onFailed?.(e,c);});},[o,l]),d=react$1.useCallback(t=>{s(e=>{if(!e.has(t))return e;let a=new Map(e);return a.delete(t),a});},[]),m=react$1.useCallback(()=>{s(t=>t.size===0?t:new Map);},[]);return react$1.useMemo(()=>({track:w,clear:d,clearAll:m,transactions:i}),[w,d,m,i])}typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-trade"]="0.1.1");var U="0.1.1";exports.useSwap=k;exports.useTxConfirmation=V;exports.version=U;//# sourceMappingURL=index.js.map
|
|
1
|
+
'use strict';var react$1=require('react'),react=require('@liberfi.io/react'),types=require('@liberfi.io/types'),walletConnector=require('@liberfi.io/wallet-connector'),ui=require('@liberfi.io/ui'),jsxRuntime=require('react/jsx-runtime');function Fe(e){let t=atob(e),u=new Uint8Array(t.length);for(let i=0;i<t.length;i++)u[i]=t.charCodeAt(i);return u}function Me(e){let t="";for(let u=0;u<e.length;u++)t+=String.fromCharCode(e[u]);return btoa(t)}function ie(e){let{client:t}=react.useDexClient(),[u,i]=react$1.useState(false),a=react$1.useRef(e);a.current=e;let n=react$1.useCallback(async d=>{let{wallet:m,chain:p,...r}=d;i(true);try{let l;try{l=await t.swapRoute({chain:p,userAddress:m.address,input:r.input,output:r.output,mode:r.mode??types.API.SwapMode.EXACT_IN,amount:r.amount,slippage:r.slippage,priorityFee:r.priorityFee,tipFee:r.tipFee,isAntiMev:r.isAntiMev,permit:r.permit,deadline:r.deadline});}catch(s){let S=s instanceof Error?s:new Error(String(s));throw a.current?.onError?.(S,"route"),S}let h;try{let s=Fe(l.serializedTx);h=await m.signTransaction(s);}catch(s){let S=s instanceof Error?s:new Error(String(s));throw a.current?.onError?.(S,"sign"),S}let f;try{let s=Me(h);f=await t.sendTx({chain:p,serializedTx:s});}catch(s){let S=s instanceof Error?s:new Error(String(s));throw a.current?.onError?.(S,"send"),S}let w={txHash:f.txHash,extra:f.extra};return a.current?.onSubmitted?.(w),w}finally{i(false);}},[t]);return react$1.useMemo(()=>({swap:n,isSwapping:u}),[n,u])}var Le=12e3;function ae(e,t){let u=t?.interval??Le,i=t?.paused??false,a=react$1.useRef(t);a.current=t;let d=!!e.chain&&!!e.userAddress&&!!e.input&&!!e.output&&!!e.amount&&!i,m=react.useSwapRouteQuery(e,{enabled:d,refetchInterval:d?u:false,retry:false});return react$1.useEffect(()=>{m.error&&a.current?.onError?.(m.error);},[m.error]),react$1.useMemo(()=>({route:m.data,isRouting:m.isFetching,error:m.error}),[m.data,m.isFetching,m.error])}var je=6e4;function ue(e){let{client:t}=react.useDexClient(),[u,i]=react$1.useState(()=>new Map),a=react$1.useRef(e);a.current=e;let n=react$1.useCallback((r,l)=>{i(h=>{let f=h.get(r);if(!f||f.status===l)return h;let w=new Map(h);return w.set(r,{...f,status:l}),w});},[]),d=react$1.useCallback((r,l)=>{i(f=>{if(f.has(l))return f;let w=new Map(f);return w.set(l,{chain:r,txHash:l,status:"pending"}),w});let h=a.current?.timeout??je;t.checkTxSuccess(r,l,h).then(f=>{if(f)n(l,"confirmed"),a.current?.onConfirmed?.(l);else {let w=new Error("Transaction failed on-chain");n(l,"failed"),a.current?.onFailed?.(l,w);}}).catch(f=>{let w=f instanceof Error?f:new Error(String(f));n(l,"failed"),a.current?.onFailed?.(l,w);});},[t,n]),m=react$1.useCallback(r=>{i(l=>{if(!l.has(r))return l;let h=new Map(l);return h.delete(r),h});},[]),p=react$1.useCallback(()=>{i(r=>r.size===0?r:new Map);},[]);return react$1.useMemo(()=>({track:d,clear:m,clearAll:p,transactions:u}),[d,m,p,u])}var Qe=new Set([types.Chain.SOLANA,types.Chain.SOLANA_TESTNET,types.Chain.SOLANA_DEVNET]);function Ke(e){return Qe.has(e)?types.ChainNamespace.SOLANA:types.ChainNamespace.EVM}var Xe=1e4,qe=15e3;function Ge(e,t){if(e.length===0)return;let i=e[e.length-1].outputAmount;if(!i||i==="0")return "0";let a=i.padStart(t+1,"0"),n=a.slice(0,a.length-t)||"0",m=a.slice(a.length-t).replace(/0+$/,"");return m?`${n}.${m}`:n}function j(e){let{chain:t}=e,u=walletConnector.useWallets(),i=Ke(t),a=react$1.useMemo(()=>u.find(o=>o.chainNamespace===i&&o.isConnected),[u,i]),n=a?.address??"",[d,m]=react$1.useState(e.from??""),[p,r]=react$1.useState(e.to??""),l=react$1.useRef(e.from),h=react$1.useRef(e.to);react$1.useEffect(()=>{e.from!==l.current&&(l.current=e.from,e.from&&m(e.from));},[e.from]),react$1.useEffect(()=>{e.to!==h.current&&(h.current=e.to,e.to&&r(e.to));},[e.to]);let f=react$1.useMemo(()=>[d,p].filter(Boolean),[d,p]),w=react.useTokensQuery({chain:t,addresses:f},{enabled:f.length>0,refetchInterval:Xe}),s=react$1.useMemo(()=>w.data?.find(o=>o.address===d)??null,[w.data,d]),S=react$1.useMemo(()=>w.data?.find(o=>o.address===p)??null,[w.data,p]),C=react.useWalletPortfoliosByTokensQuery({chain:t,address:n,tokenAddresses:f},{enabled:!!n&&f.length>0,refetchInterval:qe}),b=react$1.useMemo(()=>C.data?.find(o=>o.address===d)??null,[C.data,d]),g=react$1.useMemo(()=>C.data?.find(o=>o.address===p)??null,[C.data,p]),[A,T]=react$1.useState(void 0),P=react$1.useMemo(()=>{if(!A||s?.decimals==null)return;let o=A.split("."),I=o[0]??"0",ye=(o[1]??"").slice(0,s.decimals).padEnd(s.decimals,"0");return (I+ye).replace(/^0+/,"")||"0"},[A,s?.decimals]),X=react$1.useMemo(()=>{if(!A||!s?.marketData?.priceInUsd)return;let o=Number(s.marketData.priceInUsd),I=Number(A)*o;return Number.isFinite(I)?I.toString():void 0},[A,s?.marketData?.priceInUsd]),q=react$1.useCallback(()=>{if(!b)return;let o=Number(b.amount);if(!Number.isFinite(o)||o<=0)return;let I=o/2,oe=s?.decimals??9;T(I.toLocaleString("en-US",{useGrouping:false,maximumFractionDigits:oe}));},[b,s?.decimals]),G=react$1.useCallback(()=>{if(!b)return;let o=Number(b.amount);if(!Number.isFinite(o)||o<=0)return;let I=s?.decimals??9;T(o.toLocaleString("en-US",{useGrouping:false,maximumFractionDigits:I}));},[b,s?.decimals]),be=react$1.useMemo(()=>({chain:t,userAddress:n||void 0,input:d||void 0,output:p||void 0,mode:types.API.SwapMode.EXACT_IN,amount:P}),[t,n,d,p,P]),Z=react$1.useRef(false),{route:U,isRouting:H,error:J}=ae(be,{paused:Z.current}),F=react$1.useMemo(()=>U&&S?Ge(U.plans,S.decimals):void 0,[U,S]),Y=react$1.useMemo(()=>{if(!F||!S?.marketData?.priceInUsd)return;let o=Number(S.marketData.priceInUsd),I=Number(F)*o;return Number.isFinite(I)?I.toString():void 0},[F,S?.marketData?.priceInUsd]),{swap:ee,isSwapping:k}=ie();Z.current=k;let L=react$1.useRef(e.onComplete);L.current=e.onComplete;let{track:te,transactions:D}=ue({onConfirmed:o=>{L.current?.({success:true,txHash:o});},onFailed:o=>{L.current?.({success:false,txHash:o});}}),ne=react$1.useMemo(()=>{if(D.size===0)return "idle";let o=Array.from(D.values());return o[o.length-1].status},[D]),re=react$1.useCallback(async()=>{if(!(!a||!U||!d||!p||!P))try{let o=await ee({chain:t,wallet:a,input:d,output:p,amount:P,mode:types.API.SwapMode.EXACT_IN});te(t,o.txHash);}catch{}},[a,U,t,d,p,P,ee,te]),se=w.isPending||C.isPending;return react$1.useMemo(()=>({fromTokenAddress:d,toTokenAddress:p,setFromTokenAddress:m,setToTokenAddress:r,fromToken:s,toToken:S,fromBalance:b,toBalance:g,amount:A,setAmount:T,setHalfAmount:q,setMaxAmount:G,amountInDecimals:P,amountInUsd:X,outputAmount:F,outputAmountInUsd:Y,route:U,isRouting:H,routeError:J,swap:re,isSwapping:k,txStatus:ne,isLoading:se}),[d,p,s,S,b,g,A,q,G,P,X,F,Y,U,H,J,re,k,ne,se])}function V({isOpen:e,onOpenChange:t,fromToken:u,toToken:i,fromBalance:a,inputAmount:n,inputAmountInUsd:d,outputAmount:m,outputAmountInUsd:p,route:r,isRouting:l,routeError:h,onConfirm:f,isSwapping:w}){let[s,S]=react$1.useState(false),C=react$1.useCallback(()=>S(g=>!g),[]),b=react$1.useMemo(()=>r?r.plans.map((g,A)=>({key:`plan-${A}`,name:g.name,input:g.input,inputAmount:g.inputAmount,output:g.output,outputAmount:g.outputAmount,feeQuote:g.feeQuote,feeAmount:g.feeAmount})):[],[r]);return jsxRuntime.jsx(ui.Modal,{isOpen:e,onOpenChange:t,hideCloseButton:true,scrollBehavior:"inside",backdrop:"blur",children:jsxRuntime.jsxs(ui.ModalContent,{className:"bg-content2 rounded-lg",children:[jsxRuntime.jsx(ui.ModalHeader,{children:"Preview"}),jsxRuntime.jsx(ui.ModalBody,{children:jsxRuntime.jsxs("div",{className:"flex w-full max-h-[70vh] flex-1 flex-col overflow-y-auto py-2",children:[jsxRuntime.jsxs("div",{className:"mb-5",children:[jsxRuntime.jsx("div",{className:"text-neutral flex items-center justify-between text-xs font-medium",children:"From"}),jsxRuntime.jsxs("div",{className:"bg-content3 mt-3 flex w-full items-center gap-3 rounded-lg px-4 py-3",children:[jsxRuntime.jsxs("div",{className:"flex flex-1 items-center gap-3",children:[u?.image&&jsxRuntime.jsx(ui.Avatar,{size:"sm",src:u.image,name:u.symbol,className:"h-6 w-6"}),jsxRuntime.jsxs("div",{className:"flex flex-col items-start justify-center gap-0.5",children:[jsxRuntime.jsx("div",{className:"text-foreground text-xs",children:u?.symbol??"\u2014"}),a&&jsxRuntime.jsxs("div",{className:"text-neutral flex items-center gap-1 text-[10px]",children:[jsxRuntime.jsx(at,{}),jsxRuntime.jsxs("span",{children:[$(a.amount)," ",u?.symbol]})]})]})]}),jsxRuntime.jsxs("div",{className:"flex-0 flex flex-col items-end justify-center gap-0.5",children:[jsxRuntime.jsx("div",{className:"text-foreground text-xs",children:$(n)}),jsxRuntime.jsxs("div",{className:"text-neutral text-[10px]",children:["$",fe(d)]})]})]})]}),jsxRuntime.jsxs("div",{className:"mb-5",children:[jsxRuntime.jsx("div",{className:"text-neutral flex items-center justify-between text-xs font-medium",children:"Estimated Receive"}),jsxRuntime.jsxs("div",{className:"bg-content3 mt-3 flex w-full items-center gap-3 rounded-lg px-4 py-3",children:[jsxRuntime.jsxs("div",{className:"flex flex-1 items-center gap-3",children:[i?.image&&jsxRuntime.jsx(ui.Avatar,{size:"sm",src:i.image,name:i.symbol,className:"h-6 w-6"}),jsxRuntime.jsxs("div",{className:"flex flex-col items-start justify-center gap-0.5",children:[jsxRuntime.jsx("div",{className:"text-foreground text-xs",children:i?.symbol??"\u2014"}),jsxRuntime.jsx("div",{className:"text-neutral text-[10px]",children:E(i?.address)})]})]}),jsxRuntime.jsxs("div",{className:"flex-0 flex flex-col items-end justify-center gap-0.5",children:[jsxRuntime.jsx("div",{className:"text-foreground text-xs",children:$(m)}),jsxRuntime.jsxs("div",{className:"text-neutral text-[10px]",children:["$",fe(p)]})]})]})]}),s&&b.length>0&&jsxRuntime.jsxs("div",{className:"my-3",children:[jsxRuntime.jsx("div",{className:"text-neutral flex items-center justify-between text-xs font-medium",children:"Route Details"}),jsxRuntime.jsx("div",{className:"mt-3 flex flex-col gap-3",children:b.map(g=>jsxRuntime.jsxs("div",{className:"bg-content3 flex w-full flex-col items-center gap-2 rounded-lg px-4 py-3",children:[jsxRuntime.jsxs("div",{className:"flex w-full items-center justify-between",children:[jsxRuntime.jsx("div",{className:"text-neutral text-xs",children:"DEX"}),jsxRuntime.jsx("div",{className:"text-foreground text-xs",children:g.name})]}),jsxRuntime.jsxs("div",{className:"flex w-full items-center justify-between",children:[jsxRuntime.jsx("div",{className:"text-neutral text-xs",children:"Swap"}),jsxRuntime.jsxs("div",{className:"text-foreground flex items-center gap-2 text-xs",children:[jsxRuntime.jsxs("span",{children:[z(g.inputAmount)," ",E(g.input)]}),jsxRuntime.jsx(ui.TradeIcon,{width:12,height:12,className:"text-foreground"}),jsxRuntime.jsxs("span",{children:[z(g.outputAmount)," ",E(g.output)]})]})]}),g.feeAmount&&jsxRuntime.jsxs("div",{className:"flex w-full items-center justify-between",children:[jsxRuntime.jsx("div",{className:"text-neutral text-xs",children:"Fee"}),jsxRuntime.jsxs("div",{className:"text-foreground text-xs",children:[z(g.feeAmount)," ",E(g.feeQuote)]})]})]},g.key))})]}),b.length>0&&jsxRuntime.jsx("div",{className:"flex justify-center",children:jsxRuntime.jsx(ui.Button,{size:"sm",className:"text-neutral flex bg-transparent text-xs",endContent:s?jsxRuntime.jsx(ui.ChevronUpIcon,{width:12,height:12}):jsxRuntime.jsx(ui.ChevronDownIcon,{width:12,height:12}),disableRipple:true,onPress:C,children:s?"Show Less":"Show More"})})]})}),jsxRuntime.jsx(ui.ModalFooter,{children:jsxRuntime.jsx(ui.Button,{fullWidth:true,color:"primary",className:"flex rounded-lg",disableRipple:true,isDisabled:!r||!!h,isLoading:!r&&l||w,onPress:f,children:"Confirm"})})]})})}function at(){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:12,height:12,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:"text-neutral",children:[jsxRuntime.jsx("path",{d:"M21 12V7H5a2 2 0 0 1 0-4h14v4"}),jsxRuntime.jsx("path",{d:"M3 5v14a2 2 0 0 0 2 2h16v-5"}),jsxRuntime.jsx("path",{d:"M18 12a2 2 0 0 0 0 4h4v-4Z"})]})}function fe(e){if(!e)return "0.00";let t=Number(e);return Number.isFinite(t)?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):"0.00"}function $(e){if(!e)return "0";let t=Number(e);return Number.isFinite(t)?t>=1e6?(t/1e6).toLocaleString("en-US",{maximumFractionDigits:2})+"M":t>=1e3?(t/1e3).toLocaleString("en-US",{maximumFractionDigits:2})+"K":t.toLocaleString("en-US",{maximumFractionDigits:6}):"0"}function z(e){if(!e||e==="0")return "0";let t=Number(e);return Number.isFinite(t)?t>=1e12?(t/1e12).toFixed(2)+"T":t>=1e9?(t/1e9).toFixed(2)+"B":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(2)+"K":e:e}function E(e){return e?e.length<=10?e:`${e.slice(0,4)}...${e.slice(-4)}`:"\u2014"}function K({fromToken:e,toToken:t,fromBalance:u,toBalance:i,amount:a,amountInUsd:n,onAmountChange:d,onHalfAmount:m,onMaxAmount:p,outputAmount:r,outputAmountInUsd:l,onFromTokenSelect:h,onToTokenSelect:f,route:w,isRouting:s,routeError:S,onPreview:C,isSwapping:b,className:g}){return jsxRuntime.jsxs("div",{className:ui.cn("px-4 pb-4 lg:pb-8",g),children:[jsxRuntime.jsxs("div",{className:"space-y-3",children:[jsxRuntime.jsx("p",{className:"text-neutral text-sm font-medium",children:"From"}),jsxRuntime.jsxs("div",{className:"bg-content1 flex flex-col rounded-lg px-3.5 pb-2.5 pt-2",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx("div",{className:"flex-1",children:jsxRuntime.jsx(ui.Input,{type:"number",value:a??"",onChange:A=>d(A.target.value||void 0),placeholder:"0",classNames:{inputWrapper:ui.cn("h-10 p-0 bg-transparent","data-[hover=true]:bg-transparent group-data-[focus=true]:bg-transparent","group-data-[focus-visible=true]:ring-offset-transparent group-data-[focus-visible=true]:ring-transparent"),input:ui.cn("w-full h-full caret-primary text-3xl font-medium","placeholder:text-placeholder placeholder:text-3xl placeholder:font-medium","scrollbar-hide overflow-hidden text-ellipsis whitespace-nowrap")}})}),jsxRuntime.jsx("div",{className:"flex-0 flex h-full items-center justify-center",children:jsxRuntime.jsx(ui.Button,{className:ui.cn("flex min-w-0 h-8 min-h-8 pl-3 pr-2 bg-content3 rounded-full",e?"text-foreground":"text-neutral"),disableRipple:true,startContent:e?.image?jsxRuntime.jsx(ui.Avatar,{size:"sm",src:e.image,name:e.symbol,className:"h-6 w-6"}):null,endContent:jsxRuntime.jsx(ui.ChevronDownIcon,{width:16,height:16,className:"text-neutral"}),onPress:()=>h(""),children:e?e.symbol:"Select token"})})]}),jsxRuntime.jsxs("div",{className:"mt-3 flex items-center justify-between gap-4",children:[jsxRuntime.jsxs("div",{className:"text-neutral flex-1 text-xs",children:["\u2248 $",Se(n)]}),u&&jsxRuntime.jsxs("div",{className:"flex-0 flex items-center gap-2 pr-3 text-xs",children:[jsxRuntime.jsx(ve,{}),jsxRuntime.jsxs("span",{className:"text-neutral",children:[he(u.amount)," ",u.symbol]}),m&&jsxRuntime.jsx("span",{className:"text-primary cursor-pointer",onClick:m,children:"Half"}),p&&jsxRuntime.jsx("span",{className:"text-primary cursor-pointer",onClick:p,children:"Max"})]})]}),S&&jsxRuntime.jsx("p",{className:"mt-1 break-words text-xs text-danger-500",children:S.message})]})]}),jsxRuntime.jsxs("div",{className:"mt-4 space-y-3",children:[jsxRuntime.jsx("p",{className:"text-neutral text-sm font-medium",children:"To"}),jsxRuntime.jsxs("div",{className:"bg-content1 flex flex-col rounded-lg px-3.5 pb-2.5 pt-2",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx("div",{className:"flex-1",children:jsxRuntime.jsx(ui.Input,{type:"number",value:r??"",disabled:true,placeholder:"0",classNames:{inputWrapper:ui.cn("h-10 p-0 bg-transparent","data-[hover=true]:bg-transparent group-data-[focus=true]:bg-transparent","group-data-[focus-visible=true]:ring-offset-transparent group-data-[focus-visible=true]:ring-transparent"),input:ui.cn("w-full h-full caret-primary text-3xl font-medium","placeholder:text-placeholder placeholder:text-3xl placeholder:font-medium","scrollbar-hide overflow-hidden text-ellipsis whitespace-nowrap")}})}),jsxRuntime.jsx("div",{className:"flex-0 flex h-full items-center justify-center",children:jsxRuntime.jsx(ui.Button,{className:ui.cn("flex min-w-0 h-8 min-h-8 pl-3 pr-2 bg-content3 rounded-full",t?"text-foreground":"text-neutral"),disableRipple:true,startContent:t?.image?jsxRuntime.jsx(ui.Avatar,{size:"sm",src:t.image,name:t.symbol,className:"h-6 w-6"}):null,endContent:jsxRuntime.jsx(ui.ChevronDownIcon,{width:16,height:16,className:"text-neutral"}),onPress:()=>f(""),children:t?t.symbol:"Select token"})})]}),jsxRuntime.jsxs("div",{className:"mt-3 flex items-center justify-between gap-4",children:[jsxRuntime.jsxs("div",{className:"text-neutral flex-1 text-xs",children:["\u2248 $",Se(l)]}),i&&jsxRuntime.jsxs("div",{className:"flex-0 flex items-center gap-2 pr-3 text-xs",children:[jsxRuntime.jsx(ve,{}),jsxRuntime.jsxs("span",{className:"text-neutral",children:[he(i.amount)," ",i.symbol]})]})]})]})]}),jsxRuntime.jsx(ui.Button,{fullWidth:true,color:"primary",className:"mt-8 flex rounded-lg",disableRipple:true,isDisabled:!w,isLoading:!w&&s,onPress:C,children:b?"Swapping...":s?"Finding route...":"Swap"})]})}function ve(){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:12,height:12,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:"text-neutral",children:[jsxRuntime.jsx("path",{d:"M21 12V7H5a2 2 0 0 1 0-4h14v4"}),jsxRuntime.jsx("path",{d:"M3 5v14a2 2 0 0 0 2 2h16v-5"}),jsxRuntime.jsx("path",{d:"M18 12a2 2 0 0 0 0 4h4v-4Z"})]})}function Se(e){if(!e)return "0.00";let t=Number(e);return Number.isFinite(t)?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):"0.00"}function he(e){if(!e)return "0";let t=Number(e);return Number.isFinite(t)?t>=1e6?(t/1e6).toLocaleString("en-US",{maximumFractionDigits:2})+"M":t>=1e3?(t/1e3).toLocaleString("en-US",{maximumFractionDigits:2})+"K":t.toLocaleString("en-US",{maximumFractionDigits:6}):"0"}function ct({chain:e,from:t,to:u,onComplete:i,className:a}){let n=j({chain:e,from:t,to:u,onComplete:i}),{isOpen:d,onOpen:m,onOpenChange:p,onClose:r}=ui.useDisclosure(),l=react$1.useCallback(async()=>{await n.swap(),r();},[n,r]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(K,{fromToken:n.fromToken,toToken:n.toToken,fromBalance:n.fromBalance,toBalance:n.toBalance,amount:n.amount,amountInUsd:n.amountInUsd,onAmountChange:n.setAmount,onHalfAmount:n.setHalfAmount,onMaxAmount:n.setMaxAmount,outputAmount:n.outputAmount,outputAmountInUsd:n.outputAmountInUsd,onFromTokenSelect:n.setFromTokenAddress,onToTokenSelect:n.setToTokenAddress,route:n.route,isRouting:n.isRouting,routeError:n.routeError,onPreview:m,isSwapping:n.isSwapping,className:a}),jsxRuntime.jsx(V,{isOpen:d,onOpenChange:p,fromToken:n.fromToken,toToken:n.toToken,fromBalance:n.fromBalance,inputAmount:n.amount,inputAmountInUsd:n.amountInUsd,outputAmount:n.outputAmount,outputAmountInUsd:n.outputAmountInUsd,route:n.route,isRouting:n.isRouting,routeError:n.routeError,onConfirm:l,isSwapping:n.isSwapping})]})}typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-trade"]="0.1.2");var pt="0.1.2";
|
|
2
|
+
exports.SwapPreviewModal=V;exports.SwapUI=K;exports.SwapWidget=ct;exports.useSwap=ie;exports.useSwapRoutePolling=ae;exports.useSwapScript=j;exports.useTxConfirmation=ue;exports.version=pt;//# sourceMappingURL=index.js.map
|
|
2
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useSwap.ts","../src/hooks/useTxConfirmation.ts","../src/version.ts"],"names":["base64ToUint8Array","base64","binary","bytes","i","uint8ArrayToBase64","useSwap","options","client","useDexClient","isSwapping","setIsSwapping","useState","optionsRef","useRef","swap","useCallback","input","wallet","chain","rest","route","API","e","err","signedBytes","unsignedBytes","sendResult","signedBase64","result","useMemo","DEFAULT_TIMEOUT","useTxConfirmation","transactions","setTransactions","updateTx","txHash","status","prev","existing","next","track","timeout","success","clear","clearAll","version_default"],"mappings":"gHAKA,SAASA,CAAAA,CAAmBC,CAAAA,CAA4B,CACtD,IAAMC,CAAAA,CAAS,KAAKD,CAAM,CAAA,CACpBE,CAAAA,CAAQ,IAAI,WAAWD,CAAAA,CAAO,MAAM,CAAA,CAC1C,IAAA,IAASE,EAAI,CAAA,CAAGA,CAAAA,CAAIF,CAAAA,CAAO,MAAA,CAAQE,CAAAA,EAAAA,CACjCD,CAAAA,CAAMC,CAAC,CAAA,CAAIF,EAAO,UAAA,CAAWE,CAAC,CAAA,CAEhC,OAAOD,CACT,CAEA,SAASE,CAAAA,CAAmBF,CAAAA,CAA2B,CACrD,IAAID,CAAAA,CAAS,EAAA,CACb,IAAA,IAAS,EAAI,CAAA,CAAG,CAAA,CAAIC,CAAAA,CAAM,MAAA,CAAQ,IAChCD,CAAAA,EAAU,MAAA,CAAO,YAAA,CAAaC,CAAAA,CAAM,CAAC,CAAC,CAAA,CAExC,OAAO,IAAA,CAAKD,CAAM,CACpB,CAYO,SAASI,CAAAA,CAAQC,CAAAA,CAA0B,CAChD,GAAM,CAAE,OAAAC,CAAO,CAAA,CAAIC,kBAAAA,EAAa,CAC1B,CAACC,CAAAA,CAAYC,CAAa,CAAA,CAAIC,gBAAAA,CAAS,KAAK,CAAA,CAC5CC,CAAAA,CAAaC,cAAAA,CAAOP,CAAO,CAAA,CACjCM,CAAAA,CAAW,OAAA,CAAUN,CAAAA,CAErB,IAAMQ,CAAAA,CAAOC,mBAAAA,CACX,MAAOC,CAAAA,EAA0C,CAC/C,GAAM,CAAE,MAAA,CAAAC,CAAAA,CAAQ,MAAAC,CAAAA,CAAO,GAAGC,CAAK,CAAA,CAAIH,CAAAA,CAEnCN,CAAAA,CAAc,IAAI,CAAA,CAClB,GAAI,CAEF,IAAIU,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAQ,MAAMb,CAAAA,CAAO,SAAA,CAAU,CAC7B,KAAA,CAAAW,CAAAA,CACA,WAAA,CAAaD,CAAAA,CAAO,QACpB,KAAA,CAAOE,CAAAA,CAAK,KAAA,CACZ,MAAA,CAAQA,EAAK,MAAA,CACb,IAAA,CAAMA,CAAAA,CAAK,IAAA,EAAQE,UAAI,QAAA,CAAS,QAAA,CAChC,MAAA,CAAQF,CAAAA,CAAK,OACb,QAAA,CAAUA,CAAAA,CAAK,QAAA,CACf,WAAA,CAAaA,CAAAA,CAAK,WAAA,CAClB,MAAA,CAAQA,CAAAA,CAAK,OACb,SAAA,CAAWA,CAAAA,CAAK,SAAA,CAChB,MAAA,CAAQA,EAAK,MAAA,CACb,QAAA,CAAUA,CAAAA,CAAK,QACjB,CAAC,EACH,CAAA,MAASG,CAAAA,CAAG,CACV,IAAMC,CAAAA,CAAMD,CAAAA,YAAa,KAAA,CAAQA,EAAI,IAAI,KAAA,CAAM,MAAA,CAAOA,CAAC,CAAC,CAAA,CACxD,MAAAV,CAAAA,CAAW,OAAA,EAAS,UAAUW,CAAAA,CAAK,OAAO,CAAA,CACpCA,CACR,CAGA,IAAIC,CAAAA,CACJ,GAAI,CACF,IAAMC,CAAAA,CAAgB1B,CAAAA,CAAmBqB,CAAAA,CAAM,YAAY,CAAA,CAC3DI,CAAAA,CAAc,MAAMP,CAAAA,CAAO,gBAAgBQ,CAAa,EAC1D,CAAA,MAASH,CAAAA,CAAG,CACV,IAAMC,CAAAA,CAAMD,CAAAA,YAAa,KAAA,CAAQA,EAAI,IAAI,KAAA,CAAM,MAAA,CAAOA,CAAC,CAAC,CAAA,CACxD,MAAAV,CAAAA,CAAW,OAAA,EAAS,UAAUW,CAAAA,CAAK,MAAM,CAAA,CACnCA,CACR,CAGA,IAAIG,CAAAA,CACJ,GAAI,CACF,IAAMC,CAAAA,CAAevB,CAAAA,CAAmBoB,CAAW,EACnDE,CAAAA,CAAa,MAAMnB,CAAAA,CAAO,MAAA,CAAO,CAC/B,KAAA,CAAAW,CAAAA,CACA,YAAA,CAAcS,CAChB,CAAC,EACH,CAAA,MAASL,CAAAA,CAAG,CACV,IAAMC,CAAAA,CAAMD,CAAAA,YAAa,KAAA,CAAQA,EAAI,IAAI,KAAA,CAAM,MAAA,CAAOA,CAAC,CAAC,CAAA,CACxD,MAAAV,CAAAA,CAAW,OAAA,EAAS,OAAA,GAAUW,CAAAA,CAAK,MAAM,CAAA,CACnCA,CACR,CAEA,IAAMK,CAAAA,CAAqB,CACzB,OAAQF,CAAAA,CAAW,MAAA,CACnB,KAAA,CAAOA,CAAAA,CAAW,KACpB,CAAA,CAEA,OAAAd,CAAAA,CAAW,OAAA,EAAS,cAAcgB,CAAM,CAAA,CACjCA,CACT,CAAA,OAAE,CACAlB,CAAAA,CAAc,KAAK,EACrB,CACF,EACA,CAACH,CAAM,CACT,CAAA,CAEA,OAAOsB,eAAAA,CAAQ,KAAO,CAAE,IAAA,CAAAf,CAAAA,CAAM,UAAA,CAAAL,CAAW,CAAA,CAAA,CAAI,CAACK,CAAAA,CAAML,CAAU,CAAC,CACjE,CChGA,IAAMqB,CAAAA,CAAkB,GAAA,CAiBjB,SAASC,EAAkBzB,CAAAA,CAAoC,CACpE,GAAM,CAAE,OAAAC,CAAO,CAAA,CAAIC,kBAAAA,EAAa,CAC1B,CAACwB,CAAAA,CAAcC,CAAe,CAAA,CAAItB,iBACtC,IAAM,IAAI,GACZ,CAAA,CACMC,EAAaC,cAAAA,CAAOP,CAAO,CAAA,CACjCM,CAAAA,CAAW,QAAUN,CAAAA,CAErB,IAAM4B,CAAAA,CAAWnB,mBAAAA,CACf,CAACoB,CAAAA,CAAgBC,CAAAA,GAAiC,CAChDH,CAAAA,CAAiBI,GAAS,CACxB,IAAMC,CAAAA,CAAWD,CAAAA,CAAK,IAAIF,CAAM,CAAA,CAEhC,GADI,CAACG,GACDA,CAAAA,CAAS,MAAA,GAAWF,CAAAA,CAAQ,OAAOC,CAAAA,CACvC,IAAME,CAAAA,CAAO,IAAI,IAAIF,CAAI,CAAA,CACzB,OAAAE,CAAAA,CAAK,IAAIJ,CAAAA,CAAQ,CAAE,GAAGG,CAAAA,CAAU,OAAAF,CAAO,CAAC,CAAA,CACjCG,CACT,CAAC,EACH,CAAA,CACA,EACF,CAAA,CAEMC,CAAAA,CAAQzB,mBAAAA,CACZ,CAACG,EAAciB,CAAAA,GAAmB,CAChCF,CAAAA,CAAiBI,CAAAA,EAAS,CACxB,GAAIA,CAAAA,CAAK,GAAA,CAAIF,CAAM,CAAA,CAAG,OAAOE,CAAAA,CAC7B,IAAME,EAAO,IAAI,GAAA,CAAIF,CAAI,CAAA,CACzB,OAAAE,CAAAA,CAAK,GAAA,CAAIJ,CAAAA,CAAQ,CAAE,MAAAjB,CAAAA,CAAO,MAAA,CAAAiB,CAAAA,CAAQ,MAAA,CAAQ,SAAU,CAAC,CAAA,CAC9CI,CACT,CAAC,EAED,IAAME,CAAAA,CAAU7B,CAAAA,CAAW,OAAA,EAAS,SAAWkB,CAAAA,CAE/CvB,CAAAA,CACG,cAAA,CAAeW,CAAAA,CAAOiB,EAAQM,CAAO,CAAA,CACrC,IAAA,CAAMC,CAAAA,EAAY,CACjB,GAAIA,CAAAA,CACFR,CAAAA,CAASC,EAAQ,WAAW,CAAA,CAC5BvB,CAAAA,CAAW,OAAA,EAAS,cAAcuB,CAAM,CAAA,CAAA,KACnC,CACL,IAAMZ,EAAM,IAAI,KAAA,CAAM,6BAA6B,CAAA,CACnDW,CAAAA,CAASC,CAAAA,CAAQ,QAAQ,CAAA,CACzBvB,EAAW,OAAA,EAAS,QAAA,GAAWuB,CAAAA,CAAQZ,CAAG,EAC5C,CACF,CAAC,CAAA,CACA,KAAA,CAAOD,GAAM,CACZ,IAAMC,CAAAA,CAAMD,CAAAA,YAAa,KAAA,CAAQA,CAAAA,CAAI,IAAI,KAAA,CAAM,OAAOA,CAAC,CAAC,CAAA,CACxDY,CAAAA,CAASC,EAAQ,QAAQ,CAAA,CACzBvB,CAAAA,CAAW,OAAA,EAAS,WAAWuB,CAAAA,CAAQZ,CAAG,EAC5C,CAAC,EACL,CAAA,CACA,CAAChB,CAAAA,CAAQ2B,CAAQ,CACnB,CAAA,CAEMS,CAAAA,CAAQ5B,mBAAAA,CAAaoB,CAAAA,EAAmB,CAC5CF,CAAAA,CAAiBI,CAAAA,EAAS,CACxB,GAAI,CAACA,CAAAA,CAAK,GAAA,CAAIF,CAAM,CAAA,CAAG,OAAOE,CAAAA,CAC9B,IAAME,CAAAA,CAAO,IAAI,GAAA,CAAIF,CAAI,CAAA,CACzB,OAAAE,EAAK,MAAA,CAAOJ,CAAM,CAAA,CACXI,CACT,CAAC,EACH,CAAA,CAAG,EAAE,CAAA,CAECK,CAAAA,CAAW7B,mBAAAA,CAAY,IAAM,CACjCkB,CAAAA,CAAiBI,CAAAA,EAAUA,CAAAA,CAAK,IAAA,GAAS,EAAIA,CAAAA,CAAO,IAAI,GAAM,EAChE,EAAG,EAAE,CAAA,CAEL,OAAOR,eAAAA,CACL,KAAO,CAAE,KAAA,CAAAW,EAAO,KAAA,CAAAG,CAAAA,CAAO,QAAA,CAAAC,CAAAA,CAAU,aAAAZ,CAAa,CAAA,CAAA,CAC9C,CAACQ,CAAAA,CAAOG,EAAOC,CAAAA,CAAUZ,CAAY,CACvC,CACF,CC5FI,OAAO,MAAA,CAAW,GAAA,GACpB,MAAA,CAAO,oBAAsB,MAAA,CAAO,mBAAA,EAAuB,EAAC,CAC5D,OAAO,mBAAA,CAAoB,sBAAsB,CAAA,CAAI,OAAA,CAAA,KAGhDa,CAAAA,CAAQ","file":"index.js","sourcesContent":["import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useDexClient } from \"@liberfi.io/react\";\nimport { API } from \"@liberfi.io/types\";\nimport type { SwapInput, SwapResult, UseSwapOptions } from \"../types\";\n\nfunction base64ToUint8Array(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Hook that orchestrates the full swap flow: route -> sign -> send.\n *\n * Designed for IoC: no toast, no i18n, no UI side-effects.\n * The caller controls feedback via `onSubmitted` / `onError` callbacks.\n *\n * Works across Solana and EVM chains — chain-specific differences\n * (dex selection, tx format) are handled by the underlying client\n * and wallet adapter abstractions.\n */\nexport function useSwap(options?: UseSwapOptions) {\n const { client } = useDexClient();\n const [isSwapping, setIsSwapping] = useState(false);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const swap = useCallback(\n async (input: SwapInput): Promise<SwapResult> => {\n const { wallet, chain, ...rest } = input;\n\n setIsSwapping(true);\n try {\n // 1. Fetch route — returns unsigned tx as base64\n let route: API.SwapRoute;\n try {\n route = await client.swapRoute({\n chain,\n userAddress: wallet.address,\n input: rest.input,\n output: rest.output,\n mode: rest.mode ?? API.SwapMode.EXACT_IN,\n amount: rest.amount,\n slippage: rest.slippage,\n priorityFee: rest.priorityFee,\n tipFee: rest.tipFee,\n isAntiMev: rest.isAntiMev,\n permit: rest.permit,\n deadline: rest.deadline,\n });\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n optionsRef.current?.onError?.(err, \"route\");\n throw err;\n }\n\n // 2. Sign the transaction via wallet adapter\n let signedBytes: Uint8Array;\n try {\n const unsignedBytes = base64ToUint8Array(route.serializedTx);\n signedBytes = await wallet.signTransaction(unsignedBytes);\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n optionsRef.current?.onError?.(err, \"sign\");\n throw err;\n }\n\n // 3. Submit the signed transaction\n let sendResult: API.SendTxResult;\n try {\n const signedBase64 = uint8ArrayToBase64(signedBytes);\n sendResult = await client.sendTx({\n chain,\n serializedTx: signedBase64,\n });\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n optionsRef.current?.onError?.(err, \"send\");\n throw err;\n }\n\n const result: SwapResult = {\n txHash: sendResult.txHash,\n extra: sendResult.extra,\n };\n\n optionsRef.current?.onSubmitted?.(result);\n return result;\n } finally {\n setIsSwapping(false);\n }\n },\n [client],\n );\n\n return useMemo(() => ({ swap, isSwapping }), [swap, isSwapping]);\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useDexClient } from \"@liberfi.io/react\";\nimport { Chain } from \"@liberfi.io/types\";\nimport type { TxConfirmationStatus, UseTxConfirmationOptions } from \"../types\";\n\ninterface TrackedTx {\n chain: Chain;\n txHash: string;\n status: TxConfirmationStatus;\n}\n\nconst DEFAULT_TIMEOUT = 60_000;\n\n/**\n * Hook that tracks transaction confirmation via backend SSE (Server-Sent Events).\n *\n * Designed to be composed with `useSwap` — call `track()` inside `onSubmitted`\n * to start monitoring. Supports tracking multiple concurrent transactions.\n *\n * @example\n * ```tsx\n * const { swap } = useSwap({ onSubmitted: (r) => track(chain, r.txHash) });\n * const { track, transactions } = useTxConfirmation({\n * onConfirmed: (txHash) => toast.success(`Confirmed: ${txHash}`),\n * onFailed: (txHash) => toast.error(`Failed: ${txHash}`),\n * });\n * ```\n */\nexport function useTxConfirmation(options?: UseTxConfirmationOptions) {\n const { client } = useDexClient();\n const [transactions, setTransactions] = useState<Map<string, TrackedTx>>(\n () => new Map(),\n );\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const updateTx = useCallback(\n (txHash: string, status: TxConfirmationStatus) => {\n setTransactions((prev) => {\n const existing = prev.get(txHash);\n if (!existing) return prev;\n if (existing.status === status) return prev;\n const next = new Map(prev);\n next.set(txHash, { ...existing, status });\n return next;\n });\n },\n [],\n );\n\n const track = useCallback(\n (chain: Chain, txHash: string) => {\n setTransactions((prev) => {\n if (prev.has(txHash)) return prev;\n const next = new Map(prev);\n next.set(txHash, { chain, txHash, status: \"pending\" });\n return next;\n });\n\n const timeout = optionsRef.current?.timeout ?? DEFAULT_TIMEOUT;\n\n client\n .checkTxSuccess(chain, txHash, timeout)\n .then((success) => {\n if (success) {\n updateTx(txHash, \"confirmed\");\n optionsRef.current?.onConfirmed?.(txHash);\n } else {\n const err = new Error(\"Transaction failed on-chain\");\n updateTx(txHash, \"failed\");\n optionsRef.current?.onFailed?.(txHash, err);\n }\n })\n .catch((e) => {\n const err = e instanceof Error ? e : new Error(String(e));\n updateTx(txHash, \"failed\");\n optionsRef.current?.onFailed?.(txHash, err);\n });\n },\n [client, updateTx],\n );\n\n const clear = useCallback((txHash: string) => {\n setTransactions((prev) => {\n if (!prev.has(txHash)) return prev;\n const next = new Map(prev);\n next.delete(txHash);\n return next;\n });\n }, []);\n\n const clearAll = useCallback(() => {\n setTransactions((prev) => (prev.size === 0 ? prev : new Map()));\n }, []);\n\n return useMemo(\n () => ({ track, clear, clearAll, transactions }),\n [track, clear, clearAll, transactions],\n );\n}\n","declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-trade\"] = \"0.1.1\";\n}\n\nexport default \"0.1.1\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSwap.ts","../src/hooks/useSwapRoutePolling.ts","../src/hooks/useTxConfirmation.ts","../src/components/swap/swap.script.ts","../src/components/swap/swap-preview-modal.tsx","../src/components/swap/swap.ui.tsx","../src/components/swap/swap.widget.tsx","../src/version.ts"],"names":["base64ToUint8Array","base64","binary","bytes","uint8ArrayToBase64","i","useSwap","options","client","useDexClient","isSwapping","setIsSwapping","useState","optionsRef","useRef","swap","useCallback","input","wallet","chain","rest","route","API","e","err","signedBytes","unsignedBytes","sendResult","signedBase64","result","useMemo","DEFAULT_INTERVAL","useSwapRoutePolling","params","interval","paused","enabled","query","useSwapRouteQuery","useEffect","DEFAULT_TIMEOUT","useTxConfirmation","transactions","setTransactions","updateTx","txHash","status","prev","existing","next","track","timeout","success","clear","clearAll","SOLANA_CHAINS","Chain","chainNamespace","ChainNamespace","TOKEN_POLL_MS","BALANCE_POLL_MS","formatOutputAmount","plans","decimals","raw","padded","intPart","trimmed","useSwapScript","wallets","useWallets","ns","w","walletAddress","fromTokenAddress","setFromTokenAddress","toTokenAddress","setToTokenAddress","fromRef","toRef","tokenAddresses","tokensQuery","useTokensQuery","fromToken","t","toToken","balancesQuery","useWalletPortfoliosByTokensQuery","fromBalance","p","toBalance","amount","setAmount","amountInDecimals","parts","amountInUsd","price","value","setHalfAmount","bal","half","setMaxAmount","routeParams","isSwappingRef","isRouting","routeError","outputAmount","outputAmountInUsd","rawSwap","onCompleteRef","latestTxStatus","entries","isLoading","SwapPreviewModal","isOpen","onOpenChange","inputAmount","inputAmountInUsd","onConfirm","expanded","setExpanded","toggleExpanded","plan","jsx","Modal","jsxs","ModalContent","ModalHeader","ModalBody","Avatar","WalletBalanceIcon","formatNumber","formatUsd","truncateAddress","formatSmallAmount","TradeIcon","Button","ChevronUpIcon","ChevronDownIcon","ModalFooter","n","addr","SwapUI","onAmountChange","onHalfAmount","onMaxAmount","onFromTokenSelect","onToTokenSelect","onPreview","className","cn","Input","SwapWidget","from","to","onComplete","script","onOpen","onClose","useDisclosure","handleConfirm","Fragment","version_default"],"mappings":"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","file":"index.js","sourcesContent":["import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useDexClient } from \"@liberfi.io/react\";\nimport { API } from \"@liberfi.io/types\";\nimport type { SwapInput, SwapResult, UseSwapOptions } from \"../types\";\n\nfunction base64ToUint8Array(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Hook that orchestrates the full swap flow: route -> sign -> send.\n *\n * Designed for IoC: no toast, no i18n, no UI side-effects.\n * The caller controls feedback via `onSubmitted` / `onError` callbacks.\n *\n * Works across Solana and EVM chains — chain-specific differences\n * (dex selection, tx format) are handled by the underlying client\n * and wallet adapter abstractions.\n */\nexport function useSwap(options?: UseSwapOptions) {\n const { client } = useDexClient();\n const [isSwapping, setIsSwapping] = useState(false);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const swap = useCallback(\n async (input: SwapInput): Promise<SwapResult> => {\n const { wallet, chain, ...rest } = input;\n\n setIsSwapping(true);\n try {\n // 1. Fetch route — returns unsigned tx as base64\n let route: API.SwapRoute;\n try {\n route = await client.swapRoute({\n chain,\n userAddress: wallet.address,\n input: rest.input,\n output: rest.output,\n mode: rest.mode ?? API.SwapMode.EXACT_IN,\n amount: rest.amount,\n slippage: rest.slippage,\n priorityFee: rest.priorityFee,\n tipFee: rest.tipFee,\n isAntiMev: rest.isAntiMev,\n permit: rest.permit,\n deadline: rest.deadline,\n });\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n optionsRef.current?.onError?.(err, \"route\");\n throw err;\n }\n\n // 2. Sign the transaction via wallet adapter\n let signedBytes: Uint8Array;\n try {\n const unsignedBytes = base64ToUint8Array(route.serializedTx);\n signedBytes = await wallet.signTransaction(unsignedBytes);\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n optionsRef.current?.onError?.(err, \"sign\");\n throw err;\n }\n\n // 3. Submit the signed transaction\n let sendResult: API.SendTxResult;\n try {\n const signedBase64 = uint8ArrayToBase64(signedBytes);\n sendResult = await client.sendTx({\n chain,\n serializedTx: signedBase64,\n });\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n optionsRef.current?.onError?.(err, \"send\");\n throw err;\n }\n\n const result: SwapResult = {\n txHash: sendResult.txHash,\n extra: sendResult.extra,\n };\n\n optionsRef.current?.onSubmitted?.(result);\n return result;\n } finally {\n setIsSwapping(false);\n }\n },\n [client],\n );\n\n return useMemo(() => ({ swap, isSwapping }), [swap, isSwapping]);\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { useSwapRouteQuery } from \"@liberfi.io/react\";\nimport { API } from \"@liberfi.io/types\";\nimport type { UseSwapRoutePollingOptions } from \"../types\";\n\nconst DEFAULT_INTERVAL = 12_000;\n\n/**\n * Hook that polls for swap route quotes at a configurable interval.\n *\n * Built on top of `useSwapRouteQuery` (TanStack Query) — automatically\n * deduplicates requests, caches results, and invalidates when params change.\n *\n * Polling pauses when `paused` is true (e.g. during swap execution) or\n * when required params are missing.\n */\nexport function useSwapRoutePolling(\n params: Partial<API.SwapParams>,\n options?: UseSwapRoutePollingOptions,\n) {\n const interval = options?.interval ?? DEFAULT_INTERVAL;\n const paused = options?.paused ?? false;\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const hasRequiredParams =\n !!params.chain &&\n !!params.userAddress &&\n !!params.input &&\n !!params.output &&\n !!params.amount;\n\n const enabled = hasRequiredParams && !paused;\n\n const query = useSwapRouteQuery(params as API.SwapParams, {\n enabled,\n refetchInterval: enabled ? interval : false,\n retry: false,\n });\n\n useEffect(() => {\n if (query.error) {\n optionsRef.current?.onError?.(query.error);\n }\n }, [query.error]);\n\n return useMemo(\n () => ({\n route: query.data,\n isRouting: query.isFetching,\n error: query.error,\n }),\n [query.data, query.isFetching, query.error],\n );\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useDexClient } from \"@liberfi.io/react\";\nimport { Chain } from \"@liberfi.io/types\";\nimport type { TxConfirmationStatus, UseTxConfirmationOptions } from \"../types\";\n\ninterface TrackedTx {\n chain: Chain;\n txHash: string;\n status: TxConfirmationStatus;\n}\n\nconst DEFAULT_TIMEOUT = 60_000;\n\n/**\n * Hook that tracks transaction confirmation via backend SSE (Server-Sent Events).\n *\n * Designed to be composed with `useSwap` — call `track()` inside `onSubmitted`\n * to start monitoring. Supports tracking multiple concurrent transactions.\n *\n * @example\n * ```tsx\n * const { swap } = useSwap({ onSubmitted: (r) => track(chain, r.txHash) });\n * const { track, transactions } = useTxConfirmation({\n * onConfirmed: (txHash) => toast.success(`Confirmed: ${txHash}`),\n * onFailed: (txHash) => toast.error(`Failed: ${txHash}`),\n * });\n * ```\n */\nexport function useTxConfirmation(options?: UseTxConfirmationOptions) {\n const { client } = useDexClient();\n const [transactions, setTransactions] = useState<Map<string, TrackedTx>>(\n () => new Map(),\n );\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const updateTx = useCallback(\n (txHash: string, status: TxConfirmationStatus) => {\n setTransactions((prev) => {\n const existing = prev.get(txHash);\n if (!existing) return prev;\n if (existing.status === status) return prev;\n const next = new Map(prev);\n next.set(txHash, { ...existing, status });\n return next;\n });\n },\n [],\n );\n\n const track = useCallback(\n (chain: Chain, txHash: string) => {\n setTransactions((prev) => {\n if (prev.has(txHash)) return prev;\n const next = new Map(prev);\n next.set(txHash, { chain, txHash, status: \"pending\" });\n return next;\n });\n\n const timeout = optionsRef.current?.timeout ?? DEFAULT_TIMEOUT;\n\n client\n .checkTxSuccess(chain, txHash, timeout)\n .then((success) => {\n if (success) {\n updateTx(txHash, \"confirmed\");\n optionsRef.current?.onConfirmed?.(txHash);\n } else {\n const err = new Error(\"Transaction failed on-chain\");\n updateTx(txHash, \"failed\");\n optionsRef.current?.onFailed?.(txHash, err);\n }\n })\n .catch((e) => {\n const err = e instanceof Error ? e : new Error(String(e));\n updateTx(txHash, \"failed\");\n optionsRef.current?.onFailed?.(txHash, err);\n });\n },\n [client, updateTx],\n );\n\n const clear = useCallback((txHash: string) => {\n setTransactions((prev) => {\n if (!prev.has(txHash)) return prev;\n const next = new Map(prev);\n next.delete(txHash);\n return next;\n });\n }, []);\n\n const clearAll = useCallback(() => {\n setTransactions((prev) => (prev.size === 0 ? prev : new Map()));\n }, []);\n\n return useMemo(\n () => ({ track, clear, clearAll, transactions }),\n [track, clear, clearAll, transactions],\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useTokensQuery,\n useWalletPortfoliosByTokensQuery,\n} from \"@liberfi.io/react\";\nimport { API, Chain, ChainNamespace } from \"@liberfi.io/types\";\nimport { useWallets } from \"@liberfi.io/wallet-connector\";\nimport { useSwap } from \"../../hooks/useSwap\";\nimport { useSwapRoutePolling } from \"../../hooks/useSwapRoutePolling\";\nimport { useTxConfirmation } from \"../../hooks/useTxConfirmation\";\nimport type { UseSwapScriptParams, UseSwapScriptResult } from \"./types\";\n\nconst SOLANA_CHAINS: ReadonlySet<Chain> = new Set([\n Chain.SOLANA,\n Chain.SOLANA_TESTNET,\n Chain.SOLANA_DEVNET,\n]);\n\nfunction chainNamespace(chain: Chain): ChainNamespace {\n return SOLANA_CHAINS.has(chain) ? ChainNamespace.SOLANA : ChainNamespace.EVM;\n}\n\nconst TOKEN_POLL_MS = 10_000;\nconst BALANCE_POLL_MS = 15_000;\n\n/**\n * Computes the total output amount from route plans.\n * Each plan has an outputAmount in smallest units — we take the last plan's\n * output (the final token) and shift by decimals.\n */\nfunction formatOutputAmount(\n plans: Array<{ outputAmount: string }>,\n decimals: number,\n): string | undefined {\n if (plans.length === 0) return undefined;\n const lastPlan = plans[plans.length - 1]!;\n const raw = lastPlan.outputAmount;\n if (!raw || raw === \"0\") return \"0\";\n\n const padded = raw.padStart(decimals + 1, \"0\");\n const intPart = padded.slice(0, padded.length - decimals) || \"0\";\n const fracPart = padded.slice(padded.length - decimals);\n const trimmed = fracPart.replace(/0+$/, \"\");\n return trimmed ? `${intPart}.${trimmed}` : intPart;\n}\n\n/**\n * Script hook that encapsulates all data fetching and state management\n * for the swap form.\n *\n * Pure TypeScript — no JSX, no UI imports.\n */\nexport function useSwapScript(\n params: UseSwapScriptParams,\n): UseSwapScriptResult {\n const { chain } = params;\n\n // ── Wallet ────────────────────────────────────────────────────────────────\n\n const wallets = useWallets();\n const ns = chainNamespace(chain);\n const wallet = useMemo(\n () => wallets.find((w) => w.chainNamespace === ns && w.isConnected),\n [wallets, ns],\n );\n const walletAddress = wallet?.address ?? \"\";\n\n // ── Token selection state ─────────────────────────────────────────────────\n\n const [fromTokenAddress, setFromTokenAddress] = useState(params.from ?? \"\");\n const [toTokenAddress, setToTokenAddress] = useState(params.to ?? \"\");\n\n const fromRef = useRef(params.from);\n const toRef = useRef(params.to);\n useEffect(() => {\n if (params.from !== fromRef.current) {\n fromRef.current = params.from;\n if (params.from) setFromTokenAddress(params.from);\n }\n }, [params.from]);\n useEffect(() => {\n if (params.to !== toRef.current) {\n toRef.current = params.to;\n if (params.to) setToTokenAddress(params.to);\n }\n }, [params.to]);\n\n // ── Token metadata ────────────────────────────────────────────────────────\n\n const tokenAddresses = useMemo(\n () => [fromTokenAddress, toTokenAddress].filter(Boolean),\n [fromTokenAddress, toTokenAddress],\n );\n\n const tokensQuery = useTokensQuery(\n { chain, addresses: tokenAddresses },\n { enabled: tokenAddresses.length > 0, refetchInterval: TOKEN_POLL_MS },\n );\n\n const fromToken = useMemo(\n () => tokensQuery.data?.find((t) => t.address === fromTokenAddress) ?? null,\n [tokensQuery.data, fromTokenAddress],\n );\n const toToken = useMemo(\n () => tokensQuery.data?.find((t) => t.address === toTokenAddress) ?? null,\n [tokensQuery.data, toTokenAddress],\n );\n\n // ── Balances ──────────────────────────────────────────────────────────────\n\n const balancesQuery = useWalletPortfoliosByTokensQuery(\n { chain, address: walletAddress, tokenAddresses },\n {\n enabled: !!walletAddress && tokenAddresses.length > 0,\n refetchInterval: BALANCE_POLL_MS,\n },\n );\n\n const fromBalance = useMemo(\n () =>\n balancesQuery.data?.find((p) => p.address === fromTokenAddress) ?? null,\n [balancesQuery.data, fromTokenAddress],\n );\n const toBalance = useMemo(\n () => balancesQuery.data?.find((p) => p.address === toTokenAddress) ?? null,\n [balancesQuery.data, toTokenAddress],\n );\n\n // ── Amount ────────────────────────────────────────────────────────────────\n\n const [amount, setAmount] = useState<string | undefined>(undefined);\n\n const amountInDecimals = useMemo(() => {\n if (!amount || fromToken?.decimals == null) return undefined;\n const parts = amount.split(\".\");\n const intPart = parts[0] ?? \"0\";\n const fracPart = (parts[1] ?? \"\").slice(0, fromToken.decimals);\n const padded = fracPart.padEnd(fromToken.decimals, \"0\");\n const raw = intPart + padded;\n return raw.replace(/^0+/, \"\") || \"0\";\n }, [amount, fromToken?.decimals]);\n\n const amountInUsd = useMemo(() => {\n if (!amount || !fromToken?.marketData?.priceInUsd) return undefined;\n const price = Number(fromToken.marketData.priceInUsd);\n const value = Number(amount) * price;\n return Number.isFinite(value) ? value.toString() : undefined;\n }, [amount, fromToken?.marketData?.priceInUsd]);\n\n // ── Half / Max helpers ────────────────────────────────────────────────────\n\n const setHalfAmount = useCallback(() => {\n if (!fromBalance) return;\n const bal = Number(fromBalance.amount);\n if (!Number.isFinite(bal) || bal <= 0) return;\n const half = bal / 2;\n const decimals = fromToken?.decimals ?? 9;\n setAmount(\n half.toLocaleString(\"en-US\", {\n useGrouping: false,\n maximumFractionDigits: decimals,\n }),\n );\n }, [fromBalance, fromToken?.decimals]);\n\n const setMaxAmount = useCallback(() => {\n if (!fromBalance) return;\n const bal = Number(fromBalance.amount);\n if (!Number.isFinite(bal) || bal <= 0) return;\n const decimals = fromToken?.decimals ?? 9;\n setAmount(\n bal.toLocaleString(\"en-US\", {\n useGrouping: false,\n maximumFractionDigits: decimals,\n }),\n );\n }, [fromBalance, fromToken?.decimals]);\n\n // ── Route polling ─────────────────────────────────────────────────────────\n\n const routeParams = useMemo<Partial<API.SwapParams>>(\n () => ({\n chain,\n userAddress: walletAddress || undefined,\n input: fromTokenAddress || undefined,\n output: toTokenAddress || undefined,\n mode: API.SwapMode.EXACT_IN,\n amount: amountInDecimals,\n }),\n [chain, walletAddress, fromTokenAddress, toTokenAddress, amountInDecimals],\n );\n\n const isSwappingRef = useRef(false);\n\n const {\n route,\n isRouting,\n error: routeError,\n } = useSwapRoutePolling(routeParams, { paused: isSwappingRef.current });\n\n // ── Output amount ─────────────────────────────────────────────────────────\n\n const outputAmount = useMemo(\n () =>\n route && toToken\n ? formatOutputAmount(route.plans, toToken.decimals)\n : undefined,\n [route, toToken],\n );\n\n const outputAmountInUsd = useMemo(() => {\n if (!outputAmount || !toToken?.marketData?.priceInUsd) return undefined;\n const price = Number(toToken.marketData.priceInUsd);\n const value = Number(outputAmount) * price;\n return Number.isFinite(value) ? value.toString() : undefined;\n }, [outputAmount, toToken?.marketData?.priceInUsd]);\n\n // ── Swap execution ────────────────────────────────────────────────────────\n\n const { swap: rawSwap, isSwapping } = useSwap();\n isSwappingRef.current = isSwapping;\n\n const onCompleteRef = useRef(params.onComplete);\n onCompleteRef.current = params.onComplete;\n\n const { track, transactions } = useTxConfirmation({\n onConfirmed: (txHash) => {\n onCompleteRef.current?.({ success: true, txHash });\n },\n onFailed: (txHash) => {\n onCompleteRef.current?.({ success: false, txHash });\n },\n });\n\n const latestTxStatus = useMemo(() => {\n if (transactions.size === 0) return \"idle\" as const;\n const entries = Array.from(transactions.values());\n return entries[entries.length - 1]!.status;\n }, [transactions]);\n\n const swap = useCallback(async () => {\n if (\n !wallet ||\n !route ||\n !fromTokenAddress ||\n !toTokenAddress ||\n !amountInDecimals\n ) {\n return;\n }\n\n try {\n const result = await rawSwap({\n chain,\n wallet,\n input: fromTokenAddress,\n output: toTokenAddress,\n amount: amountInDecimals,\n mode: API.SwapMode.EXACT_IN,\n });\n track(chain, result.txHash);\n } catch {\n // Error is already reported via useSwap's onError callback\n }\n }, [\n wallet,\n route,\n chain,\n fromTokenAddress,\n toTokenAddress,\n amountInDecimals,\n rawSwap,\n track,\n ]);\n\n // ── Loading state ─────────────────────────────────────────────────────────\n\n const isLoading = tokensQuery.isPending || balancesQuery.isPending;\n\n // ── Return ────────────────────────────────────────────────────────────────\n\n return useMemo(\n () => ({\n fromTokenAddress,\n toTokenAddress,\n setFromTokenAddress,\n setToTokenAddress,\n\n fromToken,\n toToken,\n\n fromBalance,\n toBalance,\n\n amount,\n setAmount,\n setHalfAmount,\n setMaxAmount,\n amountInDecimals,\n amountInUsd,\n\n outputAmount,\n outputAmountInUsd,\n\n route,\n isRouting,\n routeError,\n\n swap,\n isSwapping,\n\n txStatus: latestTxStatus,\n\n isLoading,\n }),\n [\n fromTokenAddress,\n toTokenAddress,\n fromToken,\n toToken,\n fromBalance,\n toBalance,\n amount,\n setHalfAmount,\n setMaxAmount,\n amountInDecimals,\n amountInUsd,\n outputAmount,\n outputAmountInUsd,\n route,\n isRouting,\n routeError,\n swap,\n isSwapping,\n latestTxStatus,\n isLoading,\n ],\n );\n}\n","import { useCallback, useMemo, useState } from \"react\";\nimport {\n Avatar,\n Button,\n ChevronDownIcon,\n ChevronUpIcon,\n cn,\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n TradeIcon,\n} from \"@liberfi.io/ui\";\nimport type { SwapPreviewModalProps } from \"./types\";\n\n/**\n * Modal that previews swap details before confirmation.\n *\n * Pure presentational — all data and callbacks received via props.\n * Shows from/to token cards, expandable route plan details,\n * and a confirm button.\n */\nexport function SwapPreviewModal({\n isOpen,\n onOpenChange,\n fromToken,\n toToken,\n fromBalance,\n inputAmount,\n inputAmountInUsd,\n outputAmount,\n outputAmountInUsd,\n route,\n isRouting,\n routeError,\n onConfirm,\n isSwapping,\n}: SwapPreviewModalProps) {\n const [expanded, setExpanded] = useState(false);\n const toggleExpanded = useCallback(() => setExpanded((prev) => !prev), []);\n\n const plans = useMemo(() => {\n if (!route) return [];\n return route.plans.map((plan, i) => ({\n key: `plan-${i}`,\n name: plan.name,\n input: plan.input,\n inputAmount: plan.inputAmount,\n output: plan.output,\n outputAmount: plan.outputAmount,\n feeQuote: plan.feeQuote,\n feeAmount: plan.feeAmount,\n }));\n }, [route]);\n\n return (\n <Modal\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n hideCloseButton\n scrollBehavior=\"inside\"\n backdrop=\"blur\"\n >\n <ModalContent className=\"bg-content2 rounded-lg\">\n <ModalHeader>Preview</ModalHeader>\n <ModalBody>\n <div className=\"flex w-full max-h-[70vh] flex-1 flex-col overflow-y-auto py-2\">\n {/* ── From preview ─────────────────────────────────────────── */}\n <div className=\"mb-5\">\n <div className=\"text-neutral flex items-center justify-between text-xs font-medium\">\n From\n </div>\n <div className=\"bg-content3 mt-3 flex w-full items-center gap-3 rounded-lg px-4 py-3\">\n <div className=\"flex flex-1 items-center gap-3\">\n {fromToken?.image && (\n <Avatar\n size=\"sm\"\n src={fromToken.image}\n name={fromToken.symbol}\n className=\"h-6 w-6\"\n />\n )}\n <div className=\"flex flex-col items-start justify-center gap-0.5\">\n <div className=\"text-foreground text-xs\">\n {fromToken?.symbol ?? \"—\"}\n </div>\n {fromBalance && (\n <div className=\"text-neutral flex items-center gap-1 text-[10px]\">\n <WalletBalanceIcon />\n <span>\n {formatNumber(fromBalance.amount)} {fromToken?.symbol}\n </span>\n </div>\n )}\n </div>\n </div>\n <div className=\"flex-0 flex flex-col items-end justify-center gap-0.5\">\n <div className=\"text-foreground text-xs\">\n {formatNumber(inputAmount)}\n </div>\n <div className=\"text-neutral text-[10px]\">\n ${formatUsd(inputAmountInUsd)}\n </div>\n </div>\n </div>\n </div>\n\n {/* ── To preview ───────────────────────────────────────────── */}\n <div className=\"mb-5\">\n <div className=\"text-neutral flex items-center justify-between text-xs font-medium\">\n Estimated Receive\n </div>\n <div className=\"bg-content3 mt-3 flex w-full items-center gap-3 rounded-lg px-4 py-3\">\n <div className=\"flex flex-1 items-center gap-3\">\n {toToken?.image && (\n <Avatar\n size=\"sm\"\n src={toToken.image}\n name={toToken.symbol}\n className=\"h-6 w-6\"\n />\n )}\n <div className=\"flex flex-col items-start justify-center gap-0.5\">\n <div className=\"text-foreground text-xs\">\n {toToken?.symbol ?? \"—\"}\n </div>\n <div className=\"text-neutral text-[10px]\">\n {truncateAddress(toToken?.address)}\n </div>\n </div>\n </div>\n <div className=\"flex-0 flex flex-col items-end justify-center gap-0.5\">\n <div className=\"text-foreground text-xs\">\n {formatNumber(outputAmount)}\n </div>\n <div className=\"text-neutral text-[10px]\">\n ${formatUsd(outputAmountInUsd)}\n </div>\n </div>\n </div>\n </div>\n\n {/* ── Route plan details ───────────────────────────────────── */}\n {expanded && plans.length > 0 && (\n <div className=\"my-3\">\n <div className=\"text-neutral flex items-center justify-between text-xs font-medium\">\n Route Details\n </div>\n <div className=\"mt-3 flex flex-col gap-3\">\n {plans.map((plan) => (\n <div\n key={plan.key}\n className=\"bg-content3 flex w-full flex-col items-center gap-2 rounded-lg px-4 py-3\"\n >\n <div className=\"flex w-full items-center justify-between\">\n <div className=\"text-neutral text-xs\">DEX</div>\n <div className=\"text-foreground text-xs\">\n {plan.name}\n </div>\n </div>\n <div className=\"flex w-full items-center justify-between\">\n <div className=\"text-neutral text-xs\">Swap</div>\n <div className=\"text-foreground flex items-center gap-2 text-xs\">\n <span>\n {formatSmallAmount(plan.inputAmount)}{\" \"}\n {truncateAddress(plan.input)}\n </span>\n <TradeIcon\n width={12}\n height={12}\n className=\"text-foreground\"\n />\n <span>\n {formatSmallAmount(plan.outputAmount)}{\" \"}\n {truncateAddress(plan.output)}\n </span>\n </div>\n </div>\n {plan.feeAmount && (\n <div className=\"flex w-full items-center justify-between\">\n <div className=\"text-neutral text-xs\">Fee</div>\n <div className=\"text-foreground text-xs\">\n {formatSmallAmount(plan.feeAmount)}{\" \"}\n {truncateAddress(plan.feeQuote)}\n </div>\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* ── Expand / collapse toggle ─────────────────────────────── */}\n {plans.length > 0 && (\n <div className=\"flex justify-center\">\n <Button\n size=\"sm\"\n className=\"text-neutral flex bg-transparent text-xs\"\n endContent={\n expanded ? (\n <ChevronUpIcon width={12} height={12} />\n ) : (\n <ChevronDownIcon width={12} height={12} />\n )\n }\n disableRipple\n onPress={toggleExpanded}\n >\n {expanded ? \"Show Less\" : \"Show More\"}\n </Button>\n </div>\n )}\n </div>\n </ModalBody>\n <ModalFooter>\n <Button\n fullWidth\n color=\"primary\"\n className=\"flex rounded-lg\"\n disableRipple\n isDisabled={!route || !!routeError}\n isLoading={(!route && isRouting) || isSwapping}\n onPress={onConfirm}\n >\n Confirm\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\nfunction WalletBalanceIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={12}\n height={12}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-neutral\"\n >\n <path d=\"M21 12V7H5a2 2 0 0 1 0-4h14v4\" />\n <path d=\"M3 5v14a2 2 0 0 0 2 2h16v-5\" />\n <path d=\"M18 12a2 2 0 0 0 0 4h4v-4Z\" />\n </svg>\n );\n}\n\nfunction formatUsd(value: string | undefined): string {\n if (!value) return \"0.00\";\n const n = Number(value);\n if (!Number.isFinite(n)) return \"0.00\";\n return n.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n}\n\nfunction formatNumber(value: string | undefined): string {\n if (!value) return \"0\";\n const n = Number(value);\n if (!Number.isFinite(n)) return \"0\";\n if (n >= 1_000_000)\n return (\n (n / 1_000_000).toLocaleString(\"en-US\", {\n maximumFractionDigits: 2,\n }) + \"M\"\n );\n if (n >= 1_000)\n return (\n (n / 1_000).toLocaleString(\"en-US\", { maximumFractionDigits: 2 }) + \"K\"\n );\n return n.toLocaleString(\"en-US\", { maximumFractionDigits: 6 });\n}\n\n/** Render raw smallest-unit amounts in abbreviated form. */\nfunction formatSmallAmount(value: string | undefined): string {\n if (!value || value === \"0\") return \"0\";\n const n = Number(value);\n if (!Number.isFinite(n)) return value;\n if (n >= 1e12) return (n / 1e12).toFixed(2) + \"T\";\n if (n >= 1e9) return (n / 1e9).toFixed(2) + \"B\";\n if (n >= 1e6) return (n / 1e6).toFixed(2) + \"M\";\n if (n >= 1e3) return (n / 1e3).toFixed(2) + \"K\";\n return value;\n}\n\nfunction truncateAddress(addr: string | undefined): string {\n if (!addr) return \"—\";\n if (addr.length <= 10) return addr;\n return `${addr.slice(0, 4)}...${addr.slice(-4)}`;\n}\n","import { Avatar, Button, ChevronDownIcon, cn, Input } from \"@liberfi.io/ui\";\nimport type { SwapUIProps } from \"./types\";\n\n/**\n * Pure presentational component for the swap form.\n *\n * Receives all data and callbacks via props — no API calls, no subscriptions.\n * Consumers can replace this component entirely while reusing `useSwapScript`.\n */\nexport function SwapUI({\n fromToken,\n toToken,\n fromBalance,\n toBalance,\n amount,\n amountInUsd,\n onAmountChange,\n onHalfAmount,\n onMaxAmount,\n outputAmount,\n outputAmountInUsd,\n onFromTokenSelect,\n onToTokenSelect,\n route,\n isRouting,\n routeError,\n onPreview,\n isSwapping,\n className,\n}: SwapUIProps) {\n return (\n <div className={cn(\"px-4 pb-4 lg:pb-8\", className)}>\n {/* ── From token section ─────────────────────────────────────────── */}\n <div className=\"space-y-3\">\n <p className=\"text-neutral text-sm font-medium\">From</p>\n <div className=\"bg-content1 flex flex-col rounded-lg px-3.5 pb-2.5 pt-2\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex-1\">\n <Input\n type=\"number\"\n value={amount ?? \"\"}\n onChange={(e) => onAmountChange(e.target.value || undefined)}\n placeholder=\"0\"\n classNames={{\n inputWrapper: cn(\n \"h-10 p-0 bg-transparent\",\n \"data-[hover=true]:bg-transparent group-data-[focus=true]:bg-transparent\",\n \"group-data-[focus-visible=true]:ring-offset-transparent group-data-[focus-visible=true]:ring-transparent\",\n ),\n input: cn(\n \"w-full h-full caret-primary text-3xl font-medium\",\n \"placeholder:text-placeholder placeholder:text-3xl placeholder:font-medium\",\n \"scrollbar-hide overflow-hidden text-ellipsis whitespace-nowrap\",\n ),\n }}\n />\n </div>\n <div className=\"flex-0 flex h-full items-center justify-center\">\n <Button\n className={cn(\n \"flex min-w-0 h-8 min-h-8 pl-3 pr-2 bg-content3 rounded-full\",\n fromToken ? \"text-foreground\" : \"text-neutral\",\n )}\n disableRipple\n startContent={\n fromToken?.image ? (\n <Avatar\n size=\"sm\"\n src={fromToken.image}\n name={fromToken.symbol}\n className=\"h-6 w-6\"\n />\n ) : null\n }\n endContent={\n <ChevronDownIcon\n width={16}\n height={16}\n className=\"text-neutral\"\n />\n }\n onPress={() => onFromTokenSelect(\"\")}\n >\n {fromToken ? fromToken.symbol : \"Select token\"}\n </Button>\n </div>\n </div>\n\n <div className=\"mt-3 flex items-center justify-between gap-4\">\n <div className=\"text-neutral flex-1 text-xs\">\n ≈ ${formatUsd(amountInUsd)}\n </div>\n {fromBalance && (\n <div className=\"flex-0 flex items-center gap-2 pr-3 text-xs\">\n <WalletBalanceIcon />\n <span className=\"text-neutral\">\n {formatNumber(fromBalance.amount)} {fromBalance.symbol}\n </span>\n {onHalfAmount && (\n <span\n className=\"text-primary cursor-pointer\"\n onClick={onHalfAmount}\n >\n Half\n </span>\n )}\n {onMaxAmount && (\n <span\n className=\"text-primary cursor-pointer\"\n onClick={onMaxAmount}\n >\n Max\n </span>\n )}\n </div>\n )}\n </div>\n\n {routeError && (\n <p className=\"mt-1 break-words text-xs text-danger-500\">\n {routeError.message}\n </p>\n )}\n </div>\n </div>\n\n {/* ── To token section ───────────────────────────────────────────── */}\n <div className=\"mt-4 space-y-3\">\n <p className=\"text-neutral text-sm font-medium\">To</p>\n <div className=\"bg-content1 flex flex-col rounded-lg px-3.5 pb-2.5 pt-2\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex-1\">\n <Input\n type=\"number\"\n value={outputAmount ?? \"\"}\n disabled\n placeholder=\"0\"\n classNames={{\n inputWrapper: cn(\n \"h-10 p-0 bg-transparent\",\n \"data-[hover=true]:bg-transparent group-data-[focus=true]:bg-transparent\",\n \"group-data-[focus-visible=true]:ring-offset-transparent group-data-[focus-visible=true]:ring-transparent\",\n ),\n input: cn(\n \"w-full h-full caret-primary text-3xl font-medium\",\n \"placeholder:text-placeholder placeholder:text-3xl placeholder:font-medium\",\n \"scrollbar-hide overflow-hidden text-ellipsis whitespace-nowrap\",\n ),\n }}\n />\n </div>\n <div className=\"flex-0 flex h-full items-center justify-center\">\n <Button\n className={cn(\n \"flex min-w-0 h-8 min-h-8 pl-3 pr-2 bg-content3 rounded-full\",\n toToken ? \"text-foreground\" : \"text-neutral\",\n )}\n disableRipple\n startContent={\n toToken?.image ? (\n <Avatar\n size=\"sm\"\n src={toToken.image}\n name={toToken.symbol}\n className=\"h-6 w-6\"\n />\n ) : null\n }\n endContent={\n <ChevronDownIcon\n width={16}\n height={16}\n className=\"text-neutral\"\n />\n }\n onPress={() => onToTokenSelect(\"\")}\n >\n {toToken ? toToken.symbol : \"Select token\"}\n </Button>\n </div>\n </div>\n\n <div className=\"mt-3 flex items-center justify-between gap-4\">\n <div className=\"text-neutral flex-1 text-xs\">\n ≈ ${formatUsd(outputAmountInUsd)}\n </div>\n {toBalance && (\n <div className=\"flex-0 flex items-center gap-2 pr-3 text-xs\">\n <WalletBalanceIcon />\n <span className=\"text-neutral\">\n {formatNumber(toBalance.amount)} {toBalance.symbol}\n </span>\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* ── Submit button ──────────────────────────────────────────────── */}\n <Button\n fullWidth\n color=\"primary\"\n className=\"mt-8 flex rounded-lg\"\n disableRipple\n isDisabled={!route}\n isLoading={!route && isRouting}\n onPress={onPreview}\n >\n {isSwapping ? \"Swapping...\" : isRouting ? \"Finding route...\" : \"Swap\"}\n </Button>\n </div>\n );\n}\n\nfunction WalletBalanceIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={12}\n height={12}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-neutral\"\n >\n <path d=\"M21 12V7H5a2 2 0 0 1 0-4h14v4\" />\n <path d=\"M3 5v14a2 2 0 0 0 2 2h16v-5\" />\n <path d=\"M18 12a2 2 0 0 0 0 4h4v-4Z\" />\n </svg>\n );\n}\n\nfunction formatUsd(value: string | undefined): string {\n if (!value) return \"0.00\";\n const n = Number(value);\n if (!Number.isFinite(n)) return \"0.00\";\n return n.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n}\n\nfunction formatNumber(value: string | undefined): string {\n if (!value) return \"0\";\n const n = Number(value);\n if (!Number.isFinite(n)) return \"0\";\n if (n >= 1_000_000)\n return (\n (n / 1_000_000).toLocaleString(\"en-US\", { maximumFractionDigits: 2 }) +\n \"M\"\n );\n if (n >= 1_000)\n return (\n (n / 1_000).toLocaleString(\"en-US\", { maximumFractionDigits: 2 }) + \"K\"\n );\n return n.toLocaleString(\"en-US\", { maximumFractionDigits: 6 });\n}\n","import { useCallback } from \"react\";\nimport { useDisclosure } from \"@liberfi.io/ui\";\nimport { SwapPreviewModal } from \"./swap-preview-modal\";\nimport { useSwapScript } from \"./swap.script\";\nimport { SwapUI } from \"./swap.ui\";\nimport type { SwapWidgetProps } from \"./types\";\n\n/**\n * Swap widget — thin orchestration layer.\n *\n * Calls `useSwapScript` to fetch all data, renders `SwapUI` for the form\n * and `SwapPreviewModal` for pre-swap confirmation.\n *\n * For custom UIs, use `useSwapScript` directly with your own presentation.\n */\nexport function SwapWidget({\n chain,\n from,\n to,\n onComplete,\n className,\n}: SwapWidgetProps) {\n const script = useSwapScript({ chain, from, to, onComplete });\n const { isOpen, onOpen, onOpenChange, onClose } = useDisclosure();\n\n const handleConfirm = useCallback(async () => {\n await script.swap();\n onClose();\n }, [script, onClose]);\n\n return (\n <>\n <SwapUI\n fromToken={script.fromToken}\n toToken={script.toToken}\n fromBalance={script.fromBalance}\n toBalance={script.toBalance}\n amount={script.amount}\n amountInUsd={script.amountInUsd}\n onAmountChange={script.setAmount}\n onHalfAmount={script.setHalfAmount}\n onMaxAmount={script.setMaxAmount}\n outputAmount={script.outputAmount}\n outputAmountInUsd={script.outputAmountInUsd}\n onFromTokenSelect={script.setFromTokenAddress}\n onToTokenSelect={script.setToTokenAddress}\n route={script.route}\n isRouting={script.isRouting}\n routeError={script.routeError}\n onPreview={onOpen}\n isSwapping={script.isSwapping}\n className={className}\n />\n <SwapPreviewModal\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n fromToken={script.fromToken}\n toToken={script.toToken}\n fromBalance={script.fromBalance}\n inputAmount={script.amount}\n inputAmountInUsd={script.amountInUsd}\n outputAmount={script.outputAmount}\n outputAmountInUsd={script.outputAmountInUsd}\n route={script.route}\n isRouting={script.isRouting}\n routeError={script.routeError}\n onConfirm={handleConfirm}\n isSwapping={script.isSwapping}\n />\n </>\n );\n}\n","declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-trade\"] = \"0.1.2\";\n}\n\nexport default \"0.1.2\";\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {useState,useRef,useCallback,useMemo}from'react';import {useDexClient}from'@liberfi.io/react';import {API}from'@liberfi.io/types';function I(p){let o=atob(p),i=new Uint8Array(o.length);for(let s=0;s<o.length;s++)i[s]=o.charCodeAt(s);return i}function R(p){let o="";for(let i=0;i<p.length;i++)o+=String.fromCharCode(p[i]);return btoa(o)}function k(p){let{client:o}=useDexClient(),[i,s]=useState(false),u=useRef(p);u.current=p;let l=useCallback(async w=>{let{wallet:d,chain:m,...t}=w;s(true);try{let e;try{e=await o.swapRoute({chain:m,userAddress:d.address,input:t.input,output:t.output,mode:t.mode??API.SwapMode.EXACT_IN,amount:t.amount,slippage:t.slippage,priorityFee:t.priorityFee,tipFee:t.tipFee,isAntiMev:t.isAntiMev,permit:t.permit,deadline:t.deadline});}catch(n){let f=n instanceof Error?n:new Error(String(n));throw u.current?.onError?.(f,"route"),f}let a;try{let n=I(e.serializedTx);a=await d.signTransaction(n);}catch(n){let f=n instanceof Error?n:new Error(String(n));throw u.current?.onError?.(f,"sign"),f}let r;try{let n=R(a);r=await o.sendTx({chain:m,serializedTx:n});}catch(n){let f=n instanceof Error?n:new Error(String(n));throw u.current?.onError?.(f,"send"),f}let c={txHash:r.txHash,extra:r.extra};return u.current?.onSubmitted?.(c),c}finally{s(false);}},[o]);return useMemo(()=>({swap:l,isSwapping:i}),[l,i])}var F=6e4;function V(p){let{client:o}=useDexClient(),[i,s]=useState(()=>new Map),u=useRef(p);u.current=p;let l=useCallback((t,e)=>{s(a=>{let r=a.get(t);if(!r||r.status===e)return a;let c=new Map(a);return c.set(t,{...r,status:e}),c});},[]),w=useCallback((t,e)=>{s(r=>{if(r.has(e))return r;let c=new Map(r);return c.set(e,{chain:t,txHash:e,status:"pending"}),c});let a=u.current?.timeout??F;o.checkTxSuccess(t,e,a).then(r=>{if(r)l(e,"confirmed"),u.current?.onConfirmed?.(e);else {let c=new Error("Transaction failed on-chain");l(e,"failed"),u.current?.onFailed?.(e,c);}}).catch(r=>{let c=r instanceof Error?r:new Error(String(r));l(e,"failed"),u.current?.onFailed?.(e,c);});},[o,l]),d=useCallback(t=>{s(e=>{if(!e.has(t))return e;let a=new Map(e);return a.delete(t),a});},[]),m=useCallback(()=>{s(t=>t.size===0?t:new Map);},[]);return useMemo(()=>({track:w,clear:d,clearAll:m,transactions:i}),[w,d,m,i])}typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-trade"]="0.1.1");var U="0.1.1";export{k as useSwap,V as useTxConfirmation,U as version};//# sourceMappingURL=index.mjs.map
|
|
1
|
+
import {useState,useRef,useCallback,useMemo,useEffect}from'react';import {useDexClient,useSwapRouteQuery,useTokensQuery,useWalletPortfoliosByTokensQuery}from'@liberfi.io/react';import {Chain,API,ChainNamespace}from'@liberfi.io/types';import {useWallets}from'@liberfi.io/wallet-connector';import {Modal,ModalContent,ModalHeader,ModalBody,Avatar,TradeIcon,Button,ChevronUpIcon,ChevronDownIcon,ModalFooter,cn,Input,useDisclosure}from'@liberfi.io/ui';import {jsx,jsxs,Fragment}from'react/jsx-runtime';function Fe(e){let t=atob(e),u=new Uint8Array(t.length);for(let i=0;i<t.length;i++)u[i]=t.charCodeAt(i);return u}function Me(e){let t="";for(let u=0;u<e.length;u++)t+=String.fromCharCode(e[u]);return btoa(t)}function ie(e){let{client:t}=useDexClient(),[u,i]=useState(false),a=useRef(e);a.current=e;let n=useCallback(async d=>{let{wallet:m,chain:p,...r}=d;i(true);try{let l;try{l=await t.swapRoute({chain:p,userAddress:m.address,input:r.input,output:r.output,mode:r.mode??API.SwapMode.EXACT_IN,amount:r.amount,slippage:r.slippage,priorityFee:r.priorityFee,tipFee:r.tipFee,isAntiMev:r.isAntiMev,permit:r.permit,deadline:r.deadline});}catch(s){let S=s instanceof Error?s:new Error(String(s));throw a.current?.onError?.(S,"route"),S}let h;try{let s=Fe(l.serializedTx);h=await m.signTransaction(s);}catch(s){let S=s instanceof Error?s:new Error(String(s));throw a.current?.onError?.(S,"sign"),S}let f;try{let s=Me(h);f=await t.sendTx({chain:p,serializedTx:s});}catch(s){let S=s instanceof Error?s:new Error(String(s));throw a.current?.onError?.(S,"send"),S}let w={txHash:f.txHash,extra:f.extra};return a.current?.onSubmitted?.(w),w}finally{i(false);}},[t]);return useMemo(()=>({swap:n,isSwapping:u}),[n,u])}var Le=12e3;function ae(e,t){let u=t?.interval??Le,i=t?.paused??false,a=useRef(t);a.current=t;let d=!!e.chain&&!!e.userAddress&&!!e.input&&!!e.output&&!!e.amount&&!i,m=useSwapRouteQuery(e,{enabled:d,refetchInterval:d?u:false,retry:false});return useEffect(()=>{m.error&&a.current?.onError?.(m.error);},[m.error]),useMemo(()=>({route:m.data,isRouting:m.isFetching,error:m.error}),[m.data,m.isFetching,m.error])}var je=6e4;function ue(e){let{client:t}=useDexClient(),[u,i]=useState(()=>new Map),a=useRef(e);a.current=e;let n=useCallback((r,l)=>{i(h=>{let f=h.get(r);if(!f||f.status===l)return h;let w=new Map(h);return w.set(r,{...f,status:l}),w});},[]),d=useCallback((r,l)=>{i(f=>{if(f.has(l))return f;let w=new Map(f);return w.set(l,{chain:r,txHash:l,status:"pending"}),w});let h=a.current?.timeout??je;t.checkTxSuccess(r,l,h).then(f=>{if(f)n(l,"confirmed"),a.current?.onConfirmed?.(l);else {let w=new Error("Transaction failed on-chain");n(l,"failed"),a.current?.onFailed?.(l,w);}}).catch(f=>{let w=f instanceof Error?f:new Error(String(f));n(l,"failed"),a.current?.onFailed?.(l,w);});},[t,n]),m=useCallback(r=>{i(l=>{if(!l.has(r))return l;let h=new Map(l);return h.delete(r),h});},[]),p=useCallback(()=>{i(r=>r.size===0?r:new Map);},[]);return useMemo(()=>({track:d,clear:m,clearAll:p,transactions:u}),[d,m,p,u])}var Qe=new Set([Chain.SOLANA,Chain.SOLANA_TESTNET,Chain.SOLANA_DEVNET]);function Ke(e){return Qe.has(e)?ChainNamespace.SOLANA:ChainNamespace.EVM}var Xe=1e4,qe=15e3;function Ge(e,t){if(e.length===0)return;let i=e[e.length-1].outputAmount;if(!i||i==="0")return "0";let a=i.padStart(t+1,"0"),n=a.slice(0,a.length-t)||"0",m=a.slice(a.length-t).replace(/0+$/,"");return m?`${n}.${m}`:n}function j(e){let{chain:t}=e,u=useWallets(),i=Ke(t),a=useMemo(()=>u.find(o=>o.chainNamespace===i&&o.isConnected),[u,i]),n=a?.address??"",[d,m]=useState(e.from??""),[p,r]=useState(e.to??""),l=useRef(e.from),h=useRef(e.to);useEffect(()=>{e.from!==l.current&&(l.current=e.from,e.from&&m(e.from));},[e.from]),useEffect(()=>{e.to!==h.current&&(h.current=e.to,e.to&&r(e.to));},[e.to]);let f=useMemo(()=>[d,p].filter(Boolean),[d,p]),w=useTokensQuery({chain:t,addresses:f},{enabled:f.length>0,refetchInterval:Xe}),s=useMemo(()=>w.data?.find(o=>o.address===d)??null,[w.data,d]),S=useMemo(()=>w.data?.find(o=>o.address===p)??null,[w.data,p]),C=useWalletPortfoliosByTokensQuery({chain:t,address:n,tokenAddresses:f},{enabled:!!n&&f.length>0,refetchInterval:qe}),b=useMemo(()=>C.data?.find(o=>o.address===d)??null,[C.data,d]),g=useMemo(()=>C.data?.find(o=>o.address===p)??null,[C.data,p]),[A,T]=useState(void 0),P=useMemo(()=>{if(!A||s?.decimals==null)return;let o=A.split("."),I=o[0]??"0",ye=(o[1]??"").slice(0,s.decimals).padEnd(s.decimals,"0");return (I+ye).replace(/^0+/,"")||"0"},[A,s?.decimals]),X=useMemo(()=>{if(!A||!s?.marketData?.priceInUsd)return;let o=Number(s.marketData.priceInUsd),I=Number(A)*o;return Number.isFinite(I)?I.toString():void 0},[A,s?.marketData?.priceInUsd]),q=useCallback(()=>{if(!b)return;let o=Number(b.amount);if(!Number.isFinite(o)||o<=0)return;let I=o/2,oe=s?.decimals??9;T(I.toLocaleString("en-US",{useGrouping:false,maximumFractionDigits:oe}));},[b,s?.decimals]),G=useCallback(()=>{if(!b)return;let o=Number(b.amount);if(!Number.isFinite(o)||o<=0)return;let I=s?.decimals??9;T(o.toLocaleString("en-US",{useGrouping:false,maximumFractionDigits:I}));},[b,s?.decimals]),be=useMemo(()=>({chain:t,userAddress:n||void 0,input:d||void 0,output:p||void 0,mode:API.SwapMode.EXACT_IN,amount:P}),[t,n,d,p,P]),Z=useRef(false),{route:U,isRouting:H,error:J}=ae(be,{paused:Z.current}),F=useMemo(()=>U&&S?Ge(U.plans,S.decimals):void 0,[U,S]),Y=useMemo(()=>{if(!F||!S?.marketData?.priceInUsd)return;let o=Number(S.marketData.priceInUsd),I=Number(F)*o;return Number.isFinite(I)?I.toString():void 0},[F,S?.marketData?.priceInUsd]),{swap:ee,isSwapping:k}=ie();Z.current=k;let L=useRef(e.onComplete);L.current=e.onComplete;let{track:te,transactions:D}=ue({onConfirmed:o=>{L.current?.({success:true,txHash:o});},onFailed:o=>{L.current?.({success:false,txHash:o});}}),ne=useMemo(()=>{if(D.size===0)return "idle";let o=Array.from(D.values());return o[o.length-1].status},[D]),re=useCallback(async()=>{if(!(!a||!U||!d||!p||!P))try{let o=await ee({chain:t,wallet:a,input:d,output:p,amount:P,mode:API.SwapMode.EXACT_IN});te(t,o.txHash);}catch{}},[a,U,t,d,p,P,ee,te]),se=w.isPending||C.isPending;return useMemo(()=>({fromTokenAddress:d,toTokenAddress:p,setFromTokenAddress:m,setToTokenAddress:r,fromToken:s,toToken:S,fromBalance:b,toBalance:g,amount:A,setAmount:T,setHalfAmount:q,setMaxAmount:G,amountInDecimals:P,amountInUsd:X,outputAmount:F,outputAmountInUsd:Y,route:U,isRouting:H,routeError:J,swap:re,isSwapping:k,txStatus:ne,isLoading:se}),[d,p,s,S,b,g,A,q,G,P,X,F,Y,U,H,J,re,k,ne,se])}function V({isOpen:e,onOpenChange:t,fromToken:u,toToken:i,fromBalance:a,inputAmount:n,inputAmountInUsd:d,outputAmount:m,outputAmountInUsd:p,route:r,isRouting:l,routeError:h,onConfirm:f,isSwapping:w}){let[s,S]=useState(false),C=useCallback(()=>S(g=>!g),[]),b=useMemo(()=>r?r.plans.map((g,A)=>({key:`plan-${A}`,name:g.name,input:g.input,inputAmount:g.inputAmount,output:g.output,outputAmount:g.outputAmount,feeQuote:g.feeQuote,feeAmount:g.feeAmount})):[],[r]);return jsx(Modal,{isOpen:e,onOpenChange:t,hideCloseButton:true,scrollBehavior:"inside",backdrop:"blur",children:jsxs(ModalContent,{className:"bg-content2 rounded-lg",children:[jsx(ModalHeader,{children:"Preview"}),jsx(ModalBody,{children:jsxs("div",{className:"flex w-full max-h-[70vh] flex-1 flex-col overflow-y-auto py-2",children:[jsxs("div",{className:"mb-5",children:[jsx("div",{className:"text-neutral flex items-center justify-between text-xs font-medium",children:"From"}),jsxs("div",{className:"bg-content3 mt-3 flex w-full items-center gap-3 rounded-lg px-4 py-3",children:[jsxs("div",{className:"flex flex-1 items-center gap-3",children:[u?.image&&jsx(Avatar,{size:"sm",src:u.image,name:u.symbol,className:"h-6 w-6"}),jsxs("div",{className:"flex flex-col items-start justify-center gap-0.5",children:[jsx("div",{className:"text-foreground text-xs",children:u?.symbol??"\u2014"}),a&&jsxs("div",{className:"text-neutral flex items-center gap-1 text-[10px]",children:[jsx(at,{}),jsxs("span",{children:[$(a.amount)," ",u?.symbol]})]})]})]}),jsxs("div",{className:"flex-0 flex flex-col items-end justify-center gap-0.5",children:[jsx("div",{className:"text-foreground text-xs",children:$(n)}),jsxs("div",{className:"text-neutral text-[10px]",children:["$",fe(d)]})]})]})]}),jsxs("div",{className:"mb-5",children:[jsx("div",{className:"text-neutral flex items-center justify-between text-xs font-medium",children:"Estimated Receive"}),jsxs("div",{className:"bg-content3 mt-3 flex w-full items-center gap-3 rounded-lg px-4 py-3",children:[jsxs("div",{className:"flex flex-1 items-center gap-3",children:[i?.image&&jsx(Avatar,{size:"sm",src:i.image,name:i.symbol,className:"h-6 w-6"}),jsxs("div",{className:"flex flex-col items-start justify-center gap-0.5",children:[jsx("div",{className:"text-foreground text-xs",children:i?.symbol??"\u2014"}),jsx("div",{className:"text-neutral text-[10px]",children:E(i?.address)})]})]}),jsxs("div",{className:"flex-0 flex flex-col items-end justify-center gap-0.5",children:[jsx("div",{className:"text-foreground text-xs",children:$(m)}),jsxs("div",{className:"text-neutral text-[10px]",children:["$",fe(p)]})]})]})]}),s&&b.length>0&&jsxs("div",{className:"my-3",children:[jsx("div",{className:"text-neutral flex items-center justify-between text-xs font-medium",children:"Route Details"}),jsx("div",{className:"mt-3 flex flex-col gap-3",children:b.map(g=>jsxs("div",{className:"bg-content3 flex w-full flex-col items-center gap-2 rounded-lg px-4 py-3",children:[jsxs("div",{className:"flex w-full items-center justify-between",children:[jsx("div",{className:"text-neutral text-xs",children:"DEX"}),jsx("div",{className:"text-foreground text-xs",children:g.name})]}),jsxs("div",{className:"flex w-full items-center justify-between",children:[jsx("div",{className:"text-neutral text-xs",children:"Swap"}),jsxs("div",{className:"text-foreground flex items-center gap-2 text-xs",children:[jsxs("span",{children:[z(g.inputAmount)," ",E(g.input)]}),jsx(TradeIcon,{width:12,height:12,className:"text-foreground"}),jsxs("span",{children:[z(g.outputAmount)," ",E(g.output)]})]})]}),g.feeAmount&&jsxs("div",{className:"flex w-full items-center justify-between",children:[jsx("div",{className:"text-neutral text-xs",children:"Fee"}),jsxs("div",{className:"text-foreground text-xs",children:[z(g.feeAmount)," ",E(g.feeQuote)]})]})]},g.key))})]}),b.length>0&&jsx("div",{className:"flex justify-center",children:jsx(Button,{size:"sm",className:"text-neutral flex bg-transparent text-xs",endContent:s?jsx(ChevronUpIcon,{width:12,height:12}):jsx(ChevronDownIcon,{width:12,height:12}),disableRipple:true,onPress:C,children:s?"Show Less":"Show More"})})]})}),jsx(ModalFooter,{children:jsx(Button,{fullWidth:true,color:"primary",className:"flex rounded-lg",disableRipple:true,isDisabled:!r||!!h,isLoading:!r&&l||w,onPress:f,children:"Confirm"})})]})})}function at(){return jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:12,height:12,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:"text-neutral",children:[jsx("path",{d:"M21 12V7H5a2 2 0 0 1 0-4h14v4"}),jsx("path",{d:"M3 5v14a2 2 0 0 0 2 2h16v-5"}),jsx("path",{d:"M18 12a2 2 0 0 0 0 4h4v-4Z"})]})}function fe(e){if(!e)return "0.00";let t=Number(e);return Number.isFinite(t)?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):"0.00"}function $(e){if(!e)return "0";let t=Number(e);return Number.isFinite(t)?t>=1e6?(t/1e6).toLocaleString("en-US",{maximumFractionDigits:2})+"M":t>=1e3?(t/1e3).toLocaleString("en-US",{maximumFractionDigits:2})+"K":t.toLocaleString("en-US",{maximumFractionDigits:6}):"0"}function z(e){if(!e||e==="0")return "0";let t=Number(e);return Number.isFinite(t)?t>=1e12?(t/1e12).toFixed(2)+"T":t>=1e9?(t/1e9).toFixed(2)+"B":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(2)+"K":e:e}function E(e){return e?e.length<=10?e:`${e.slice(0,4)}...${e.slice(-4)}`:"\u2014"}function K({fromToken:e,toToken:t,fromBalance:u,toBalance:i,amount:a,amountInUsd:n,onAmountChange:d,onHalfAmount:m,onMaxAmount:p,outputAmount:r,outputAmountInUsd:l,onFromTokenSelect:h,onToTokenSelect:f,route:w,isRouting:s,routeError:S,onPreview:C,isSwapping:b,className:g}){return jsxs("div",{className:cn("px-4 pb-4 lg:pb-8",g),children:[jsxs("div",{className:"space-y-3",children:[jsx("p",{className:"text-neutral text-sm font-medium",children:"From"}),jsxs("div",{className:"bg-content1 flex flex-col rounded-lg px-3.5 pb-2.5 pt-2",children:[jsxs("div",{className:"flex items-center gap-2",children:[jsx("div",{className:"flex-1",children:jsx(Input,{type:"number",value:a??"",onChange:A=>d(A.target.value||void 0),placeholder:"0",classNames:{inputWrapper:cn("h-10 p-0 bg-transparent","data-[hover=true]:bg-transparent group-data-[focus=true]:bg-transparent","group-data-[focus-visible=true]:ring-offset-transparent group-data-[focus-visible=true]:ring-transparent"),input:cn("w-full h-full caret-primary text-3xl font-medium","placeholder:text-placeholder placeholder:text-3xl placeholder:font-medium","scrollbar-hide overflow-hidden text-ellipsis whitespace-nowrap")}})}),jsx("div",{className:"flex-0 flex h-full items-center justify-center",children:jsx(Button,{className:cn("flex min-w-0 h-8 min-h-8 pl-3 pr-2 bg-content3 rounded-full",e?"text-foreground":"text-neutral"),disableRipple:true,startContent:e?.image?jsx(Avatar,{size:"sm",src:e.image,name:e.symbol,className:"h-6 w-6"}):null,endContent:jsx(ChevronDownIcon,{width:16,height:16,className:"text-neutral"}),onPress:()=>h(""),children:e?e.symbol:"Select token"})})]}),jsxs("div",{className:"mt-3 flex items-center justify-between gap-4",children:[jsxs("div",{className:"text-neutral flex-1 text-xs",children:["\u2248 $",Se(n)]}),u&&jsxs("div",{className:"flex-0 flex items-center gap-2 pr-3 text-xs",children:[jsx(ve,{}),jsxs("span",{className:"text-neutral",children:[he(u.amount)," ",u.symbol]}),m&&jsx("span",{className:"text-primary cursor-pointer",onClick:m,children:"Half"}),p&&jsx("span",{className:"text-primary cursor-pointer",onClick:p,children:"Max"})]})]}),S&&jsx("p",{className:"mt-1 break-words text-xs text-danger-500",children:S.message})]})]}),jsxs("div",{className:"mt-4 space-y-3",children:[jsx("p",{className:"text-neutral text-sm font-medium",children:"To"}),jsxs("div",{className:"bg-content1 flex flex-col rounded-lg px-3.5 pb-2.5 pt-2",children:[jsxs("div",{className:"flex items-center gap-2",children:[jsx("div",{className:"flex-1",children:jsx(Input,{type:"number",value:r??"",disabled:true,placeholder:"0",classNames:{inputWrapper:cn("h-10 p-0 bg-transparent","data-[hover=true]:bg-transparent group-data-[focus=true]:bg-transparent","group-data-[focus-visible=true]:ring-offset-transparent group-data-[focus-visible=true]:ring-transparent"),input:cn("w-full h-full caret-primary text-3xl font-medium","placeholder:text-placeholder placeholder:text-3xl placeholder:font-medium","scrollbar-hide overflow-hidden text-ellipsis whitespace-nowrap")}})}),jsx("div",{className:"flex-0 flex h-full items-center justify-center",children:jsx(Button,{className:cn("flex min-w-0 h-8 min-h-8 pl-3 pr-2 bg-content3 rounded-full",t?"text-foreground":"text-neutral"),disableRipple:true,startContent:t?.image?jsx(Avatar,{size:"sm",src:t.image,name:t.symbol,className:"h-6 w-6"}):null,endContent:jsx(ChevronDownIcon,{width:16,height:16,className:"text-neutral"}),onPress:()=>f(""),children:t?t.symbol:"Select token"})})]}),jsxs("div",{className:"mt-3 flex items-center justify-between gap-4",children:[jsxs("div",{className:"text-neutral flex-1 text-xs",children:["\u2248 $",Se(l)]}),i&&jsxs("div",{className:"flex-0 flex items-center gap-2 pr-3 text-xs",children:[jsx(ve,{}),jsxs("span",{className:"text-neutral",children:[he(i.amount)," ",i.symbol]})]})]})]})]}),jsx(Button,{fullWidth:true,color:"primary",className:"mt-8 flex rounded-lg",disableRipple:true,isDisabled:!w,isLoading:!w&&s,onPress:C,children:b?"Swapping...":s?"Finding route...":"Swap"})]})}function ve(){return jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:12,height:12,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:"text-neutral",children:[jsx("path",{d:"M21 12V7H5a2 2 0 0 1 0-4h14v4"}),jsx("path",{d:"M3 5v14a2 2 0 0 0 2 2h16v-5"}),jsx("path",{d:"M18 12a2 2 0 0 0 0 4h4v-4Z"})]})}function Se(e){if(!e)return "0.00";let t=Number(e);return Number.isFinite(t)?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):"0.00"}function he(e){if(!e)return "0";let t=Number(e);return Number.isFinite(t)?t>=1e6?(t/1e6).toLocaleString("en-US",{maximumFractionDigits:2})+"M":t>=1e3?(t/1e3).toLocaleString("en-US",{maximumFractionDigits:2})+"K":t.toLocaleString("en-US",{maximumFractionDigits:6}):"0"}function ct({chain:e,from:t,to:u,onComplete:i,className:a}){let n=j({chain:e,from:t,to:u,onComplete:i}),{isOpen:d,onOpen:m,onOpenChange:p,onClose:r}=useDisclosure(),l=useCallback(async()=>{await n.swap(),r();},[n,r]);return jsxs(Fragment,{children:[jsx(K,{fromToken:n.fromToken,toToken:n.toToken,fromBalance:n.fromBalance,toBalance:n.toBalance,amount:n.amount,amountInUsd:n.amountInUsd,onAmountChange:n.setAmount,onHalfAmount:n.setHalfAmount,onMaxAmount:n.setMaxAmount,outputAmount:n.outputAmount,outputAmountInUsd:n.outputAmountInUsd,onFromTokenSelect:n.setFromTokenAddress,onToTokenSelect:n.setToTokenAddress,route:n.route,isRouting:n.isRouting,routeError:n.routeError,onPreview:m,isSwapping:n.isSwapping,className:a}),jsx(V,{isOpen:d,onOpenChange:p,fromToken:n.fromToken,toToken:n.toToken,fromBalance:n.fromBalance,inputAmount:n.amount,inputAmountInUsd:n.amountInUsd,outputAmount:n.outputAmount,outputAmountInUsd:n.outputAmountInUsd,route:n.route,isRouting:n.isRouting,routeError:n.routeError,onConfirm:l,isSwapping:n.isSwapping})]})}typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-trade"]="0.1.2");var pt="0.1.2";
|
|
2
|
+
export{V as SwapPreviewModal,K as SwapUI,ct as SwapWidget,ie as useSwap,ae as useSwapRoutePolling,j as useSwapScript,ue as useTxConfirmation,pt as version};//# sourceMappingURL=index.mjs.map
|
|
2
3
|
//# sourceMappingURL=index.mjs.map
|