@agg-build/hooks 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  useRampQuotes,
3
3
  useRampSession
4
- } from "./chunk-KXO3JOXF.mjs";
4
+ } from "./chunk-QKVR32KC.mjs";
5
5
  import {
6
6
  useWithdrawEstimate,
7
7
  useWithdrawFlow,
8
+ useWithdrawPreview,
8
9
  useWithdrawalLifecycle
9
- } from "./chunk-OBHXWQ6L.mjs";
10
+ } from "./chunk-DK4YDVPH.mjs";
10
11
  import {
11
12
  AggAuthContext,
12
13
  AggBalanceProvider,
@@ -94,7 +95,7 @@ import {
94
95
  useSyncBalances,
95
96
  useWithdrawManaged,
96
97
  userActivityQueryKeys
97
- } from "./chunk-VLYLQSDD.mjs";
98
+ } from "./chunk-V7VCT62L.mjs";
98
99
 
99
100
  // src/index.ts
100
101
  import { QueryClient as QueryClient4, QueryClientProvider, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
@@ -1266,16 +1267,21 @@ var extractBestPrices = (data, venueMarkets) => {
1266
1267
  }
1267
1268
  return { bestPrices, bestPriceVenuesByOutcomeId: venuesByOutcome };
1268
1269
  };
1269
- function useMidpoints(venueMarkets) {
1270
+ function useMidpoints(venueMarkets, options) {
1271
+ var _a;
1270
1272
  const client = useAggClient();
1273
+ const {
1274
+ market: { maxMidpointIdsPerRequest: configuredMaxMidpointIdsPerRequest }
1275
+ } = useAggUiConfig();
1276
+ const maxMidpointIdsPerRequest = (_a = options == null ? void 0 : options.maxMidpointIdsPerRequest) != null ? _a : configuredMaxMidpointIdsPerRequest;
1271
1277
  const ids = useMemo8(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
1272
1278
  const bestMidpointCandidateOutcomeIds = useMemo8(
1273
1279
  () => resolveBestMidpointCandidateOutcomeIds(venueMarkets),
1274
1280
  [venueMarkets]
1275
1281
  );
1276
1282
  const { data, isLoading } = useQuery2({
1277
- queryKey: ["midpoints", ids],
1278
- queryFn: () => client.getMidpoints(ids, { bestPrice: true }),
1283
+ queryKey: ["midpoints", ids, maxMidpointIdsPerRequest],
1284
+ queryFn: () => client.getMidpoints(ids, { bestPrice: true, maxMidpointIdsPerRequest }),
1279
1285
  enabled: ids.length > 0,
1280
1286
  staleTime: Infinity,
1281
1287
  gcTime: 30 * 6e4,
@@ -1284,13 +1290,13 @@ function useMidpoints(venueMarkets) {
1284
1290
  refetchOnReconnect: false
1285
1291
  });
1286
1292
  const result = useMemo8(() => {
1287
- var _a, _b, _c, _d, _e;
1293
+ var _a2, _b, _c, _d, _e;
1288
1294
  const map = /* @__PURE__ */ new Map();
1289
1295
  const venueMap = /* @__PURE__ */ new Map();
1290
1296
  if (!(data == null ? void 0 : data.data) || !venueMarkets) return { map, venueMap };
1291
1297
  const itemByMarketId = new Map(data.data.map((item) => [item.venueMarketId, item]));
1292
1298
  for (const item of data.data) {
1293
- if (!((_a = item.outcomes) == null ? void 0 : _a.length)) continue;
1299
+ if (!((_a2 = item.outcomes) == null ? void 0 : _a2.length)) continue;
1294
1300
  for (const o of item.outcomes) {
1295
1301
  if (o.midpoint == null) continue;
1296
1302
  map.set(o.venueMarketOutcomeId, o.midpoint);
@@ -1996,12 +2002,21 @@ function useSmartRoute(options) {
1996
2002
  placeholderData: keepPreviousData6
1997
2003
  });
1998
2004
  const error = query.error;
2005
+ let loadingReason = null;
2006
+ if (query.isFetching) {
2007
+ if (query.isLoading) {
2008
+ loadingReason = query.data != null ? "updating-route" : "finding-best-odds";
2009
+ } else {
2010
+ loadingReason = "refreshing-quotes";
2011
+ }
2012
+ }
1999
2013
  return {
2000
2014
  data: (_b = query.data) != null ? _b : null,
2001
2015
  isLoading: query.isLoading,
2002
2016
  isFetching: query.isFetching,
2003
2017
  error: error instanceof Error ? error : error ? new Error(String(error)) : null,
2004
- refetch: query.refetch
2018
+ refetch: query.refetch,
2019
+ loadingReason
2005
2020
  };
2006
2021
  }
2007
2022
 
@@ -2300,25 +2315,11 @@ function useVenueEvents(options) {
2300
2315
 
2301
2316
  // src/use-venue-market-midpoints.ts
2302
2317
  import { keepPreviousData as keepPreviousData8, useQuery as useQuery8 } from "@tanstack/react-query";
2303
- var MAX_VENUE_MARKET_IDS_PER_REQUEST = 200;
2304
2318
  var normalizeVenueMarketIds2 = (venueMarketIds) => {
2305
2319
  return [
2306
2320
  ...new Set(venueMarketIds.map((venueMarketId) => venueMarketId.trim()).filter(Boolean))
2307
2321
  ].sort((left, right) => left.localeCompare(right));
2308
2322
  };
2309
- var chunkVenueMarketIds = (venueMarketIds) => {
2310
- if (venueMarketIds.length === 0) return [];
2311
- const chunks = [];
2312
- for (let index = 0; index < venueMarketIds.length; index += MAX_VENUE_MARKET_IDS_PER_REQUEST) {
2313
- chunks.push(venueMarketIds.slice(index, index + MAX_VENUE_MARKET_IDS_PER_REQUEST));
2314
- }
2315
- return chunks;
2316
- };
2317
- var mergeMidpointResponses = (responses) => {
2318
- return {
2319
- data: responses.flatMap((response) => response.data)
2320
- };
2321
- };
2322
2323
  var mapMidpointsByVenueMarketId = (rows) => {
2323
2324
  const mappedMidpoints = /* @__PURE__ */ new Map();
2324
2325
  rows.forEach((row) => {
@@ -2331,23 +2332,24 @@ var mapMidpointsByVenueMarketId = (rows) => {
2331
2332
  return mappedMidpoints;
2332
2333
  };
2333
2334
  function useVenueMarketMidpoints(options) {
2334
- var _a, _b, _c;
2335
+ var _a, _b, _c, _d;
2335
2336
  const client = useAggClient();
2337
+ const {
2338
+ market: { maxMidpointIdsPerRequest: configuredMaxMidpointIdsPerRequest }
2339
+ } = useAggUiConfig();
2336
2340
  const enabled = (_a = options.enabled) != null ? _a : true;
2337
2341
  const requestedVenueMarketIds = normalizeVenueMarketIds2(options.venueMarketIds);
2342
+ const maxMidpointIdsPerRequest = (_b = options.maxMidpointIdsPerRequest) != null ? _b : configuredMaxMidpointIdsPerRequest;
2338
2343
  const query = useQuery8({
2339
- queryKey: requestedVenueMarketIds.length ? ["venue-market-midpoints", requestedVenueMarketIds] : ["venue-market-midpoints", "__disabled__"],
2344
+ queryKey: requestedVenueMarketIds.length ? ["venue-market-midpoints", requestedVenueMarketIds, maxMidpointIdsPerRequest] : ["venue-market-midpoints", "__disabled__"],
2340
2345
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
2341
- const venueMarketIdChunks = chunkVenueMarketIds(requestedVenueMarketIds);
2342
- if (venueMarketIdChunks.length === 0) {
2346
+ if (requestedVenueMarketIds.length === 0) {
2343
2347
  return { data: [] };
2344
2348
  }
2345
- const chunkResponses = yield Promise.all(
2346
- venueMarketIdChunks.map((venueMarketIds) => {
2347
- return client.getMidpoints({ venueMarketIds, bestPrice: true }, { signal });
2348
- })
2349
+ return client.getMidpoints(
2350
+ { venueMarketIds: requestedVenueMarketIds, bestPrice: true },
2351
+ { signal, maxMidpointIdsPerRequest }
2349
2352
  );
2350
- return mergeMidpointResponses(chunkResponses);
2351
2353
  }),
2352
2354
  enabled: enabled && requestedVenueMarketIds.length > 0,
2353
2355
  staleTime: 1e4,
@@ -2356,7 +2358,7 @@ function useVenueMarketMidpoints(options) {
2356
2358
  retry: 1,
2357
2359
  placeholderData: keepPreviousData8
2358
2360
  });
2359
- const midpointRows = (_c = (_b = query.data) == null ? void 0 : _b.data) != null ? _c : [];
2361
+ const midpointRows = (_d = (_c = query.data) == null ? void 0 : _c.data) != null ? _d : [];
2360
2362
  const midpointsByVenueMarketId = mapMidpointsByVenueMarketId(midpointRows);
2361
2363
  return __spreadProps(__spreadValues({}, query), {
2362
2364
  midpointRows,
@@ -2458,8 +2460,13 @@ var buildCachedMidpointEntries = (requestedVenueMarketIds, rows) => {
2458
2460
  }
2459
2461
  return nextCacheEntries;
2460
2462
  };
2461
- function useViewportMidpoints(visibleMarkets) {
2463
+ function useViewportMidpoints(visibleMarkets, options) {
2464
+ var _a;
2462
2465
  const client = useAggClient();
2466
+ const {
2467
+ market: { maxMidpointIdsPerRequest: configuredMaxMidpointIdsPerRequest }
2468
+ } = useAggUiConfig();
2469
+ const maxMidpointIdsPerRequest = (_a = options == null ? void 0 : options.maxMidpointIdsPerRequest) != null ? _a : configuredMaxMidpointIdsPerRequest;
2463
2470
  const [cache, setCache] = useState10(() => /* @__PURE__ */ new Map());
2464
2471
  const inFlightRef = useRef6(/* @__PURE__ */ new Set());
2465
2472
  const visibleRef = useRef6(visibleMarkets);
@@ -2473,10 +2480,10 @@ function useViewportMidpoints(visibleMarkets) {
2473
2480
  if (!toFetch.length) return;
2474
2481
  let cancelled = false;
2475
2482
  for (const id of toFetch) inFlightRef.current.add(id);
2476
- client.getMidpoints(toFetch, { bestPrice: true }).then((resp) => {
2477
- var _a;
2483
+ client.getMidpoints(toFetch, { bestPrice: true, maxMidpointIdsPerRequest }).then((resp) => {
2484
+ var _a2;
2478
2485
  if (cancelled) return;
2479
- const nextCacheEntries = buildCachedMidpointEntries(toFetch, (_a = resp.data) != null ? _a : []);
2486
+ const nextCacheEntries = buildCachedMidpointEntries(toFetch, (_a2 = resp.data) != null ? _a2 : []);
2480
2487
  setCache((prev) => {
2481
2488
  const next = new Map(prev);
2482
2489
  for (const [venueMarketId, entry] of nextCacheEntries) {
@@ -2491,15 +2498,15 @@ function useViewportMidpoints(visibleMarkets) {
2491
2498
  return () => {
2492
2499
  cancelled = true;
2493
2500
  };
2494
- }, [visibleFp, cache]);
2501
+ }, [visibleFp, cache, maxMidpointIdsPerRequest]);
2495
2502
  const { prices, venueByOutcomeId } = useMemo13(() => {
2496
- var _a, _b, _c, _d;
2503
+ var _a2, _b, _c, _d;
2497
2504
  const map = /* @__PURE__ */ new Map();
2498
2505
  const venueMap = /* @__PURE__ */ new Map();
2499
2506
  for (const market of visibleMarkets) {
2500
2507
  const entry = cache.get(market.id);
2501
2508
  if (!entry) continue;
2502
- const ownVenue = (_a = entry.venue) != null ? _a : market.venue;
2509
+ const ownVenue = (_a2 = entry.venue) != null ? _a2 : market.venue;
2503
2510
  for (const outcome of market.venueMarketOutcomes) {
2504
2511
  let best = (_b = entry.ownOutcomes.get(outcome.id)) != null ? _b : null;
2505
2512
  let bestVenue = best != null ? ownVenue : null;
@@ -2775,6 +2782,7 @@ export {
2775
2782
  useWithdrawEstimate,
2776
2783
  useWithdrawFlow,
2777
2784
  useWithdrawManaged,
2785
+ useWithdrawPreview,
2778
2786
  useWithdrawalLifecycle,
2779
2787
  userActivityQueryKeys
2780
2788
  };
@@ -1,11 +1,12 @@
1
1
  import * as _agg_build_sdk from '@agg-build/sdk';
2
- import { WsWithdrawalLifecycleStatus, WsWithdrawalLifecycleLeg, WithdrawManagedResponse, WithdrawManagedParams } from '@agg-build/sdk';
2
+ import { WsWithdrawalLifecycleStatus, WsWithdrawalLifecycleLeg, WithdrawPreviewResponse, WithdrawManagedResponse, WithdrawManagedParams } from '@agg-build/sdk';
3
3
  import * as _tanstack_react_query from '@tanstack/react-query';
4
4
  export { U as UseDepositAddressesOptions, u as useDepositAddresses } from './use-deposit-addresses-B9ICS-3U.mjs';
5
5
 
6
6
  type WithdrawSelectOption = {
7
7
  value: string;
8
8
  label: string;
9
+ disabled?: boolean;
9
10
  };
10
11
  type WithdrawSummary = {
11
12
  /**
@@ -38,6 +39,12 @@ interface UseWithdrawFlowResult {
38
39
  * and reset to `null` when the modal closes.
39
40
  */
40
41
  withdrawalId: string | null;
42
+ /**
43
+ * True when the user clicked Max — the backend should apply its own cap
44
+ * rather than rejecting an over-balance request. Reset to false when the
45
+ * user manually edits the amount field afterward.
46
+ */
47
+ isMax: boolean;
41
48
  };
42
49
  onWithdrawDestinationChange: (address: string) => void;
43
50
  onWithdrawAmountChange: (amount: string) => void;
@@ -88,6 +95,8 @@ interface WithdrawalLifecycleState {
88
95
  requestedAmountRaw: string | null;
89
96
  /** Terminal settled amount in destination-token native decimals. */
90
97
  completedAmountRaw: string | null;
98
+ /** Realized platform fee in destination-token native decimals. Only present on terminal events; null until then. */
99
+ feeRaw: string | null;
91
100
  /** Whether `status` is a terminal state (`completed` / `partial` / `failed`). */
92
101
  terminal: boolean;
93
102
  /** Last leg delta (the leg whose flip triggered the most recent event). */
@@ -124,6 +133,26 @@ interface UseWithdrawalLifecycleResult {
124
133
  */
125
134
  declare function useWithdrawalLifecycle(withdrawalId: string | null): UseWithdrawalLifecycleResult;
126
135
 
136
+ interface UseWithdrawPreviewParams {
137
+ amountRaw: string | null;
138
+ tokenSymbol: string | null;
139
+ destinationChainId: number | null;
140
+ destinationAddress: string | null;
141
+ /**
142
+ * When `true`, the backend caps the withdrawal to the maximum deliverable amount.
143
+ * Included in the query key so max vs non-max are distinct cache entries.
144
+ */
145
+ max?: boolean;
146
+ }
147
+ /**
148
+ * Live withdrawal preview backed by the API (`POST /execution/withdraw/preview`).
149
+ * Disabled until amount/token/chain/address are present and amount is non-zero.
150
+ * The backend caches identical previews for 15s; FE debounce keeps Relay calls
151
+ * bounded. Returns the real fee + receive amount, replacing the hardcoded
152
+ * `useWithdrawEstimate`.
153
+ */
154
+ declare function useWithdrawPreview({ amountRaw, tokenSymbol, destinationChainId, destinationAddress, max, }: UseWithdrawPreviewParams): _tanstack_react_query.UseQueryResult<WithdrawPreviewResponse, Error>;
155
+
127
156
  interface UseWithdrawManagedOptions {
128
157
  onSuccess?: (data: WithdrawManagedResponse) => void;
129
158
  onError?: (error: Error) => void;
@@ -314,4 +343,4 @@ declare function useManagedBalances(options?: UseManagedBalancesOptions): {
314
343
  promise: Promise<_agg_build_sdk.UnifiedBalanceResponse>;
315
344
  };
316
345
 
317
- export { type UseManagedBalancesOptions, type UseWithdrawEstimateParams, type UseWithdrawFlowOptions, type UseWithdrawFlowResult, type UseWithdrawManagedOptions, type UseWithdrawalLifecycleResult, type WithdrawFeeEstimate, type WithdrawalLifecycleState, useManagedBalances, useWithdrawEstimate, useWithdrawFlow, useWithdrawManaged, useWithdrawalLifecycle };
346
+ export { type UseManagedBalancesOptions, type UseWithdrawEstimateParams, type UseWithdrawFlowOptions, type UseWithdrawFlowResult, type UseWithdrawManagedOptions, type UseWithdrawPreviewParams, type UseWithdrawalLifecycleResult, type WithdrawFeeEstimate, type WithdrawalLifecycleState, useManagedBalances, useWithdrawEstimate, useWithdrawFlow, useWithdrawManaged, useWithdrawPreview, useWithdrawalLifecycle };
@@ -1,11 +1,12 @@
1
1
  import * as _agg_build_sdk from '@agg-build/sdk';
2
- import { WsWithdrawalLifecycleStatus, WsWithdrawalLifecycleLeg, WithdrawManagedResponse, WithdrawManagedParams } from '@agg-build/sdk';
2
+ import { WsWithdrawalLifecycleStatus, WsWithdrawalLifecycleLeg, WithdrawPreviewResponse, WithdrawManagedResponse, WithdrawManagedParams } from '@agg-build/sdk';
3
3
  import * as _tanstack_react_query from '@tanstack/react-query';
4
4
  export { U as UseDepositAddressesOptions, u as useDepositAddresses } from './use-deposit-addresses-B9ICS-3U.js';
5
5
 
6
6
  type WithdrawSelectOption = {
7
7
  value: string;
8
8
  label: string;
9
+ disabled?: boolean;
9
10
  };
10
11
  type WithdrawSummary = {
11
12
  /**
@@ -38,6 +39,12 @@ interface UseWithdrawFlowResult {
38
39
  * and reset to `null` when the modal closes.
39
40
  */
40
41
  withdrawalId: string | null;
42
+ /**
43
+ * True when the user clicked Max — the backend should apply its own cap
44
+ * rather than rejecting an over-balance request. Reset to false when the
45
+ * user manually edits the amount field afterward.
46
+ */
47
+ isMax: boolean;
41
48
  };
42
49
  onWithdrawDestinationChange: (address: string) => void;
43
50
  onWithdrawAmountChange: (amount: string) => void;
@@ -88,6 +95,8 @@ interface WithdrawalLifecycleState {
88
95
  requestedAmountRaw: string | null;
89
96
  /** Terminal settled amount in destination-token native decimals. */
90
97
  completedAmountRaw: string | null;
98
+ /** Realized platform fee in destination-token native decimals. Only present on terminal events; null until then. */
99
+ feeRaw: string | null;
91
100
  /** Whether `status` is a terminal state (`completed` / `partial` / `failed`). */
92
101
  terminal: boolean;
93
102
  /** Last leg delta (the leg whose flip triggered the most recent event). */
@@ -124,6 +133,26 @@ interface UseWithdrawalLifecycleResult {
124
133
  */
125
134
  declare function useWithdrawalLifecycle(withdrawalId: string | null): UseWithdrawalLifecycleResult;
126
135
 
136
+ interface UseWithdrawPreviewParams {
137
+ amountRaw: string | null;
138
+ tokenSymbol: string | null;
139
+ destinationChainId: number | null;
140
+ destinationAddress: string | null;
141
+ /**
142
+ * When `true`, the backend caps the withdrawal to the maximum deliverable amount.
143
+ * Included in the query key so max vs non-max are distinct cache entries.
144
+ */
145
+ max?: boolean;
146
+ }
147
+ /**
148
+ * Live withdrawal preview backed by the API (`POST /execution/withdraw/preview`).
149
+ * Disabled until amount/token/chain/address are present and amount is non-zero.
150
+ * The backend caches identical previews for 15s; FE debounce keeps Relay calls
151
+ * bounded. Returns the real fee + receive amount, replacing the hardcoded
152
+ * `useWithdrawEstimate`.
153
+ */
154
+ declare function useWithdrawPreview({ amountRaw, tokenSymbol, destinationChainId, destinationAddress, max, }: UseWithdrawPreviewParams): _tanstack_react_query.UseQueryResult<WithdrawPreviewResponse, Error>;
155
+
127
156
  interface UseWithdrawManagedOptions {
128
157
  onSuccess?: (data: WithdrawManagedResponse) => void;
129
158
  onError?: (error: Error) => void;
@@ -314,4 +343,4 @@ declare function useManagedBalances(options?: UseManagedBalancesOptions): {
314
343
  promise: Promise<_agg_build_sdk.UnifiedBalanceResponse>;
315
344
  };
316
345
 
317
- export { type UseManagedBalancesOptions, type UseWithdrawEstimateParams, type UseWithdrawFlowOptions, type UseWithdrawFlowResult, type UseWithdrawManagedOptions, type UseWithdrawalLifecycleResult, type WithdrawFeeEstimate, type WithdrawalLifecycleState, useManagedBalances, useWithdrawEstimate, useWithdrawFlow, useWithdrawManaged, useWithdrawalLifecycle };
346
+ export { type UseManagedBalancesOptions, type UseWithdrawEstimateParams, type UseWithdrawFlowOptions, type UseWithdrawFlowResult, type UseWithdrawManagedOptions, type UseWithdrawPreviewParams, type UseWithdrawalLifecycleResult, type WithdrawFeeEstimate, type WithdrawalLifecycleState, useManagedBalances, useWithdrawEstimate, useWithdrawFlow, useWithdrawManaged, useWithdrawPreview, useWithdrawalLifecycle };
package/dist/withdraw.js CHANGED
@@ -62,6 +62,7 @@ __export(withdraw_exports, {
62
62
  useWithdrawEstimate: () => useWithdrawEstimate,
63
63
  useWithdrawFlow: () => useWithdrawFlow,
64
64
  useWithdrawManaged: () => useWithdrawManaged,
65
+ useWithdrawPreview: () => useWithdrawPreview,
65
66
  useWithdrawalLifecycle: () => useWithdrawalLifecycle
66
67
  });
67
68
  module.exports = __toCommonJS(withdraw_exports);
@@ -81,6 +82,8 @@ var enUsLabels = {
81
82
  errorPrefix: "Error",
82
83
  tabsAria: "Tabs",
83
84
  hiddenTabsAria: "Hidden tabs",
85
+ scrollTabsLeft: "Scroll tabs left",
86
+ scrollTabsRight: "Scroll tabs right",
84
87
  selectAria: "Select",
85
88
  lineChartAria: "Line chart",
86
89
  candlestickChartAria: "Candlestick chart",
@@ -243,6 +246,7 @@ var enUsLabels = {
243
246
  networkReserveTooltipLineTwo: "Any unused amount stays in your balance.",
244
247
  youReceive: "You'll receive",
245
248
  confirm: "Confirm withdrawal",
249
+ calculatingFees: "Calculating fees\u2026",
246
250
  successTitle: "Withdrawal submitted",
247
251
  successDescription: (tokenSymbol) => `Your ${tokenSymbol} withdrawal is being processed and will arrive shortly.`,
248
252
  // Terminal-state copy. The success step swaps `successTitle` /
@@ -657,6 +661,9 @@ var enUsLabels = {
657
661
  buyingOutcome: (label) => `Buying ${label}`,
658
662
  sellingOutcome: (label) => `Selling ${label}`,
659
663
  findingBestRoute: "Finding the best route...",
664
+ findingBestOdds: "Finding best odds\u2026",
665
+ updatingRoute: "Updating route\u2026",
666
+ refreshingQuotes: "Refreshing quotes\u2026",
660
667
  checkingBalance: "Checking balance",
661
668
  submittingOrderProgress: "Submitting order...",
662
669
  orderSubmittedProgress: (orderId) => `Order #${orderId.replace(/^#/, "")} submitted`,
@@ -977,7 +984,8 @@ var defaultAggUiConfig = {
977
984
  enableNotifications: true
978
985
  },
979
986
  market: {
980
- arbitrageThreshold: 0
987
+ arbitrageThreshold: 0,
988
+ maxMidpointIdsPerRequest: 75
981
989
  },
982
990
  chart: {
983
991
  defaultChartTimeRange: "1D",
@@ -1252,6 +1260,13 @@ var isValidDestinationAddress = (address, chainId) => {
1252
1260
  if (chainId === SOLANA_CHAIN_ID) return SOLANA_ADDRESS_REGEX.test(address);
1253
1261
  return EVM_ADDRESS_REGEX.test(address);
1254
1262
  };
1263
+ var detectDestinationAddressKind = (address) => {
1264
+ const trimmed = address.trim();
1265
+ if (!trimmed) return null;
1266
+ if (EVM_ADDRESS_REGEX.test(trimmed)) return "evm";
1267
+ if (SOLANA_ADDRESS_REGEX.test(trimmed)) return "solana";
1268
+ return null;
1269
+ };
1255
1270
  var DEFAULT_WITHDRAW_SUMMARY = {
1256
1271
  amountReceived: "",
1257
1272
  network: "",
@@ -1289,7 +1304,7 @@ var parseTokenAmountToRaw = (amount, decimals) => {
1289
1304
  };
1290
1305
  var shortenAddress = (address) => address.length > 12 ? `${address.slice(0, 6)}...${address.slice(-4)}` : address;
1291
1306
  function useWithdrawFlow(options) {
1292
- var _a, _b;
1307
+ var _a, _b, _c, _d, _e;
1293
1308
  const { open, onOpenChange } = options;
1294
1309
  const { totalBalance } = useAggBalanceState();
1295
1310
  const { balances } = useManagedBalances({ enabled: open });
@@ -1310,31 +1325,42 @@ function useWithdrawFlow(options) {
1310
1325
  const [withdrawNetwork, setWithdrawNetwork] = (0, import_react5.useState)("");
1311
1326
  const [withdrawSummary, setWithdrawSummary] = (0, import_react5.useState)(DEFAULT_WITHDRAW_SUMMARY);
1312
1327
  const [withdrawalId, setWithdrawalId] = (0, import_react5.useState)(null);
1328
+ const [isMax, setIsMax] = (0, import_react5.useState)(false);
1329
+ const detectedAddressKind = (0, import_react5.useMemo)(
1330
+ () => detectDestinationAddressKind(withdrawDestination),
1331
+ [withdrawDestination]
1332
+ );
1313
1333
  const networkOptions = (0, import_react5.useMemo)(
1314
- () => (supportedChains != null ? supportedChains : []).filter((chain) => WITHDRAWAL_SUPPORTED_CHAIN_IDS.has(chain.chainId)).map((chain) => ({
1315
- value: String(chain.chainId),
1316
- label: chain.name
1317
- })),
1318
- [supportedChains]
1334
+ () => (supportedChains != null ? supportedChains : []).filter((chain) => WITHDRAWAL_SUPPORTED_CHAIN_IDS.has(chain.chainId)).map((chain) => {
1335
+ const value = String(chain.chainId);
1336
+ const isSolana = chain.chainId === SOLANA_CHAIN_ID;
1337
+ const disabled = detectedAddressKind === "solana" ? !isSolana : detectedAddressKind === "evm" ? isSolana : false;
1338
+ return { value, label: chain.name, disabled };
1339
+ }),
1340
+ [supportedChains, detectedAddressKind]
1341
+ );
1342
+ const firstEnabledNetwork = (_d = (_c = (_a = networkOptions.find((option) => !option.disabled)) == null ? void 0 : _a.value) != null ? _c : (_b = networkOptions[0]) == null ? void 0 : _b.value) != null ? _d : "";
1343
+ const isCurrentNetworkSelectable = networkOptions.some(
1344
+ (option) => option.value === withdrawNetwork && !option.disabled
1319
1345
  );
1320
- const resolvedWithdrawNetwork = withdrawNetwork || ((_a = networkOptions[0]) == null ? void 0 : _a.value) || "";
1346
+ const resolvedWithdrawNetwork = isCurrentNetworkSelectable ? withdrawNetwork : firstEnabledNetwork;
1321
1347
  (0, import_react5.useEffect)(() => {
1322
1348
  if (!networkOptions.length) return;
1323
- if (!withdrawNetwork || !networkOptions.some((option) => option.value === withdrawNetwork)) {
1324
- setWithdrawNetwork(networkOptions[0].value);
1349
+ if (!isCurrentNetworkSelectable && firstEnabledNetwork) {
1350
+ setWithdrawNetwork(firstEnabledNetwork);
1325
1351
  }
1326
- }, [networkOptions, withdrawNetwork]);
1352
+ }, [networkOptions, isCurrentNetworkSelectable, firstEnabledNetwork]);
1327
1353
  const tokenOptions = (0, import_react5.useMemo)(() => {
1328
- var _a2, _b2, _c;
1354
+ var _a2, _b2, _c2;
1329
1355
  const selectedChainId = Number(resolvedWithdrawNetwork);
1330
1356
  const supportedTokensForNetwork = (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === selectedChainId)) == null ? void 0 : _a2.tokens) != null ? _b2 : [];
1331
1357
  const withdrawableSymbols = new Set(supportedTokensForNetwork.map((token) => token.symbol));
1332
- return ((_c = balances == null ? void 0 : balances.cash) != null ? _c : []).filter((cashEntry) => withdrawableSymbols.has(cashEntry.tokenSymbol)).map((cashEntry) => ({
1358
+ return ((_c2 = balances == null ? void 0 : balances.cash) != null ? _c2 : []).filter((cashEntry) => withdrawableSymbols.has(cashEntry.tokenSymbol)).map((cashEntry) => ({
1333
1359
  value: cashEntry.tokenSymbol,
1334
1360
  label: cashEntry.tokenSymbol
1335
1361
  }));
1336
1362
  }, [balances, resolvedWithdrawNetwork, supportedChains]);
1337
- const resolvedWithdrawToken = tokenOptions.some((option) => option.value === withdrawToken) ? withdrawToken : ((_b = tokenOptions[0]) == null ? void 0 : _b.value) || "";
1363
+ const resolvedWithdrawToken = tokenOptions.some((option) => option.value === withdrawToken) ? withdrawToken : ((_e = tokenOptions[0]) == null ? void 0 : _e.value) || "";
1338
1364
  (0, import_react5.useEffect)(() => {
1339
1365
  if (!tokenOptions.length) return;
1340
1366
  if (!tokenOptions.some((option) => option.value === withdrawToken)) {
@@ -1346,9 +1372,9 @@ function useWithdrawFlow(options) {
1346
1372
  [balances, resolvedWithdrawToken]
1347
1373
  );
1348
1374
  const selectedTokenDecimals = (0, import_react5.useMemo)(() => {
1349
- var _a2, _b2, _c, _d;
1375
+ var _a2, _b2, _c2, _d2;
1350
1376
  const selectedChainId = Number(resolvedWithdrawNetwork);
1351
- return (_d = (_c = (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === selectedChainId)) == null ? void 0 : _a2.tokens.find((token) => token.symbol === resolvedWithdrawToken)) == null ? void 0 : _b2.decimals) != null ? _c : selectedCashEntry == null ? void 0 : selectedCashEntry.decimals) != null ? _d : 6;
1377
+ return (_d2 = (_c2 = (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === selectedChainId)) == null ? void 0 : _a2.tokens.find((token) => token.symbol === resolvedWithdrawToken)) == null ? void 0 : _b2.decimals) != null ? _c2 : selectedCashEntry == null ? void 0 : selectedCashEntry.decimals) != null ? _d2 : 6;
1352
1378
  }, [
1353
1379
  resolvedWithdrawNetwork,
1354
1380
  resolvedWithdrawToken,
@@ -1373,6 +1399,7 @@ function useWithdrawFlow(options) {
1373
1399
  setWithdrawNetwork("");
1374
1400
  setWithdrawSummary(DEFAULT_WITHDRAW_SUMMARY);
1375
1401
  setWithdrawalId(null);
1402
+ setIsMax(false);
1376
1403
  }, []);
1377
1404
  const handleWithdrawOpenChange = (0, import_react5.useCallback)(
1378
1405
  (isOpen) => {
@@ -1412,19 +1439,19 @@ function useWithdrawFlow(options) {
1412
1439
  }
1413
1440
  return scaleBy(native, selectedTokenDecimals - selectedCashEntry.decimals);
1414
1441
  })();
1415
- if (BigInt(amountRaw) > balanceInDestFrame) {
1442
+ if (!isMax && BigInt(amountRaw) > balanceInDestFrame) {
1416
1443
  throw new Error("Withdrawal amount exceeds your available balance.");
1417
1444
  }
1418
1445
  }
1419
1446
  ws == null ? void 0 : ws.connect();
1420
1447
  yield new Promise((resolve, reject) => {
1421
1448
  withdrawMutation.mutate(
1422
- {
1449
+ __spreadValues({
1423
1450
  amountRaw,
1424
1451
  tokenSymbol: resolvedWithdrawToken,
1425
1452
  destinationAddress: trimmedDestination,
1426
1453
  destinationChainId
1427
- },
1454
+ }, isMax ? { max: true } : {}),
1428
1455
  {
1429
1456
  onSuccess: (data) => {
1430
1457
  setWithdrawalId(data.withdrawalId);
@@ -1441,6 +1468,7 @@ function useWithdrawFlow(options) {
1441
1468
  fees: "\u2014"
1442
1469
  });
1443
1470
  }), [
1471
+ isMax,
1444
1472
  resolvedWithdrawNetwork,
1445
1473
  resolvedWithdrawToken,
1446
1474
  selectedCashEntry,
@@ -1464,13 +1492,18 @@ function useWithdrawFlow(options) {
1464
1492
  selectedToken: resolvedWithdrawToken,
1465
1493
  selectedNetwork: resolvedWithdrawNetwork,
1466
1494
  purchaseSummary: withdrawSummary,
1467
- withdrawalId
1495
+ withdrawalId,
1496
+ isMax
1468
1497
  },
1469
1498
  onWithdrawDestinationChange: setWithdrawDestination,
1470
- onWithdrawAmountChange: setWithdrawAmount,
1499
+ onWithdrawAmountChange: (0, import_react5.useCallback)((v) => {
1500
+ setIsMax(false);
1501
+ setWithdrawAmount(v);
1502
+ }, []),
1471
1503
  onWithdrawTokenChange: setWithdrawToken,
1472
1504
  onWithdrawNetworkChange: setWithdrawNetwork,
1473
1505
  onMaxClick: (0, import_react5.useCallback)(() => {
1506
+ setIsMax(true);
1474
1507
  setWithdrawAmount(exactBalance === "0" ? "0" : exactBalance);
1475
1508
  }, [exactBalance]),
1476
1509
  onSelectWithdrawProvider: (0, import_react5.useCallback)(
@@ -1537,6 +1570,7 @@ var INITIAL_STATE = {
1537
1570
  status: null,
1538
1571
  requestedAmountRaw: null,
1539
1572
  completedAmountRaw: null,
1573
+ feeRaw: null,
1540
1574
  terminal: false,
1541
1575
  lastLeg: null,
1542
1576
  legs: [],
@@ -1567,16 +1601,17 @@ var mergeLegs = (prev, snapshot, delta) => {
1567
1601
  return next;
1568
1602
  };
1569
1603
  var restToLifecycleState = (response) => {
1570
- var _a, _b;
1604
+ var _a, _b, _c;
1571
1605
  return {
1572
1606
  pending: false,
1573
1607
  status: response.status,
1574
1608
  requestedAmountRaw: response.requested.amountRaw,
1575
1609
  completedAmountRaw: (_a = response.completedAmountRaw) != null ? _a : null,
1610
+ feeRaw: (_b = response.expected.feeRaw) != null ? _b : null,
1576
1611
  terminal: response.status === "completed" || response.status === "partial" || response.status === "failed",
1577
1612
  lastLeg: null,
1578
1613
  legs: response.legs.map(restLegToWsLeg),
1579
- errorMessage: (_b = response.errorMessage) != null ? _b : null,
1614
+ errorMessage: (_c = response.errorMessage) != null ? _c : null,
1580
1615
  // No server timestamp on the REST response — we use 0 as "older than any
1581
1616
  // WS timestamp" so a subsequent WS event always wins. Callers that read
1582
1617
  // `timestamp` should treat 0/null interchangeably as "unset".
@@ -1618,14 +1653,15 @@ function useWithdrawalLifecycle(withdrawalId) {
1618
1653
  return (msg) => {
1619
1654
  if (msg.withdrawalId !== withdrawalId) return;
1620
1655
  setState((prev) => {
1621
- var _a, _b, _c, _d;
1656
+ var _a, _b, _c, _d, _e;
1622
1657
  return {
1623
1658
  pending: false,
1624
1659
  status: msg.status,
1625
1660
  requestedAmountRaw: (_a = msg.requestedAmountRaw) != null ? _a : prev.requestedAmountRaw,
1626
1661
  completedAmountRaw: (_b = msg.completedAmountRaw) != null ? _b : prev.completedAmountRaw,
1662
+ feeRaw: (_c = msg.feeRaw) != null ? _c : null,
1627
1663
  terminal: msg.terminal,
1628
- lastLeg: (_c = msg.leg) != null ? _c : null,
1664
+ lastLeg: (_d = msg.leg) != null ? _d : null,
1629
1665
  // `legs[]` is the cumulative server-known truth. Snapshots
1630
1666
  // (`pending` / terminal rollup) carry a full `legs[]` and replace
1631
1667
  // it. Intermediate per-leg deltas carry only `leg` (no `legs[]`)
@@ -1633,7 +1669,7 @@ function useWithdrawalLifecycle(withdrawalId) {
1633
1669
  // (sourceChainId, destChainId, type) so the timeline UI doesn't
1634
1670
  // collapse to empty between snapshots.
1635
1671
  legs: mergeLegs(prev.legs, msg.legs, msg.leg),
1636
- errorMessage: (_d = msg.errorMessage) != null ? _d : null,
1672
+ errorMessage: (_e = msg.errorMessage) != null ? _e : null,
1637
1673
  timestamp: msg.timestamp
1638
1674
  };
1639
1675
  });
@@ -1652,6 +1688,37 @@ function useWithdrawalLifecycle(withdrawalId) {
1652
1688
  const reset = (0, import_react7.useCallback)(() => setState(INITIAL_STATE), []);
1653
1689
  return { state, reset };
1654
1690
  }
1691
+
1692
+ // src/withdraw/use-withdraw-preview.ts
1693
+ var import_react_query7 = require("@tanstack/react-query");
1694
+ function useWithdrawPreview({
1695
+ amountRaw,
1696
+ tokenSymbol,
1697
+ destinationChainId,
1698
+ destinationAddress,
1699
+ max
1700
+ }) {
1701
+ const client = useAggClient();
1702
+ const enabled = !!amountRaw && BigInt(amountRaw || "0") > BigInt(0) && !!tokenSymbol && !!destinationChainId && !!destinationAddress;
1703
+ return (0, import_react_query7.useQuery)({
1704
+ queryKey: [
1705
+ "withdraw-preview",
1706
+ tokenSymbol,
1707
+ amountRaw,
1708
+ destinationChainId,
1709
+ destinationAddress,
1710
+ max != null ? max : false
1711
+ ],
1712
+ enabled,
1713
+ staleTime: 15e3,
1714
+ queryFn: () => client.withdrawPreview(__spreadValues({
1715
+ amountRaw,
1716
+ tokenSymbol,
1717
+ destinationChainId,
1718
+ destinationAddress
1719
+ }, max ? { max: true } : {}))
1720
+ });
1721
+ }
1655
1722
  // Annotate the CommonJS export names for ESM import in node:
1656
1723
  0 && (module.exports = {
1657
1724
  useDepositAddresses,
@@ -1659,5 +1726,6 @@ function useWithdrawalLifecycle(withdrawalId) {
1659
1726
  useWithdrawEstimate,
1660
1727
  useWithdrawFlow,
1661
1728
  useWithdrawManaged,
1729
+ useWithdrawPreview,
1662
1730
  useWithdrawalLifecycle
1663
1731
  });
package/dist/withdraw.mjs CHANGED
@@ -1,18 +1,20 @@
1
1
  import {
2
2
  useWithdrawEstimate,
3
3
  useWithdrawFlow,
4
+ useWithdrawPreview,
4
5
  useWithdrawalLifecycle
5
- } from "./chunk-OBHXWQ6L.mjs";
6
+ } from "./chunk-DK4YDVPH.mjs";
6
7
  import {
7
8
  useDepositAddresses,
8
9
  useManagedBalances,
9
10
  useWithdrawManaged
10
- } from "./chunk-VLYLQSDD.mjs";
11
+ } from "./chunk-V7VCT62L.mjs";
11
12
  export {
12
13
  useDepositAddresses,
13
14
  useManagedBalances,
14
15
  useWithdrawEstimate,
15
16
  useWithdrawFlow,
16
17
  useWithdrawManaged,
18
+ useWithdrawPreview,
17
19
  useWithdrawalLifecycle
18
20
  };