@agg-build/hooks 1.0.0 → 1.0.1

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.js CHANGED
@@ -82,8 +82,8 @@ __export(src_exports, {
82
82
  MarketStatus: () => MarketStatus,
83
83
  MatchStatus: () => MatchStatus,
84
84
  MatchType: () => MatchType,
85
- QueryClient: () => import_react_query35.QueryClient,
86
- QueryClientProvider: () => import_react_query35.QueryClientProvider,
85
+ QueryClient: () => import_react_query36.QueryClient,
86
+ QueryClientProvider: () => import_react_query36.QueryClientProvider,
87
87
  TurnstileChallengeError: () => import_sdk4.TurnstileChallengeError,
88
88
  Venue: () => Venue,
89
89
  computeClosedPositionTotals: () => computeClosedPositionTotals,
@@ -151,11 +151,12 @@ __export(src_exports, {
151
151
  useOnBalanceUpdate: () => useOnBalanceUpdate,
152
152
  useOnOrderSubmitted: () => useOnOrderSubmitted,
153
153
  useOnRedeemEvent: () => useOnRedeemEvent2,
154
+ useOnWithdrawalLifecycle: () => useOnWithdrawalLifecycle,
154
155
  useOrderBook: () => useOrderBook,
155
156
  useOrderbookQuote: () => useOrderbookQuote,
156
157
  useOrders: () => useOrders,
157
158
  usePositions: () => usePositions,
158
- useQueryClient: () => import_react_query35.useQueryClient,
159
+ useQueryClient: () => import_react_query36.useQueryClient,
159
160
  useQuoteManaged: () => useQuoteManaged,
160
161
  useRampQuotes: () => useRampQuotes,
161
162
  useRampSession: () => useRampSession,
@@ -174,7 +175,9 @@ __export(src_exports, {
174
175
  useVenueMarkets: () => useVenueMarkets,
175
176
  useViewportMidpoints: () => useViewportMidpoints,
176
177
  useVisibleIds: () => useVisibleIds,
177
- useWithdrawManaged: () => useWithdrawManaged
178
+ useWithdrawFlow: () => useWithdrawFlow,
179
+ useWithdrawManaged: () => useWithdrawManaged,
180
+ useWithdrawalLifecycle: () => useWithdrawalLifecycle
178
181
  });
179
182
  module.exports = __toCommonJS(src_exports);
180
183
 
@@ -300,7 +303,7 @@ var getVenueOrder = (venue) => {
300
303
  var sortVenues = (venues) => [...venues].sort((a, b) => getVenueOrder(a) - getVenueOrder(b));
301
304
 
302
305
  // src/index.ts
303
- var import_react_query35 = require("@tanstack/react-query");
306
+ var import_react_query36 = require("@tanstack/react-query");
304
307
 
305
308
  // src/candle-store.ts
306
309
  var import_sdk = require("@agg-build/sdk");
@@ -595,6 +598,8 @@ var enUsLabels = {
595
598
  successDescription: "Your USDC has been successfully added to your balance.",
596
599
  pendingTitle: (provider) => `Complete your payment on ${provider}`,
597
600
  pendingDescription: "Once your transaction is finished, your balance may take a few minutes to update. The deposit will appear in your activity once it's successful.",
601
+ pendingWalletAddressHelp: "Some providers may ask for a wallet address during checkout, use this one to receive your deposit:",
602
+ pendingCopyAddress: "Copy deposit address",
598
603
  viewActivity: "View Activity",
599
604
  chooseAnotherProvider: "Choose another provider",
600
605
  summary: {
@@ -631,9 +636,55 @@ var enUsLabels = {
631
636
  done: "Done",
632
637
  balancePrefix: "Balance:",
633
638
  methods: {
639
+ walletTitle: "Withdraw to wallet",
640
+ walletDescription: "Withdraw funds instantly to your crypto wallet",
634
641
  cardTitle: "Withdraw with card",
635
642
  cardDescription: "Withdraw funds to your card"
636
643
  },
644
+ walletFlow: {
645
+ title: "Withdraw to wallet",
646
+ recipientAddressLabel: "Recipient address",
647
+ amountLabel: "Amount",
648
+ max: "Max",
649
+ tokenLabel: "Receive token",
650
+ networkLabel: "Receive network",
651
+ confirm: "Confirm withdrawal",
652
+ successTitle: "Withdrawal submitted",
653
+ successDescription: (tokenSymbol) => `Your ${tokenSymbol} withdrawal is being processed and will arrive shortly.`,
654
+ // Terminal-state copy. The success step swaps `successTitle` /
655
+ // `successDescription` for these once the lifecycle has reached a
656
+ // terminal status — otherwise a finished withdrawal would keep showing
657
+ // "submitted / processing" forever and force the user to hard-refresh.
658
+ successTitleCompleted: "Withdrawal complete",
659
+ successDescriptionCompleted: (tokenSymbol) => `Your ${tokenSymbol} withdrawal has been delivered.`,
660
+ successTitlePartial: "Withdrawal partially completed",
661
+ successDescriptionPartial: (tokenSymbol) => `Some legs of your ${tokenSymbol} withdrawal completed; see details below.`,
662
+ successTitleFailed: "Withdrawal failed",
663
+ successDescriptionFailed: (tokenSymbol) => `Your ${tokenSymbol} withdrawal could not be completed.`,
664
+ summary: {
665
+ // The response is `pricingStatus: "unquoted"` — we don't know net
666
+ // output until on-chain settlement. Calling this "Amount received"
667
+ // would imply receipt before the lifecycle has confirmed. Keep it
668
+ // honest as the submitted amount until the multi-stable quote
669
+ // layer (PR-E) populates `expected.outputRaw`.
670
+ amountReceived: "Amount",
671
+ network: "Network",
672
+ toWallet: "To wallet",
673
+ fees: "Fees"
674
+ },
675
+ lifecycle: {
676
+ pending: "Submitted \u2014 preparing your withdrawal\u2026",
677
+ bridging: "Bridging funds across chains\u2026",
678
+ transferring: "Transferring to your wallet\u2026",
679
+ completed: "Withdrawal complete.",
680
+ partial: "Withdrawal partially completed \u2014 see details below.",
681
+ failed: "Withdrawal failed.",
682
+ steps: {
683
+ bridge: (sourceChainName, destChainName) => `Bridging from ${sourceChainName} to ${destChainName}`,
684
+ transfer: (destChainName) => `Transferring on ${destChainName}`
685
+ }
686
+ }
687
+ },
637
688
  cardFlow: {
638
689
  title: "Sell crypto",
639
690
  amountLabel: "Amount",
@@ -657,7 +708,10 @@ var enUsLabels = {
657
708
  }
658
709
  },
659
710
  summary: {
660
- amountReceived: "Amount received",
711
+ // Lifecycle-honest: until quoting is live (PR-E) the response is
712
+ // `pricingStatus: "unquoted"` so this is the submitted amount, not
713
+ // a guaranteed net output.
714
+ amountReceived: "Amount",
661
715
  network: "Network"
662
716
  }
663
717
  },
@@ -674,12 +728,16 @@ var enUsLabels = {
674
728
  userProfile: {
675
729
  activity: {
676
730
  depositType: "Deposit",
677
- withdrawalType: "Withdraw",
731
+ withdrawalType: "Withdrawal",
678
732
  depositTitles: {
679
733
  connectedWallet: "Deposit from connected wallet",
680
734
  externalWallet: "Deposit from external wallet",
681
735
  card: "Deposit with card"
682
736
  },
737
+ // Activity-row title for any withdrawal regardless of lifecycle
738
+ // state (pending / completed / failed) — render the asset rather
739
+ // than implying success. The ActivityRow renders a separate status
740
+ // chip when the row is failed.
683
741
  withdrawalTitle: (tokenSymbol) => `Withdraw ${tokenSymbol}`
684
742
  },
685
743
  positions: {
@@ -2190,6 +2248,20 @@ function useOnRedeemEvent(callback) {
2190
2248
  return listeners.addRedeemEventListener(handler);
2191
2249
  }, [listeners, hasCallback]);
2192
2250
  }
2251
+ function useOnWithdrawalLifecycle(callback) {
2252
+ const listeners = (0, import_react6.useContext)(AggWsUserEventContext);
2253
+ const callbackRef = (0, import_react6.useRef)(callback);
2254
+ callbackRef.current = callback;
2255
+ const hasCallback = callback !== null;
2256
+ (0, import_react6.useEffect)(() => {
2257
+ if (!listeners || !callbackRef.current) return;
2258
+ const handler = (msg) => {
2259
+ var _a;
2260
+ (_a = callbackRef.current) == null ? void 0 : _a.call(callbackRef, msg);
2261
+ };
2262
+ return listeners.addWithdrawalLifecycleListener(handler);
2263
+ }, [listeners, hasCallback]);
2264
+ }
2193
2265
  function AggWebSocketProvider({ children }) {
2194
2266
  const client = useAggClient();
2195
2267
  const { enableWebsocketsLogs } = useAggUiConfig();
@@ -2210,6 +2282,9 @@ function AggWebSocketProvider({ children }) {
2210
2282
  const balanceUpdateListenersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
2211
2283
  const orderEventListenersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
2212
2284
  const redeemEventListenersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
2285
+ const withdrawalLifecycleListenersRef = (0, import_react6.useRef)(
2286
+ /* @__PURE__ */ new Set()
2287
+ );
2213
2288
  const userEventListeners = (0, import_react6.useMemo)(
2214
2289
  () => ({
2215
2290
  addOrderSubmittedListener: (cb) => {
@@ -2235,6 +2310,12 @@ function AggWebSocketProvider({ children }) {
2235
2310
  return () => {
2236
2311
  redeemEventListenersRef.current.delete(cb);
2237
2312
  };
2313
+ },
2314
+ addWithdrawalLifecycleListener: (cb) => {
2315
+ withdrawalLifecycleListenersRef.current.add(cb);
2316
+ return () => {
2317
+ withdrawalLifecycleListenersRef.current.delete(cb);
2318
+ };
2238
2319
  }
2239
2320
  }),
2240
2321
  []
@@ -2409,6 +2490,14 @@ function AggWebSocketProvider({ children }) {
2409
2490
  listener(msg);
2410
2491
  }
2411
2492
  },
2493
+ onWithdrawalLifecycle: (msg) => {
2494
+ if (isClientAuthenticated) {
2495
+ invalidateBalanceCaches();
2496
+ }
2497
+ for (const listener of withdrawalLifecycleListenersRef.current) {
2498
+ listener(msg);
2499
+ }
2500
+ },
2412
2501
  onError: (msg) => {
2413
2502
  const outcomeId = resolveSnapshotUnavailableOutcomeId(msg.message);
2414
2503
  if (!outcomeId) return;
@@ -3135,6 +3224,9 @@ function useRampSession() {
3135
3224
  });
3136
3225
  }
3137
3226
 
3227
+ // src/withdraw/use-withdraw-flow.ts
3228
+ var import_react11 = require("react");
3229
+
3138
3230
  // src/execution/use-quote-managed.ts
3139
3231
  var import_react_query6 = require("@tanstack/react-query");
3140
3232
  function useQuoteManaged(options) {
@@ -3645,11 +3737,381 @@ var useRedeemEligibleCount = () => {
3645
3737
  return (_a = query.data) != null ? _a : 0;
3646
3738
  };
3647
3739
 
3740
+ // src/withdraw/use-withdraw-flow.ts
3741
+ var EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
3742
+ var SOLANA_ADDRESS_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
3743
+ var SOLANA_CHAIN_ID = 792703809;
3744
+ var WITHDRAWAL_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
3745
+ 1,
3746
+ // Ethereum
3747
+ 137,
3748
+ // Polygon
3749
+ 42161,
3750
+ // Arbitrum
3751
+ 8453,
3752
+ // Base
3753
+ 56,
3754
+ // BNB
3755
+ SOLANA_CHAIN_ID
3756
+ ]);
3757
+ var isValidDestinationAddress = (address, chainId) => {
3758
+ if (chainId === SOLANA_CHAIN_ID) return SOLANA_ADDRESS_REGEX.test(address);
3759
+ return EVM_ADDRESS_REGEX.test(address);
3760
+ };
3761
+ var DEFAULT_WITHDRAW_SUMMARY = {
3762
+ amountReceived: "",
3763
+ network: "",
3764
+ toWallet: "",
3765
+ fees: "\u2014"
3766
+ };
3767
+ var formatRawTokenAmount = (rawAmount, decimals) => {
3768
+ if (!rawAmount) return "0";
3769
+ const raw = BigInt(rawAmount);
3770
+ const divisor = BigInt(`1${"0".repeat(decimals)}`);
3771
+ const whole = raw / divisor;
3772
+ const remainder = raw % divisor;
3773
+ if (remainder === BigInt(0)) return whole.toString();
3774
+ return `${whole.toString()}.${remainder.toString().padStart(decimals, "0").replace(/0+$/, "")}`;
3775
+ };
3776
+ var formatRawTokenAmountForDisplay = (rawAmount, decimals, fractionDigits = 2) => {
3777
+ const [wholePart, fractionalPart = ""] = formatRawTokenAmount(rawAmount, decimals).split(".");
3778
+ const normalizedFraction = fractionalPart.padEnd(fractionDigits, "0").slice(0, fractionDigits);
3779
+ return `${wholePart}.${normalizedFraction}`;
3780
+ };
3781
+ var parseTokenAmountToRaw = (amount, decimals) => {
3782
+ const normalizedAmount = amount.trim();
3783
+ if (!normalizedAmount || !/^\d*(?:\.\d*)?$/.test(normalizedAmount)) {
3784
+ return null;
3785
+ }
3786
+ const [wholePart = "0", fractionalPart = ""] = normalizedAmount.split(".");
3787
+ if (fractionalPart.length > decimals) return null;
3788
+ const normalizedWhole = wholePart === "" ? "0" : wholePart;
3789
+ const normalizedFraction = fractionalPart.padEnd(decimals, "0");
3790
+ try {
3791
+ return `${BigInt(normalizedWhole)}${normalizedFraction}`.replace(/^0+(?=\d)/, "");
3792
+ } catch (e) {
3793
+ return null;
3794
+ }
3795
+ };
3796
+ var shortenAddress = (address) => address.length > 12 ? `${address.slice(0, 6)}....${address.slice(-4)}` : address;
3797
+ function useWithdrawFlow(options) {
3798
+ var _a, _b;
3799
+ const { open, onOpenChange } = options;
3800
+ const { totalBalance } = useAggBalanceState();
3801
+ const { balances } = useManagedBalances({ enabled: open });
3802
+ const { supportedChains } = useDepositAddresses({ enabled: open });
3803
+ const withdrawMutation = useWithdrawManaged();
3804
+ const syncBalances = useSyncBalances();
3805
+ const ws = useAggWebSocket();
3806
+ (0, import_react11.useEffect)(() => {
3807
+ if (!open) return;
3808
+ syncBalances.mutate(void 0, {
3809
+ onError: () => {
3810
+ }
3811
+ });
3812
+ }, [open]);
3813
+ const [withdrawDestination, setWithdrawDestination] = (0, import_react11.useState)("");
3814
+ const [withdrawAmount, setWithdrawAmount] = (0, import_react11.useState)("");
3815
+ const [withdrawToken, setWithdrawToken] = (0, import_react11.useState)("USDC");
3816
+ const [withdrawNetwork, setWithdrawNetwork] = (0, import_react11.useState)("");
3817
+ const [withdrawSummary, setWithdrawSummary] = (0, import_react11.useState)(DEFAULT_WITHDRAW_SUMMARY);
3818
+ const [withdrawalId, setWithdrawalId] = (0, import_react11.useState)(null);
3819
+ const networkOptions = (0, import_react11.useMemo)(
3820
+ () => (supportedChains != null ? supportedChains : []).filter((chain) => WITHDRAWAL_SUPPORTED_CHAIN_IDS.has(chain.chainId)).map((chain) => ({
3821
+ value: String(chain.chainId),
3822
+ label: chain.name
3823
+ })),
3824
+ [supportedChains]
3825
+ );
3826
+ const resolvedWithdrawNetwork = withdrawNetwork || ((_a = networkOptions[0]) == null ? void 0 : _a.value) || "";
3827
+ (0, import_react11.useEffect)(() => {
3828
+ if (!networkOptions.length) return;
3829
+ if (!withdrawNetwork || !networkOptions.some((option) => option.value === withdrawNetwork)) {
3830
+ setWithdrawNetwork(networkOptions[0].value);
3831
+ }
3832
+ }, [networkOptions, withdrawNetwork]);
3833
+ const tokenOptions = (0, import_react11.useMemo)(() => {
3834
+ var _a2, _b2, _c;
3835
+ const selectedChainId = Number(resolvedWithdrawNetwork);
3836
+ const supportedTokensForNetwork = (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === selectedChainId)) == null ? void 0 : _a2.tokens) != null ? _b2 : [];
3837
+ const withdrawableSymbols = new Set(supportedTokensForNetwork.map((token) => token.symbol));
3838
+ return ((_c = balances == null ? void 0 : balances.cash) != null ? _c : []).filter((cashEntry) => withdrawableSymbols.has(cashEntry.tokenSymbol)).map((cashEntry) => ({
3839
+ value: cashEntry.tokenSymbol,
3840
+ label: cashEntry.tokenSymbol
3841
+ }));
3842
+ }, [balances, resolvedWithdrawNetwork, supportedChains]);
3843
+ const resolvedWithdrawToken = tokenOptions.some((option) => option.value === withdrawToken) ? withdrawToken : ((_b = tokenOptions[0]) == null ? void 0 : _b.value) || "";
3844
+ (0, import_react11.useEffect)(() => {
3845
+ if (!tokenOptions.length) return;
3846
+ if (!tokenOptions.some((option) => option.value === withdrawToken)) {
3847
+ setWithdrawToken(tokenOptions[0].value);
3848
+ }
3849
+ }, [tokenOptions, withdrawToken]);
3850
+ const selectedCashEntry = (0, import_react11.useMemo)(
3851
+ () => balances == null ? void 0 : balances.cash.find((cashEntry) => cashEntry.tokenSymbol === resolvedWithdrawToken),
3852
+ [balances, resolvedWithdrawToken]
3853
+ );
3854
+ const selectedTokenDecimals = (0, import_react11.useMemo)(() => {
3855
+ var _a2, _b2, _c, _d;
3856
+ const selectedChainId = Number(resolvedWithdrawNetwork);
3857
+ 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;
3858
+ }, [
3859
+ resolvedWithdrawNetwork,
3860
+ resolvedWithdrawToken,
3861
+ selectedCashEntry == null ? void 0 : selectedCashEntry.decimals,
3862
+ supportedChains
3863
+ ]);
3864
+ const exactBalance = (0, import_react11.useMemo)(() => {
3865
+ if (!selectedCashEntry) return "0";
3866
+ return formatRawTokenAmount(selectedCashEntry.totalRaw, selectedCashEntry.decimals);
3867
+ }, [selectedCashEntry]);
3868
+ const balanceDisplay = (0, import_react11.useMemo)(() => {
3869
+ if (!selectedCashEntry) return `0.00 ${resolvedWithdrawToken || withdrawToken}`;
3870
+ return `${formatRawTokenAmountForDisplay(
3871
+ selectedCashEntry.totalRaw,
3872
+ selectedCashEntry.decimals
3873
+ )} ${resolvedWithdrawToken}`;
3874
+ }, [resolvedWithdrawToken, selectedCashEntry, withdrawToken]);
3875
+ const resetFlowState = (0, import_react11.useCallback)(() => {
3876
+ setWithdrawDestination("");
3877
+ setWithdrawAmount("");
3878
+ setWithdrawToken("USDC");
3879
+ setWithdrawNetwork("");
3880
+ setWithdrawSummary(DEFAULT_WITHDRAW_SUMMARY);
3881
+ setWithdrawalId(null);
3882
+ }, []);
3883
+ const handleWithdrawOpenChange = (0, import_react11.useCallback)(
3884
+ (isOpen) => {
3885
+ if (!isOpen) resetFlowState();
3886
+ onOpenChange(isOpen);
3887
+ },
3888
+ [onOpenChange, resetFlowState]
3889
+ );
3890
+ (0, import_react11.useEffect)(() => {
3891
+ if (!open) resetFlowState();
3892
+ }, [open, resetFlowState]);
3893
+ const handleWithdrawProvider = (0, import_react11.useCallback)(() => __async(null, null, function* () {
3894
+ var _a2, _b2;
3895
+ const destinationChainId = Number(resolvedWithdrawNetwork);
3896
+ const trimmedDestination = withdrawDestination.trim();
3897
+ const amountRaw = parseTokenAmountToRaw(withdrawAmount, selectedTokenDecimals);
3898
+ if (!amountRaw || BigInt(amountRaw) <= BigInt(0)) {
3899
+ throw new Error("Enter a withdrawal amount greater than zero.");
3900
+ }
3901
+ if (!Number.isFinite(destinationChainId) || destinationChainId <= 0) {
3902
+ throw new Error("Select a destination network.");
3903
+ }
3904
+ if (!isValidDestinationAddress(trimmedDestination, destinationChainId)) {
3905
+ const expected = destinationChainId === SOLANA_CHAIN_ID ? "a Solana wallet address (base58, 32\u201344 chars)" : "an EVM destination address (0x\u2026 40 hex chars)";
3906
+ throw new Error(`Enter ${expected}.`);
3907
+ }
3908
+ if (selectedCashEntry) {
3909
+ const scaleBy = (n, exp) => {
3910
+ if (exp <= 0) return n;
3911
+ return n * BigInt(`1${"0".repeat(exp)}`);
3912
+ };
3913
+ const balanceInDestFrame = (() => {
3914
+ const native = BigInt(selectedCashEntry.totalRaw);
3915
+ if (selectedCashEntry.decimals === selectedTokenDecimals) return native;
3916
+ if (selectedCashEntry.decimals > selectedTokenDecimals) {
3917
+ return native / scaleBy(BigInt(1), selectedCashEntry.decimals - selectedTokenDecimals);
3918
+ }
3919
+ return scaleBy(native, selectedTokenDecimals - selectedCashEntry.decimals);
3920
+ })();
3921
+ if (BigInt(amountRaw) > balanceInDestFrame) {
3922
+ throw new Error("Withdrawal amount exceeds your available balance.");
3923
+ }
3924
+ }
3925
+ ws == null ? void 0 : ws.connect();
3926
+ yield new Promise((resolve, reject) => {
3927
+ withdrawMutation.mutate(
3928
+ {
3929
+ amountRaw,
3930
+ tokenSymbol: resolvedWithdrawToken,
3931
+ destinationAddress: trimmedDestination,
3932
+ destinationChainId
3933
+ },
3934
+ {
3935
+ onSuccess: (data) => {
3936
+ setWithdrawalId(data.withdrawalId);
3937
+ resolve();
3938
+ },
3939
+ onError: reject
3940
+ }
3941
+ );
3942
+ });
3943
+ setWithdrawSummary({
3944
+ amountReceived: `${formatRawTokenAmountForDisplay(amountRaw, selectedTokenDecimals)} ${resolvedWithdrawToken}`,
3945
+ network: (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === destinationChainId)) == null ? void 0 : _a2.name) != null ? _b2 : resolvedWithdrawNetwork,
3946
+ toWallet: shortenAddress(trimmedDestination),
3947
+ fees: "\u2014"
3948
+ });
3949
+ }), [
3950
+ resolvedWithdrawNetwork,
3951
+ resolvedWithdrawToken,
3952
+ selectedCashEntry,
3953
+ selectedTokenDecimals,
3954
+ supportedChains,
3955
+ withdrawAmount,
3956
+ withdrawDestination,
3957
+ withdrawMutation,
3958
+ ws
3959
+ ]);
3960
+ return {
3961
+ open,
3962
+ onOpenChange: handleWithdrawOpenChange,
3963
+ withdrawFlow: {
3964
+ balance: totalBalance,
3965
+ balanceDisplay,
3966
+ amount: withdrawAmount,
3967
+ destinationWallet: withdrawDestination,
3968
+ tokenOptions,
3969
+ networkOptions,
3970
+ selectedToken: resolvedWithdrawToken,
3971
+ selectedNetwork: resolvedWithdrawNetwork,
3972
+ purchaseSummary: withdrawSummary,
3973
+ withdrawalId
3974
+ },
3975
+ onWithdrawDestinationChange: setWithdrawDestination,
3976
+ onWithdrawAmountChange: setWithdrawAmount,
3977
+ onWithdrawTokenChange: setWithdrawToken,
3978
+ onWithdrawNetworkChange: setWithdrawNetwork,
3979
+ onMaxClick: (0, import_react11.useCallback)(() => {
3980
+ setWithdrawAmount(exactBalance === "0" ? "0" : exactBalance);
3981
+ }, [exactBalance]),
3982
+ onSelectWithdrawProvider: (0, import_react11.useCallback)(
3983
+ (_providerId) => __async(null, null, function* () {
3984
+ return handleWithdrawProvider();
3985
+ }),
3986
+ [handleWithdrawProvider]
3987
+ ),
3988
+ onDoneWithdraw: (0, import_react11.useCallback)(() => handleWithdrawOpenChange(false), [handleWithdrawOpenChange])
3989
+ };
3990
+ }
3991
+
3992
+ // src/withdraw/use-withdrawal-lifecycle.ts
3993
+ var import_react12 = require("react");
3994
+ var import_react_query15 = require("@tanstack/react-query");
3995
+ var INITIAL_STATE = {
3996
+ pending: true,
3997
+ status: null,
3998
+ terminal: false,
3999
+ lastLeg: null,
4000
+ legs: [],
4001
+ errorMessage: null,
4002
+ timestamp: null
4003
+ };
4004
+ var restLegToWsLeg = (leg) => ({
4005
+ sourceChainId: leg.sourceChainId,
4006
+ destChainId: leg.destChainId,
4007
+ type: leg.type,
4008
+ // The wire-level WS leg status enum and the REST leg status enum are the
4009
+ // same union (planned/submitted/confirmed/failed). Keep the cast narrow to
4010
+ // avoid pulling the SDK enum apart for a one-line bridge.
4011
+ status: leg.status,
4012
+ amountRaw: leg.amountRaw,
4013
+ txHash: leg.txHash,
4014
+ bridgeOperationId: leg.bridgeOperationId
4015
+ });
4016
+ var mergeLegs = (prev, snapshot, delta) => {
4017
+ if (snapshot) return snapshot;
4018
+ if (!delta) return prev;
4019
+ const idx = prev.findIndex(
4020
+ (l) => l.sourceChainId === delta.sourceChainId && l.destChainId === delta.destChainId && l.type === delta.type
4021
+ );
4022
+ if (idx === -1) return [...prev, delta];
4023
+ const next = prev.slice();
4024
+ next[idx] = delta;
4025
+ return next;
4026
+ };
4027
+ var restToLifecycleState = (response) => {
4028
+ var _a;
4029
+ return {
4030
+ pending: false,
4031
+ status: response.status,
4032
+ terminal: response.status === "completed" || response.status === "partial" || response.status === "failed",
4033
+ lastLeg: null,
4034
+ legs: response.legs.map(restLegToWsLeg),
4035
+ errorMessage: (_a = response.errorMessage) != null ? _a : null,
4036
+ // No server timestamp on the REST response — we use 0 as "older than any
4037
+ // WS timestamp" so a subsequent WS event always wins. Callers that read
4038
+ // `timestamp` should treat 0/null interchangeably as "unset".
4039
+ timestamp: 0
4040
+ };
4041
+ };
4042
+ function useWithdrawalLifecycle(withdrawalId) {
4043
+ const client = useAggClient();
4044
+ const wsConnected = useAggWebSocketConnectionState();
4045
+ const queryClient = (0, import_react_query15.useQueryClient)();
4046
+ const [state, setState] = (0, import_react12.useState)(INITIAL_STATE);
4047
+ const stateRef = (0, import_react12.useRef)(state);
4048
+ stateRef.current = state;
4049
+ const balanceRefetchedForRef = (0, import_react12.useRef)(null);
4050
+ (0, import_react12.useEffect)(() => {
4051
+ setState(INITIAL_STATE);
4052
+ }, [withdrawalId]);
4053
+ (0, import_react12.useEffect)(() => {
4054
+ if (!withdrawalId) return;
4055
+ let cancelled = false;
4056
+ (() => __async(null, null, function* () {
4057
+ try {
4058
+ const response = yield client.getWithdrawalStatus(withdrawalId);
4059
+ if (cancelled) return;
4060
+ if (response.withdrawalId !== withdrawalId) return;
4061
+ const current = stateRef.current;
4062
+ const wsAlreadyWon = current.timestamp != null && current.timestamp > 0;
4063
+ if (wsAlreadyWon) return;
4064
+ setState(restToLifecycleState(response));
4065
+ } catch (e) {
4066
+ }
4067
+ }))();
4068
+ return () => {
4069
+ cancelled = true;
4070
+ };
4071
+ }, [client, withdrawalId, wsConnected]);
4072
+ const handler = (0, import_react12.useMemo)(() => {
4073
+ if (!withdrawalId) return null;
4074
+ return (msg) => {
4075
+ if (msg.withdrawalId !== withdrawalId) return;
4076
+ setState((prev) => {
4077
+ var _a, _b;
4078
+ return {
4079
+ pending: false,
4080
+ status: msg.status,
4081
+ terminal: msg.terminal,
4082
+ lastLeg: (_a = msg.leg) != null ? _a : null,
4083
+ // `legs[]` is the cumulative server-known truth. Snapshots
4084
+ // (`pending` / terminal rollup) carry a full `legs[]` and replace
4085
+ // it. Intermediate per-leg deltas carry only `leg` (no `legs[]`)
4086
+ // — merge the delta into the existing array by
4087
+ // (sourceChainId, destChainId, type) so the timeline UI doesn't
4088
+ // collapse to empty between snapshots.
4089
+ legs: mergeLegs(prev.legs, msg.legs, msg.leg),
4090
+ errorMessage: (_b = msg.errorMessage) != null ? _b : null,
4091
+ timestamp: msg.timestamp
4092
+ };
4093
+ });
4094
+ };
4095
+ }, [withdrawalId]);
4096
+ useOnWithdrawalLifecycle(handler);
4097
+ (0, import_react12.useEffect)(() => {
4098
+ if (!withdrawalId) return;
4099
+ if (!state.terminal) return;
4100
+ if (balanceRefetchedForRef.current === withdrawalId) return;
4101
+ balanceRefetchedForRef.current = withdrawalId;
4102
+ invalidateBalanceQueries(queryClient);
4103
+ client.syncManagedBalances().catch(() => {
4104
+ });
4105
+ }, [client, queryClient, state.terminal, withdrawalId]);
4106
+ const reset = (0, import_react12.useCallback)(() => setState(INITIAL_STATE), []);
4107
+ return { state, reset };
4108
+ }
4109
+
3648
4110
  // src/index.ts
3649
4111
  var import_sdk4 = require("@agg-build/sdk");
3650
4112
 
3651
4113
  // src/use-geo-block.ts
3652
- var import_react11 = require("react");
4114
+ var import_react13 = require("react");
3653
4115
  var DEFAULT_STATE = {
3654
4116
  isLocationBlocked: false,
3655
4117
  isTradingBlocked: false,
@@ -3657,7 +4119,7 @@ var DEFAULT_STATE = {
3657
4119
  };
3658
4120
  function useGeoBlock() {
3659
4121
  var _a, _b;
3660
- const authContext = (0, import_react11.useContext)(AggAuthContext);
4122
+ const authContext = (0, import_react13.useContext)(AggAuthContext);
3661
4123
  if (process.env.NEXT_PUBLIC_GEO_BLOCK_DISABLE === "true") return DEFAULT_STATE;
3662
4124
  const isBlocked = (_b = (_a = authContext == null ? void 0 : authContext.user) == null ? void 0 : _a.isLocationBlocked) != null ? _b : false;
3663
4125
  if (!isBlocked) return DEFAULT_STATE;
@@ -3669,7 +4131,7 @@ function useGeoBlock() {
3669
4131
  }
3670
4132
 
3671
4133
  // src/use-agg-auth.ts
3672
- var import_react12 = require("react");
4134
+ var import_react14 = require("react");
3673
4135
  function useAggAuth(options = {}) {
3674
4136
  const {
3675
4137
  isAuthenticated,
@@ -3679,7 +4141,7 @@ function useAggAuth(options = {}) {
3679
4141
  signIn: signInWithProvider,
3680
4142
  signOut
3681
4143
  } = useAggAuthContext();
3682
- const signIn = (0, import_react12.useCallback)(
4144
+ const signIn = (0, import_react14.useCallback)(
3683
4145
  (statement) => __async(null, null, function* () {
3684
4146
  if (!options.signMessage) {
3685
4147
  throw new Error(
@@ -3703,11 +4165,11 @@ function useAggAuth(options = {}) {
3703
4165
  }
3704
4166
 
3705
4167
  // src/use-link-account.ts
3706
- var import_react13 = require("react");
4168
+ var import_react15 = require("react");
3707
4169
  function useLinkAccount() {
3708
4170
  const client = useAggClient();
3709
- const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
3710
- const [error, setError] = (0, import_react13.useState)(null);
4171
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
4172
+ const [error, setError] = (0, import_react15.useState)(null);
3711
4173
  const run = (fn) => {
3712
4174
  setIsLoading(true);
3713
4175
  setError(null);
@@ -3717,11 +4179,11 @@ function useLinkAccount() {
3717
4179
  throw err;
3718
4180
  }).finally(() => setIsLoading(false));
3719
4181
  };
3720
- const startLink = (0, import_react13.useCallback)(
4182
+ const startLink = (0, import_react15.useCallback)(
3721
4183
  (body) => run(() => client.linkAccount(body)),
3722
4184
  [client]
3723
4185
  );
3724
- const confirmLink = (0, import_react13.useCallback)(
4186
+ const confirmLink = (0, import_react15.useCallback)(
3725
4187
  (token) => run(() => client.linkAccountConfirm(token)),
3726
4188
  [client]
3727
4189
  );
@@ -3736,13 +4198,13 @@ var requestAggAuthChooserOpen = () => {
3736
4198
  };
3737
4199
 
3738
4200
  // src/use-categories.ts
3739
- var import_react_query15 = require("@tanstack/react-query");
4201
+ var import_react_query16 = require("@tanstack/react-query");
3740
4202
  function useCategories(options) {
3741
4203
  var _a, _b, _c, _d;
3742
4204
  const client = useAggClient();
3743
4205
  const enabled = (_a = options == null ? void 0 : options.enabled) != null ? _a : true;
3744
4206
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
3745
- const query = (0, import_react_query15.useInfiniteQuery)({
4207
+ const query = (0, import_react_query16.useInfiniteQuery)({
3746
4208
  queryKey: ["categories", limit],
3747
4209
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
3748
4210
  const res = yield client.getCategories({
@@ -3767,10 +4229,10 @@ function useCategories(options) {
3767
4229
  }
3768
4230
 
3769
4231
  // src/use-debounced-value.ts
3770
- var import_react14 = require("react");
4232
+ var import_react16 = require("react");
3771
4233
  function useDebouncedValue(value, delay) {
3772
- const [debouncedValue, setDebouncedValue] = (0, import_react14.useState)(value);
3773
- (0, import_react14.useEffect)(() => {
4234
+ const [debouncedValue, setDebouncedValue] = (0, import_react16.useState)(value);
4235
+ (0, import_react16.useEffect)(() => {
3774
4236
  const timeoutId = window.setTimeout(() => {
3775
4237
  setDebouncedValue(value);
3776
4238
  }, delay);
@@ -3782,12 +4244,12 @@ function useDebouncedValue(value, delay) {
3782
4244
  }
3783
4245
 
3784
4246
  // src/use-execution-orders.ts
3785
- var import_react_query16 = require("@tanstack/react-query");
4247
+ var import_react_query17 = require("@tanstack/react-query");
3786
4248
  function useExecutionOrders(options = {}) {
3787
4249
  var _a, _b;
3788
4250
  const client = useAggClient();
3789
4251
  const { status, limit = 50, enabled = true, refetchIntervalMs = false } = options;
3790
- const query = (0, import_react_query16.useInfiniteQuery)({
4252
+ const query = (0, import_react_query17.useInfiniteQuery)({
3791
4253
  queryKey: ["execution-orders", status != null ? status : "all", limit],
3792
4254
  queryFn: ({ pageParam }) => client.getExecutionOrders({
3793
4255
  status,
@@ -3811,12 +4273,12 @@ function useExecutionOrders(options = {}) {
3811
4273
  }
3812
4274
 
3813
4275
  // src/use-user-activity.ts
3814
- var import_react_query17 = require("@tanstack/react-query");
4276
+ var import_react_query18 = require("@tanstack/react-query");
3815
4277
  function useUserActivity(options = {}) {
3816
4278
  var _a, _b;
3817
4279
  const client = useAggClient();
3818
4280
  const { type, limit = 50, enabled = true } = options;
3819
- const query = (0, import_react_query17.useInfiniteQuery)({
4281
+ const query = (0, import_react_query18.useInfiniteQuery)({
3820
4282
  queryKey: ["user-activity", type != null ? type : "all", limit],
3821
4283
  queryFn: ({ pageParam }) => client.getUserActivity({
3822
4284
  type,
@@ -3839,13 +4301,13 @@ function useUserActivity(options = {}) {
3839
4301
  }
3840
4302
 
3841
4303
  // src/use-external-id.ts
3842
- var import_react15 = require("react");
4304
+ var import_react17 = require("react");
3843
4305
  function useExternalId(options = {}) {
3844
4306
  const client = useAggClient();
3845
4307
  const { onSuccess, onError: onErrorCb } = options;
3846
- const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
3847
- const [error, setError] = (0, import_react15.useState)(null);
3848
- const linkExternalId = (0, import_react15.useCallback)(
4308
+ const [isLoading, setIsLoading] = (0, import_react17.useState)(false);
4309
+ const [error, setError] = (0, import_react17.useState)(null);
4310
+ const linkExternalId = (0, import_react17.useCallback)(
3849
4311
  (assertion) => __async(null, null, function* () {
3850
4312
  setIsLoading(true);
3851
4313
  setError(null);
@@ -3868,12 +4330,12 @@ function useExternalId(options = {}) {
3868
4330
  }
3869
4331
 
3870
4332
  // src/use-execution-positions.ts
3871
- var import_react_query18 = require("@tanstack/react-query");
4333
+ var import_react_query19 = require("@tanstack/react-query");
3872
4334
  function useExecutionPositions(options = {}) {
3873
4335
  var _a, _b;
3874
4336
  const client = useAggClient();
3875
4337
  const { limit = 50, status, enabled = true } = options;
3876
- const query = (0, import_react_query18.useInfiniteQuery)({
4338
+ const query = (0, import_react_query19.useInfiniteQuery)({
3877
4339
  queryKey: executionKeys.positions(null, limit, status != null ? status : null),
3878
4340
  queryFn: ({ pageParam }) => client.getExecutionPositions({
3879
4341
  limit,
@@ -3896,17 +4358,17 @@ function useExecutionPositions(options = {}) {
3896
4358
  }
3897
4359
 
3898
4360
  // src/use-live-candle-overlay.ts
3899
- var import_react19 = require("react");
4361
+ var import_react21 = require("react");
3900
4362
 
3901
4363
  // src/use-live-candles.ts
3902
- var import_react18 = require("react");
4364
+ var import_react20 = require("react");
3903
4365
  var import_sdk3 = require("@agg-build/sdk");
3904
4366
 
3905
4367
  // src/use-market-chart.ts
3906
- var import_react_query19 = require("@tanstack/react-query");
4368
+ var import_react_query20 = require("@tanstack/react-query");
3907
4369
 
3908
4370
  // src/market-data/subscription.ts
3909
- var import_react16 = require("react");
4371
+ var import_react18 = require("react");
3910
4372
  function useMarketDataSubscription({
3911
4373
  marketId,
3912
4374
  additionalMarketIds,
@@ -3915,7 +4377,7 @@ function useMarketDataSubscription({
3915
4377
  trades = false
3916
4378
  }) {
3917
4379
  const ws = useAggWebSocket();
3918
- const allIds = (0, import_react16.useMemo)(() => {
4380
+ const allIds = (0, import_react18.useMemo)(() => {
3919
4381
  const ids = /* @__PURE__ */ new Set();
3920
4382
  if (marketId) ids.add(marketId);
3921
4383
  if (additionalMarketIds) {
@@ -3926,7 +4388,7 @@ function useMarketDataSubscription({
3926
4388
  return [...ids];
3927
4389
  }, [marketId, additionalMarketIds]);
3928
4390
  const stableKey = allIds.join("|");
3929
- (0, import_react16.useEffect)(() => {
4391
+ (0, import_react18.useEffect)(() => {
3930
4392
  if (!ws || !allIds.length || !enabled || !orderbook && !trades) return;
3931
4393
  const unsubscribers = [];
3932
4394
  for (const id of allIds) {
@@ -3989,7 +4451,7 @@ function useMarketChart(options) {
3989
4451
  orderbook: true,
3990
4452
  trades: true
3991
4453
  });
3992
- const queries = (0, import_react_query19.useQueries)({
4454
+ const queries = (0, import_react_query20.useQueries)({
3993
4455
  queries: outcomeIds.map((outcomeId) => ({
3994
4456
  queryKey: marketDataKeys.chart(outcomeId, interval, startTs, endTs, countBack),
3995
4457
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
@@ -4016,7 +4478,7 @@ function useMarketChart(options) {
4016
4478
  gcTime: 5 * 6e4,
4017
4479
  refetchOnWindowFocus: false,
4018
4480
  retry: 1,
4019
- placeholderData: import_react_query19.keepPreviousData
4481
+ placeholderData: import_react_query20.keepPreviousData
4020
4482
  }))
4021
4483
  });
4022
4484
  const successfulDatasets = queries.flatMap((query) => {
@@ -4045,13 +4507,13 @@ function useMarketChart(options) {
4045
4507
  }
4046
4508
 
4047
4509
  // src/use-live-market-stores.ts
4048
- var import_react17 = require("react");
4510
+ var import_react19 = require("react");
4049
4511
  function useLiveMarketStores(venueMarketIds) {
4050
4512
  const ws = useAggWebSocket();
4051
- const [, forceRender] = (0, import_react17.useReducer)((c) => c + 1, 0);
4052
- const subsRef = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
4053
- const stableKey = (0, import_react17.useMemo)(() => venueMarketIds.slice().sort().join("|"), [venueMarketIds]);
4054
- (0, import_react17.useEffect)(() => {
4513
+ const [, forceRender] = (0, import_react19.useReducer)((c) => c + 1, 0);
4514
+ const subsRef = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
4515
+ const stableKey = (0, import_react19.useMemo)(() => venueMarketIds.slice().sort().join("|"), [venueMarketIds]);
4516
+ (0, import_react19.useEffect)(() => {
4055
4517
  if (!ws || venueMarketIds.length === 0) return;
4056
4518
  const current = subsRef.current;
4057
4519
  const desired = new Set(venueMarketIds);
@@ -4088,7 +4550,7 @@ function candleToLive(c, source) {
4088
4550
  function useLiveCandles(options) {
4089
4551
  var _a;
4090
4552
  const { market, interval = "5m", mode = "venue", startTs, endTs } = options;
4091
- const venueMarketIds = (0, import_react18.useMemo)(() => {
4553
+ const venueMarketIds = (0, import_react20.useMemo)(() => {
4092
4554
  if (!market) return [];
4093
4555
  if (mode === "venue") return [market.id];
4094
4556
  const ids = [market.id];
@@ -4108,7 +4570,7 @@ function useLiveCandles(options) {
4108
4570
  endTs: endTs != null ? endTs : null,
4109
4571
  enabled: !!restMarketId && startTs != null && endTs != null
4110
4572
  });
4111
- const liveData = (0, import_react18.useMemo)(() => {
4573
+ const liveData = (0, import_react20.useMemo)(() => {
4112
4574
  if (builders2.length === 0) return { closed: [], forming: null };
4113
4575
  if (mode === "venue" || builders2.length === 1) {
4114
4576
  return {
@@ -4121,7 +4583,7 @@ function useLiveCandles(options) {
4121
4583
  forming: (0, import_sdk3.mergeCandles)(builders2.map((b) => b.getForming(interval)))
4122
4584
  };
4123
4585
  }, [builders2, interval, mode]);
4124
- const candles = (0, import_react18.useMemo)(() => {
4586
+ const candles = (0, import_react20.useMemo)(() => {
4125
4587
  const byTime = /* @__PURE__ */ new Map();
4126
4588
  if (chartData) {
4127
4589
  const venueEntries = Object.values(chartData.venues);
@@ -4146,7 +4608,7 @@ function useLiveCandles(options) {
4146
4608
  merged.sort((a, b) => a.time - b.time);
4147
4609
  return merged;
4148
4610
  }, [chartData, liveData.closed]);
4149
- const liveCandle = (0, import_react18.useMemo)(() => {
4611
+ const liveCandle = (0, import_react20.useMemo)(() => {
4150
4612
  if (!liveData.forming) return null;
4151
4613
  return candleToLive(liveData.forming, "live");
4152
4614
  }, [liveData.forming]);
@@ -4194,7 +4656,7 @@ function useLiveCandleOverlay(options) {
4194
4656
  startTs,
4195
4657
  endTs
4196
4658
  });
4197
- const scaleCandle = (0, import_react19.useCallback)(
4659
+ const scaleCandle = (0, import_react21.useCallback)(
4198
4660
  (candle) => ({
4199
4661
  time: candle.time,
4200
4662
  open: candle.o * scale,
@@ -4205,8 +4667,8 @@ function useLiveCandleOverlay(options) {
4205
4667
  }),
4206
4668
  [scale]
4207
4669
  );
4208
- const scaledCandles = (0, import_react19.useMemo)(() => rawCandles.map(scaleCandle), [rawCandles, scaleCandle]);
4209
- const liveCandle = (0, import_react19.useMemo)(() => rawLive ? scaleCandle(rawLive) : null, [rawLive, scaleCandle]);
4670
+ const scaledCandles = (0, import_react21.useMemo)(() => rawCandles.map(scaleCandle), [rawCandles, scaleCandle]);
4671
+ const liveCandle = (0, import_react21.useMemo)(() => rawLive ? scaleCandle(rawLive) : null, [rawLive, scaleCandle]);
4210
4672
  return {
4211
4673
  liveCandle,
4212
4674
  scaledCandles,
@@ -4217,7 +4679,7 @@ function useLiveCandleOverlay(options) {
4217
4679
  }
4218
4680
 
4219
4681
  // src/use-event-orderbook-data.ts
4220
- var import_react20 = require("react");
4682
+ var import_react22 = require("react");
4221
4683
  function extractSelectedOutcomeIds(selectedMarket) {
4222
4684
  var _a, _b, _c;
4223
4685
  if (!selectedMarket) return [];
@@ -4237,17 +4699,17 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
4237
4699
  const {
4238
4700
  features: { enableLiveUpdates }
4239
4701
  } = useAggUiConfig();
4240
- const selectedMarket = (0, import_react20.useMemo)(() => {
4702
+ const selectedMarket = (0, import_react22.useMemo)(() => {
4241
4703
  var _a;
4242
4704
  if (!selectedMarketId || !(venueMarkets == null ? void 0 : venueMarkets.length)) return null;
4243
4705
  return (_a = venueMarkets.find((m) => m.id === selectedMarketId)) != null ? _a : null;
4244
4706
  }, [venueMarkets, selectedMarketId]);
4245
- const selectedOutcomeIds = (0, import_react20.useMemo)(
4707
+ const selectedOutcomeIds = (0, import_react22.useMemo)(
4246
4708
  () => extractSelectedOutcomeIds(selectedMarket),
4247
4709
  [selectedMarket]
4248
4710
  );
4249
4711
  const selectedKey = selectedOutcomeIds.join("|");
4250
- (0, import_react20.useEffect)(() => {
4712
+ (0, import_react22.useEffect)(() => {
4251
4713
  if (!ws || !enableLiveUpdates || !selectedOutcomeIds.length) return;
4252
4714
  const unsubscribers = selectedOutcomeIds.map((id) => ws.subscribe(id, "orderbook"));
4253
4715
  return () => {
@@ -4257,7 +4719,7 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
4257
4719
  }
4258
4720
 
4259
4721
  // src/use-live-market.ts
4260
- var import_react_query20 = require("@tanstack/react-query");
4722
+ var import_react_query21 = require("@tanstack/react-query");
4261
4723
  function outcomeOrderbookToState(response, marketId) {
4262
4724
  var _a, _b, _c, _d;
4263
4725
  const { venue, orderbook, midpoint, spread, seq, checksum, timestamp, venueMarketOutcomeId } = response;
@@ -4307,7 +4769,7 @@ function useLiveMarket(canonicalMarketId) {
4307
4769
  enabled: isLiveSubscriptionEnabled,
4308
4770
  orderbook: true
4309
4771
  });
4310
- const query = (0, import_react_query20.useQuery)({
4772
+ const query = (0, import_react_query21.useQuery)({
4311
4773
  queryKey: marketDataKeys.live(canonicalMarketId != null ? canonicalMarketId : "__disabled__"),
4312
4774
  queryFn: () => __async(null, null, function* () {
4313
4775
  return createMarketLiveState(canonicalMarketId != null ? canonicalMarketId : "__disabled__");
@@ -4319,7 +4781,7 @@ function useLiveMarket(canonicalMarketId) {
4319
4781
  isConnected: Boolean(isLiveSubscriptionEnabled && isConnected)
4320
4782
  })
4321
4783
  });
4322
- const seedQuery = (0, import_react_query20.useQuery)({
4784
+ const seedQuery = (0, import_react_query21.useQuery)({
4323
4785
  queryKey: ["live-market-seed", canonicalMarketId],
4324
4786
  queryFn: ({ signal }) => canonicalMarketId ? client.getOutcomeOrderbook(canonicalMarketId, { signal }) : Promise.resolve(null),
4325
4787
  enabled: Boolean(canonicalMarketId),
@@ -4339,8 +4801,8 @@ function useLiveMarket(canonicalMarketId) {
4339
4801
  }
4340
4802
 
4341
4803
  // src/use-live-outcome-prices.ts
4342
- var import_react21 = require("react");
4343
- var import_react_query21 = require("@tanstack/react-query");
4804
+ var import_react23 = require("react");
4805
+ var import_react_query22 = require("@tanstack/react-query");
4344
4806
  var EMPTY_PRICES = /* @__PURE__ */ new Map();
4345
4807
  var buildMidpointFingerprint = (outcomeIds, queries) => {
4346
4808
  var _a, _b, _c;
@@ -4355,7 +4817,7 @@ function useLiveOutcomePrices(venueMarkets) {
4355
4817
  const {
4356
4818
  features: { enableLiveUpdates }
4357
4819
  } = useAggUiConfig();
4358
- const outcomeIds = (0, import_react21.useMemo)(() => {
4820
+ const outcomeIds = (0, import_react23.useMemo)(() => {
4359
4821
  var _a;
4360
4822
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
4361
4823
  const ids = /* @__PURE__ */ new Set();
@@ -4366,7 +4828,7 @@ function useLiveOutcomePrices(venueMarkets) {
4366
4828
  }
4367
4829
  return [...ids].sort();
4368
4830
  }, [venueMarkets]);
4369
- const queries = (0, import_react_query21.useQueries)({
4831
+ const queries = (0, import_react_query22.useQueries)({
4370
4832
  queries: outcomeIds.map((id) => ({
4371
4833
  queryKey: marketDataKeys.live(id),
4372
4834
  queryFn: () => createMarketLiveState(id),
@@ -4377,11 +4839,11 @@ function useLiveOutcomePrices(venueMarkets) {
4377
4839
  }))
4378
4840
  });
4379
4841
  const fingerprint = buildMidpointFingerprint(outcomeIds, queries);
4380
- const prevRef = (0, import_react21.useRef)({
4842
+ const prevRef = (0, import_react23.useRef)({
4381
4843
  fingerprint: "",
4382
4844
  prices: EMPTY_PRICES
4383
4845
  });
4384
- const data = (0, import_react21.useMemo)(() => {
4846
+ const data = (0, import_react23.useMemo)(() => {
4385
4847
  var _a, _b, _c, _d;
4386
4848
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return EMPTY_PRICES;
4387
4849
  if (fingerprint === prevRef.current.fingerprint) {
@@ -4400,7 +4862,9 @@ function useLiveOutcomePrices(venueMarkets) {
4400
4862
  continue;
4401
4863
  }
4402
4864
  const liveMidpoint = liveByOutcomeId.get(outcome.id);
4403
- prices.set(outcome.id, liveMidpoint != null ? liveMidpoint : outcome.price);
4865
+ if (liveMidpoint != null) {
4866
+ prices.set(outcome.id, liveMidpoint);
4867
+ }
4404
4868
  }
4405
4869
  }
4406
4870
  prevRef.current = { fingerprint, prices };
@@ -4428,8 +4892,8 @@ function useLiveTrades(canonicalMarketId) {
4428
4892
  }
4429
4893
 
4430
4894
  // src/use-midpoints.ts
4431
- var import_react22 = require("react");
4432
- var import_react_query22 = require("@tanstack/react-query");
4895
+ var import_react24 = require("react");
4896
+ var import_react_query23 = require("@tanstack/react-query");
4433
4897
  var normalizeVenueMarketIds = (venueMarkets) => {
4434
4898
  return [...new Set((venueMarkets != null ? venueMarkets : []).map((market) => market.id).filter(Boolean))].sort(
4435
4899
  (left, right) => left.localeCompare(right)
@@ -4437,8 +4901,8 @@ var normalizeVenueMarketIds = (venueMarkets) => {
4437
4901
  };
4438
4902
  function useMidpoints(venueMarkets) {
4439
4903
  const client = useAggClient();
4440
- const ids = (0, import_react22.useMemo)(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
4441
- const { data, isLoading } = (0, import_react_query22.useQuery)({
4904
+ const ids = (0, import_react24.useMemo)(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
4905
+ const { data, isLoading } = (0, import_react_query23.useQuery)({
4442
4906
  queryKey: ["midpoints", ids],
4443
4907
  queryFn: () => client.getMidpoints(ids),
4444
4908
  enabled: ids.length > 0,
@@ -4448,29 +4912,43 @@ function useMidpoints(venueMarkets) {
4448
4912
  refetchOnWindowFocus: false,
4449
4913
  refetchOnReconnect: false
4450
4914
  });
4451
- const prices = (0, import_react22.useMemo)(() => {
4452
- var _a, _b, _c, _d;
4915
+ const result = (0, import_react24.useMemo)(() => {
4916
+ var _a, _b, _c, _d, _e, _f;
4453
4917
  const map = /* @__PURE__ */ new Map();
4454
- if (!(data == null ? void 0 : data.data) || !venueMarkets) return map;
4918
+ const venueMap = /* @__PURE__ */ new Map();
4919
+ if (!(data == null ? void 0 : data.data) || !venueMarkets) return { map, venueMap };
4455
4920
  for (const item of data.data) {
4456
4921
  if ((_a = item.outcomes) == null ? void 0 : _a.length) {
4457
4922
  for (const o of item.outcomes) {
4458
4923
  if (o.midpoint != null) {
4459
4924
  map.set(o.venueMarketOutcomeId, o.midpoint);
4925
+ if (item.venue) venueMap.set(o.venueMarketOutcomeId, item.venue);
4460
4926
  }
4461
4927
  }
4462
4928
  if ((_b = item.matched) == null ? void 0 : _b.length) {
4463
- for (const m of item.matched) {
4464
- if (m.midpoint != null) {
4465
- const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
4466
- if (!market) continue;
4929
+ const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
4930
+ if (market) {
4931
+ const primaryYesOutcome = market.venueMarketOutcomes.find(
4932
+ (o) => {
4933
+ var _a2;
4934
+ return ((_a2 = o.label) == null ? void 0 : _a2.toLowerCase()) === "yes";
4935
+ }
4936
+ );
4937
+ const primaryYesMidpoint = primaryYesOutcome ? (_c = map.get(primaryYesOutcome.id)) != null ? _c : null : null;
4938
+ let bestMatchedMidpoint = null;
4939
+ let bestMatchedVenue = null;
4940
+ for (const m of item.matched) {
4941
+ if (m.midpoint == null) continue;
4942
+ if (bestMatchedMidpoint == null || m.midpoint < bestMatchedMidpoint) {
4943
+ bestMatchedMidpoint = m.midpoint;
4944
+ bestMatchedVenue = (_d = m.venue) != null ? _d : null;
4945
+ }
4946
+ }
4947
+ if (bestMatchedMidpoint != null && (primaryYesMidpoint == null || bestMatchedMidpoint < primaryYesMidpoint)) {
4467
4948
  for (const outcome of market.venueMarketOutcomes) {
4468
- const existing = map.get(outcome.id);
4469
- const isYes = ((_c = outcome.label) == null ? void 0 : _c.toLowerCase()) === "yes";
4470
- const matchedPrice = isYes ? m.midpoint : 1 - m.midpoint;
4471
- if (existing == null || isYes && matchedPrice > existing || !isYes && matchedPrice < existing) {
4472
- map.set(outcome.id, matchedPrice);
4473
- }
4949
+ const isYes = ((_e = outcome.label) == null ? void 0 : _e.toLowerCase()) === "yes";
4950
+ map.set(outcome.id, isYes ? bestMatchedMidpoint : 1 - bestMatchedMidpoint);
4951
+ if (bestMatchedVenue) venueMap.set(outcome.id, bestMatchedVenue);
4474
4952
  }
4475
4953
  }
4476
4954
  }
@@ -4481,21 +4959,26 @@ function useMidpoints(venueMarkets) {
4481
4959
  const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
4482
4960
  if (!market) continue;
4483
4961
  for (const outcome of market.venueMarketOutcomes) {
4484
- const isYes = ((_d = outcome.label) == null ? void 0 : _d.toLowerCase()) === "yes";
4962
+ const isYes = ((_f = outcome.label) == null ? void 0 : _f.toLowerCase()) === "yes";
4485
4963
  map.set(outcome.id, isYes ? item.midpoint : 1 - item.midpoint);
4964
+ if (item.venue) venueMap.set(outcome.id, item.venue);
4486
4965
  }
4487
4966
  }
4488
4967
  }
4489
- return map;
4968
+ return { map, venueMap };
4490
4969
  }, [data, venueMarkets]);
4491
- return { prices, isLoading: isLoading && ids.length > 0 };
4970
+ return {
4971
+ prices: result.map,
4972
+ venueByOutcomeId: result.venueMap,
4973
+ isLoading: isLoading && ids.length > 0
4974
+ };
4492
4975
  }
4493
4976
 
4494
4977
  // src/use-market-orderbook.ts
4495
- var import_react_query23 = require("@tanstack/react-query");
4978
+ var import_react_query24 = require("@tanstack/react-query");
4496
4979
  function useMarketOrderbook(options) {
4497
4980
  var _a, _b, _c, _d, _e, _f, _g;
4498
- const queryClient = (0, import_react_query23.useQueryClient)();
4981
+ const queryClient = (0, import_react_query24.useQueryClient)();
4499
4982
  const ws = useAggWebSocket();
4500
4983
  const isConnected = useAggWebSocketConnectionState();
4501
4984
  const {
@@ -4512,7 +4995,7 @@ function useMarketOrderbook(options) {
4512
4995
  enabled: enabled && !!selectedOutcomeId,
4513
4996
  orderbook: true
4514
4997
  });
4515
- const liveQueries = (0, import_react_query23.useQueries)({
4998
+ const liveQueries = (0, import_react_query24.useQueries)({
4516
4999
  queries: subscriptionIds.map((subscriptionId) => ({
4517
5000
  queryKey: marketDataKeys.live(subscriptionId),
4518
5001
  queryFn: () => createMarketLiveState(subscriptionId),
@@ -4578,7 +5061,7 @@ function useMarketOrderbook(options) {
4578
5061
  }
4579
5062
 
4580
5063
  // src/use-order-book.ts
4581
- var import_react_query24 = require("@tanstack/react-query");
5064
+ var import_react_query25 = require("@tanstack/react-query");
4582
5065
  function useOrderBook(options) {
4583
5066
  const client = useAggClient();
4584
5067
  const { orderbooks, enabled = true, canonicalMarketId } = options;
@@ -4591,7 +5074,7 @@ function useOrderBook(options) {
4591
5074
  venueMarketOutcomeId: outcome.id
4592
5075
  })) : void 0
4593
5076
  });
4594
- const batchedResult = (0, import_react_query24.useQuery)({
5077
+ const batchedResult = (0, import_react_query25.useQuery)({
4595
5078
  queryKey: requestedVenueMarketIds.length ? ["orderbooks", requestedVenueMarketIds, null] : ["orderbooks", "__disabled__", null],
4596
5079
  queryFn: ({ signal }) => client.getOrderbooks(
4597
5080
  {
@@ -4604,7 +5087,7 @@ function useOrderBook(options) {
4604
5087
  gcTime: 5 * 6e4,
4605
5088
  refetchOnWindowFocus: false,
4606
5089
  retry: 1,
4607
- placeholderData: import_react_query24.keepPreviousData
5090
+ placeholderData: import_react_query25.keepPreviousData
4608
5091
  });
4609
5092
  const data = (() => {
4610
5093
  var _a, _b;
@@ -4659,7 +5142,7 @@ function useOrderBook(options) {
4659
5142
  }
4660
5143
 
4661
5144
  // src/use-orderbook-quote.ts
4662
- var import_react_query25 = require("@tanstack/react-query");
5145
+ var import_react_query26 = require("@tanstack/react-query");
4663
5146
  var QUOTE_DEBOUNCE_MS = 300;
4664
5147
  var createUnavailableOrderbookError = (message, code, retryable) => {
4665
5148
  const error = new Error(message);
@@ -4721,7 +5204,7 @@ function useOrderbookQuote(options) {
4721
5204
  const { marketId, side, size, enabled = true } = options;
4722
5205
  const debouncedSize = useDebouncedValue(size, QUOTE_DEBOUNCE_MS);
4723
5206
  const shouldFetch = enabled && !!marketId && debouncedSize > 0;
4724
- const query = (0, import_react_query25.useQuery)({
5207
+ const query = (0, import_react_query26.useQuery)({
4725
5208
  queryKey: marketId ? marketDataKeys.orderbookQuote(marketId, side, debouncedSize) : ["market-data", "orderbook-quote", "__disabled__"],
4726
5209
  queryFn: () => __async(null, null, function* () {
4727
5210
  var _a2, _b, _c, _d;
@@ -4752,7 +5235,7 @@ function useOrderbookQuote(options) {
4752
5235
  staleTime: 1e4,
4753
5236
  gcTime: 5 * 6e4,
4754
5237
  retry: 1,
4755
- placeholderData: import_react_query25.keepPreviousData
5238
+ placeholderData: import_react_query26.keepPreviousData
4756
5239
  });
4757
5240
  return {
4758
5241
  data: (_a = query.data) != null ? _a : null,
@@ -4763,12 +5246,12 @@ function useOrderbookQuote(options) {
4763
5246
  }
4764
5247
 
4765
5248
  // src/use-orders.ts
4766
- var import_react_query26 = require("@tanstack/react-query");
5249
+ var import_react_query27 = require("@tanstack/react-query");
4767
5250
  function useOrders(options = {}) {
4768
5251
  var _a, _b, _c, _d;
4769
5252
  const client = useAggClient();
4770
5253
  const { userId, status, limit = 50, offset = 0, enabled = true } = options;
4771
- const query = (0, import_react_query26.useQuery)({
5254
+ const query = (0, import_react_query27.useQuery)({
4772
5255
  queryKey: ["orders", userId != null ? userId : "me", status != null ? status : "all", limit, offset],
4773
5256
  queryFn: () => client.getOrders({
4774
5257
  userId,
@@ -4785,16 +5268,16 @@ function useOrders(options = {}) {
4785
5268
  }
4786
5269
 
4787
5270
  // src/use-search.ts
4788
- var import_react_query27 = require("@tanstack/react-query");
4789
- var import_react23 = require("react");
5271
+ var import_react_query28 = require("@tanstack/react-query");
5272
+ var import_react25 = require("react");
4790
5273
  function useSearch(options) {
4791
5274
  var _a, _b, _c;
4792
- const client = (0, import_react23.useContext)(AggClientContext);
4793
- const queryClient = (0, import_react23.useContext)(import_react_query27.QueryClientContext);
4794
- const [fallbackQueryClient] = (0, import_react23.useState)(() => new import_react_query27.QueryClient());
5275
+ const client = (0, import_react25.useContext)(AggClientContext);
5276
+ const queryClient = (0, import_react25.useContext)(import_react_query28.QueryClientContext);
5277
+ const [fallbackQueryClient] = (0, import_react25.useState)(() => new import_react_query28.QueryClient());
4795
5278
  const { q, type, categoryIds, limit = 20, enabled = true } = options;
4796
5279
  const isEnabled = enabled && q.length > 0;
4797
- (0, import_react23.useEffect)(() => {
5280
+ (0, import_react25.useEffect)(() => {
4798
5281
  if (queryClient) return void 0;
4799
5282
  fallbackQueryClient.mount();
4800
5283
  return () => {
@@ -4804,7 +5287,7 @@ function useSearch(options) {
4804
5287
  if (isEnabled && !client) {
4805
5288
  throw new Error("useSearch must be used within an <AggProvider>");
4806
5289
  }
4807
- const query = (0, import_react_query27.useInfiniteQuery)(
5290
+ const query = (0, import_react_query28.useInfiniteQuery)(
4808
5291
  {
4809
5292
  queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit],
4810
5293
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
@@ -4826,7 +5309,7 @@ function useSearch(options) {
4826
5309
  if (!lastPage.hasMore) return void 0;
4827
5310
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
4828
5311
  },
4829
- placeholderData: import_react_query27.keepPreviousData,
5312
+ placeholderData: import_react_query28.keepPreviousData,
4830
5313
  enabled: isEnabled && !!client
4831
5314
  },
4832
5315
  queryClient != null ? queryClient : fallbackQueryClient
@@ -4845,7 +5328,7 @@ function useSearch(options) {
4845
5328
  }
4846
5329
 
4847
5330
  // src/use-smart-route.ts
4848
- var import_react_query28 = require("@tanstack/react-query");
5331
+ var import_react_query29 = require("@tanstack/react-query");
4849
5332
  function useSmartRoute(options) {
4850
5333
  var _a, _b;
4851
5334
  const client = useAggClient();
@@ -4863,7 +5346,7 @@ function useSmartRoute(options) {
4863
5346
  enabled = true
4864
5347
  } = options;
4865
5348
  const resolvedVenueMarketOutcomeId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : venueMarketId) != null ? _a : outcomeId;
4866
- const query = (0, import_react_query28.useQuery)({
5349
+ const query = (0, import_react_query29.useQuery)({
4867
5350
  queryKey: [
4868
5351
  "smart-route",
4869
5352
  resolvedVenueMarketOutcomeId,
@@ -4895,7 +5378,7 @@ function useSmartRoute(options) {
4895
5378
  gcTime: 6e4,
4896
5379
  refetchOnWindowFocus: false,
4897
5380
  retry: 1,
4898
- placeholderData: import_react_query28.keepPreviousData
5381
+ placeholderData: import_react_query29.keepPreviousData
4899
5382
  });
4900
5383
  const error = query.error;
4901
5384
  return {
@@ -4908,12 +5391,12 @@ function useSmartRoute(options) {
4908
5391
  }
4909
5392
 
4910
5393
  // src/use-user-holdings.ts
4911
- var import_react_query29 = require("@tanstack/react-query");
5394
+ var import_react_query30 = require("@tanstack/react-query");
4912
5395
  function useUserHoldings(options) {
4913
5396
  var _a, _b;
4914
5397
  const client = useAggClient();
4915
5398
  const { venue, venueMarketId, venueEventId, enabled = true } = options;
4916
- const query = (0, import_react_query29.useInfiniteQuery)({
5399
+ const query = (0, import_react_query30.useInfiniteQuery)({
4917
5400
  queryKey: ["user-holdings", venue, venueMarketId, venueEventId],
4918
5401
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
4919
5402
  return client.getUserHoldings({
@@ -4939,15 +5422,15 @@ function useUserHoldings(options) {
4939
5422
  }
4940
5423
 
4941
5424
  // src/use-enriched-venue-event.ts
4942
- var import_react25 = require("react");
5425
+ var import_react27 = require("react");
4943
5426
 
4944
5427
  // src/use-venue-event.ts
4945
- var import_react_query30 = require("@tanstack/react-query");
5428
+ var import_react_query31 = require("@tanstack/react-query");
4946
5429
  function useVenueEvent(options) {
4947
5430
  var _a;
4948
5431
  const client = useAggClient();
4949
5432
  const { eventId, enabled = true } = options;
4950
- const query = (0, import_react_query30.useQuery)({
5433
+ const query = (0, import_react_query31.useQuery)({
4951
5434
  queryKey: ["venue-event", eventId],
4952
5435
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
4953
5436
  return client.getVenueEventById(eventId, { signal });
@@ -4966,13 +5449,13 @@ function useVenueEvent(options) {
4966
5449
  }
4967
5450
 
4968
5451
  // src/use-venue-markets.ts
4969
- var import_react_query31 = require("@tanstack/react-query");
4970
- var import_react24 = require("react");
5452
+ var import_react_query32 = require("@tanstack/react-query");
5453
+ var import_react26 = require("react");
4971
5454
  function useVenueMarkets(options) {
4972
5455
  var _a, _b, _c, _d, _e;
4973
- const client = (0, import_react24.useContext)(AggClientContext);
4974
- const queryClient = (0, import_react24.useContext)(import_react_query31.QueryClientContext);
4975
- const [fallbackQueryClient] = (0, import_react24.useState)(() => new import_react_query31.QueryClient());
5456
+ const client = (0, import_react26.useContext)(AggClientContext);
5457
+ const queryClient = (0, import_react26.useContext)(import_react_query32.QueryClientContext);
5458
+ const [fallbackQueryClient] = (0, import_react26.useState)(() => new import_react_query32.QueryClient());
4976
5459
  const venue = options == null ? void 0 : options.venue;
4977
5460
  const venueEventId = options == null ? void 0 : options.venueEventId;
4978
5461
  const search = options == null ? void 0 : options.search;
@@ -4983,7 +5466,7 @@ function useVenueMarkets(options) {
4983
5466
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
4984
5467
  const sortBy = options == null ? void 0 : options.sortBy;
4985
5468
  const sortDir = options == null ? void 0 : options.sortDir;
4986
- (0, import_react24.useEffect)(() => {
5469
+ (0, import_react26.useEffect)(() => {
4987
5470
  if (queryClient) return void 0;
4988
5471
  fallbackQueryClient.mount();
4989
5472
  return () => {
@@ -4993,7 +5476,7 @@ function useVenueMarkets(options) {
4993
5476
  if (enabled && !client) {
4994
5477
  throw new Error("useVenueMarkets must be used within an <AggProvider>");
4995
5478
  }
4996
- const query = (0, import_react_query31.useInfiniteQuery)(
5479
+ const query = (0, import_react_query32.useInfiniteQuery)(
4997
5480
  {
4998
5481
  queryKey: [
4999
5482
  "venue-markets",
@@ -5063,7 +5546,7 @@ function useEnrichedVenueEvent(options) {
5063
5546
  sortBy: "yesPrice",
5064
5547
  sortDir: "desc"
5065
5548
  });
5066
- const enrichedEvent = (0, import_react25.useMemo)(() => {
5549
+ const enrichedEvent = (0, import_react27.useMemo)(() => {
5067
5550
  if (!event) return void 0;
5068
5551
  if (markets.length === 0) return event;
5069
5552
  return mergeEventWithFullMarkets(event, markets);
@@ -5077,13 +5560,13 @@ function useEnrichedVenueEvent(options) {
5077
5560
  }
5078
5561
 
5079
5562
  // src/use-venue-events.ts
5080
- var import_react_query32 = require("@tanstack/react-query");
5081
- var import_react26 = require("react");
5563
+ var import_react_query33 = require("@tanstack/react-query");
5564
+ var import_react28 = require("react");
5082
5565
  function useVenueEvents(options) {
5083
5566
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
5084
- const client = (0, import_react26.useContext)(AggClientContext);
5085
- const queryClient = (0, import_react26.useContext)(import_react_query32.QueryClientContext);
5086
- const [fallbackQueryClient] = (0, import_react26.useState)(() => new import_react_query32.QueryClient());
5567
+ const client = (0, import_react28.useContext)(AggClientContext);
5568
+ const queryClient = (0, import_react28.useContext)(import_react_query33.QueryClientContext);
5569
+ const [fallbackQueryClient] = (0, import_react28.useState)(() => new import_react_query33.QueryClient());
5087
5570
  const venues = options == null ? void 0 : options.venues;
5088
5571
  const search = options == null ? void 0 : options.search;
5089
5572
  const categoryIds = options == null ? void 0 : options.categoryIds;
@@ -5098,7 +5581,7 @@ function useVenueEvents(options) {
5098
5581
  const maxYesPrice = options == null ? void 0 : options.maxYesPrice;
5099
5582
  const endDateFrom = options == null ? void 0 : options.endDateFrom;
5100
5583
  const initialPages = options == null ? void 0 : options.initialPages;
5101
- (0, import_react26.useEffect)(() => {
5584
+ (0, import_react28.useEffect)(() => {
5102
5585
  if (queryClient) return void 0;
5103
5586
  fallbackQueryClient.mount();
5104
5587
  return () => {
@@ -5108,7 +5591,7 @@ function useVenueEvents(options) {
5108
5591
  if (enabled && !client) {
5109
5592
  throw new Error("useVenueEvents must be used within an <AggProvider>");
5110
5593
  }
5111
- const query = (0, import_react_query32.useInfiniteQuery)(
5594
+ const query = (0, import_react_query33.useInfiniteQuery)(
5112
5595
  {
5113
5596
  queryKey: [
5114
5597
  queryKeyScope,
@@ -5150,13 +5633,14 @@ function useVenueEvents(options) {
5150
5633
  if (!lastPage.hasMore) return void 0;
5151
5634
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
5152
5635
  },
5153
- placeholderData: import_react_query32.keepPreviousData,
5636
+ // TODO: RMIK - Comment out to show skeletons on category switch
5637
+ placeholderData: import_react_query33.keepPreviousData,
5154
5638
  enabled: enabled && !!client
5155
5639
  },
5156
5640
  queryClient != null ? queryClient : fallbackQueryClient
5157
5641
  );
5158
- const prefetchedRef = (0, import_react26.useRef)(false);
5159
- (0, import_react26.useEffect)(() => {
5642
+ const prefetchedRef = (0, import_react28.useRef)(false);
5643
+ (0, import_react28.useEffect)(() => {
5160
5644
  var _a2, _b2;
5161
5645
  if (prefetchedRef.current) return;
5162
5646
  if (!initialPages || initialPages <= 1) return;
@@ -5174,7 +5658,7 @@ function useVenueEvents(options) {
5174
5658
  query.hasNextPage,
5175
5659
  query.fetchNextPage
5176
5660
  ]);
5177
- const events = (0, import_react26.useMemo)(
5661
+ const events = (0, import_react28.useMemo)(
5178
5662
  () => {
5179
5663
  var _a2, _b2;
5180
5664
  return (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.flatMap((page) => page.data)) != null ? _b2 : [];
@@ -5192,7 +5676,7 @@ function useVenueEvents(options) {
5192
5676
  }
5193
5677
 
5194
5678
  // src/use-venue-market-midpoints.ts
5195
- var import_react_query33 = require("@tanstack/react-query");
5679
+ var import_react_query34 = require("@tanstack/react-query");
5196
5680
  var MAX_VENUE_MARKET_IDS_PER_REQUEST = 200;
5197
5681
  var normalizeVenueMarketIds2 = (venueMarketIds) => {
5198
5682
  return [
@@ -5228,7 +5712,7 @@ function useVenueMarketMidpoints(options) {
5228
5712
  const client = useAggClient();
5229
5713
  const enabled = (_a = options.enabled) != null ? _a : true;
5230
5714
  const requestedVenueMarketIds = normalizeVenueMarketIds2(options.venueMarketIds);
5231
- const query = (0, import_react_query33.useQuery)({
5715
+ const query = (0, import_react_query34.useQuery)({
5232
5716
  queryKey: requestedVenueMarketIds.length ? ["venue-market-midpoints", requestedVenueMarketIds] : ["venue-market-midpoints", "__disabled__"],
5233
5717
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
5234
5718
  const venueMarketIdChunks = chunkVenueMarketIds(requestedVenueMarketIds);
@@ -5247,7 +5731,7 @@ function useVenueMarketMidpoints(options) {
5247
5731
  gcTime: 5 * 6e4,
5248
5732
  refetchOnWindowFocus: false,
5249
5733
  retry: 1,
5250
- placeholderData: import_react_query33.keepPreviousData
5734
+ placeholderData: import_react_query34.keepPreviousData
5251
5735
  });
5252
5736
  const midpointRows = (_c = (_b = query.data) == null ? void 0 : _b.data) != null ? _c : [];
5253
5737
  const midpointsByVenueMarketId = mapMidpointsByVenueMarketId(midpointRows);
@@ -5282,7 +5766,7 @@ function computePriceGaps(input) {
5282
5766
  }
5283
5767
 
5284
5768
  // src/use-viewport-midpoints.ts
5285
- var import_react27 = require("react");
5769
+ var import_react29 = require("react");
5286
5770
  var resolveUncachedVisibleMarketIds = (visibleMarkets, cache, inFlightIds) => {
5287
5771
  const idsToFetch = [];
5288
5772
  for (const market of visibleMarkets) {
@@ -5293,19 +5777,21 @@ var resolveUncachedVisibleMarketIds = (visibleMarkets, cache, inFlightIds) => {
5293
5777
  return idsToFetch;
5294
5778
  };
5295
5779
  var buildCachedMidpointEntries = (requestedVenueMarketIds, rows) => {
5296
- var _a, _b;
5780
+ var _a, _b, _c;
5297
5781
  const rowsByVenueMarketId = new Map(rows.map((item) => [item.venueMarketId, item]));
5298
5782
  const nextCacheEntries = /* @__PURE__ */ new Map();
5299
5783
  for (const venueMarketId of requestedVenueMarketIds) {
5300
5784
  const item = rowsByVenueMarketId.get(venueMarketId);
5301
5785
  nextCacheEntries.set(venueMarketId, {
5302
5786
  midpoint: (_a = item == null ? void 0 : item.midpoint) != null ? _a : null,
5303
- matched: ((_b = item == null ? void 0 : item.matched) != null ? _b : []).map((matched) => {
5304
- var _a2;
5305
- return {
5787
+ spread: (_b = item == null ? void 0 : item.spread) != null ? _b : null,
5788
+ matched: ((_c = item == null ? void 0 : item.matched) != null ? _c : []).map((matched) => {
5789
+ var _a2, _b2;
5790
+ return __spreadValues({
5306
5791
  venueMarketId: matched.venueMarketId,
5307
- midpoint: (_a2 = matched.midpoint) != null ? _a2 : null
5308
- };
5792
+ midpoint: (_a2 = matched.midpoint) != null ? _a2 : null,
5793
+ spread: (_b2 = matched.spread) != null ? _b2 : null
5794
+ }, matched.venue ? { venue: matched.venue } : {});
5309
5795
  })
5310
5796
  });
5311
5797
  }
@@ -5313,15 +5799,15 @@ var buildCachedMidpointEntries = (requestedVenueMarketIds, rows) => {
5313
5799
  };
5314
5800
  function useViewportMidpoints(visibleMarkets) {
5315
5801
  const client = useAggClient();
5316
- const [cache, setCache] = (0, import_react27.useState)(() => /* @__PURE__ */ new Map());
5317
- const inFlightRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
5318
- const visibleRef = (0, import_react27.useRef)(visibleMarkets);
5802
+ const [cache, setCache] = (0, import_react29.useState)(() => /* @__PURE__ */ new Map());
5803
+ const inFlightRef = (0, import_react29.useRef)(/* @__PURE__ */ new Set());
5804
+ const visibleRef = (0, import_react29.useRef)(visibleMarkets);
5319
5805
  visibleRef.current = visibleMarkets;
5320
- const visibleFp = (0, import_react27.useMemo)(
5806
+ const visibleFp = (0, import_react29.useMemo)(
5321
5807
  () => [...new Set(visibleMarkets.map((m) => m.id))].sort().join("|"),
5322
5808
  [visibleMarkets]
5323
5809
  );
5324
- (0, import_react27.useEffect)(() => {
5810
+ (0, import_react29.useEffect)(() => {
5325
5811
  const toFetch = resolveUncachedVisibleMarketIds(visibleRef.current, cache, inFlightRef.current);
5326
5812
  if (!toFetch.length) return;
5327
5813
  let cancelled = false;
@@ -5345,37 +5831,44 @@ function useViewportMidpoints(visibleMarkets) {
5345
5831
  cancelled = true;
5346
5832
  };
5347
5833
  }, [visibleFp, cache]);
5348
- const prices = (0, import_react27.useMemo)(() => {
5349
- var _a;
5834
+ const { prices, venueByOutcomeId } = (0, import_react29.useMemo)(() => {
5835
+ var _a, _b;
5350
5836
  const map = /* @__PURE__ */ new Map();
5837
+ const venueMap = /* @__PURE__ */ new Map();
5351
5838
  for (const market of visibleMarkets) {
5352
5839
  const entry = cache.get(market.id);
5353
5840
  if (!entry) continue;
5354
- const candidates = [];
5355
- if (entry.midpoint != null) candidates.push(entry.midpoint);
5356
- for (const m of entry.matched) if (m.midpoint != null) candidates.push(m.midpoint);
5357
- if (!candidates.length) continue;
5358
- const mid = Math.max(...candidates);
5841
+ let mid = entry.midpoint;
5842
+ let midVenue = market.venue;
5843
+ for (const m of entry.matched) {
5844
+ if (m.midpoint == null) continue;
5845
+ if (mid == null || m.midpoint < mid) {
5846
+ mid = m.midpoint;
5847
+ midVenue = (_a = m.venue) != null ? _a : market.venue;
5848
+ }
5849
+ }
5850
+ if (mid == null) continue;
5359
5851
  for (const outcome of market.venueMarketOutcomes) {
5360
- const isYes = ((_a = outcome.label) == null ? void 0 : _a.toLowerCase()) === "yes";
5852
+ const isYes = ((_b = outcome.label) == null ? void 0 : _b.toLowerCase()) === "yes";
5361
5853
  map.set(outcome.id, isYes ? mid : 1 - mid);
5854
+ venueMap.set(outcome.id, midVenue);
5362
5855
  }
5363
5856
  }
5364
- return map;
5857
+ return { prices: map, venueByOutcomeId: venueMap };
5365
5858
  }, [cache, visibleMarkets]);
5366
- return { prices };
5859
+ return { prices, venueByOutcomeId };
5367
5860
  }
5368
5861
 
5369
5862
  // src/use-visible-ids.ts
5370
- var import_react28 = require("react");
5863
+ var import_react30 = require("react");
5371
5864
  function useVisibleIds(options = {}) {
5372
5865
  const { rootMargin = "0px", threshold = 0 } = options;
5373
- const [visibleIds, setVisibleIds] = (0, import_react28.useState)(() => /* @__PURE__ */ new Set());
5374
- const observerRef = (0, import_react28.useRef)(null);
5375
- const elementsRef = (0, import_react28.useRef)(/* @__PURE__ */ new Map());
5376
- const elementIdRef = (0, import_react28.useRef)(/* @__PURE__ */ new WeakMap());
5377
- const callbackRefsRef = (0, import_react28.useRef)(/* @__PURE__ */ new Map());
5378
- (0, import_react28.useEffect)(() => {
5866
+ const [visibleIds, setVisibleIds] = (0, import_react30.useState)(() => /* @__PURE__ */ new Set());
5867
+ const observerRef = (0, import_react30.useRef)(null);
5868
+ const elementsRef = (0, import_react30.useRef)(/* @__PURE__ */ new Map());
5869
+ const elementIdRef = (0, import_react30.useRef)(/* @__PURE__ */ new WeakMap());
5870
+ const callbackRefsRef = (0, import_react30.useRef)(/* @__PURE__ */ new Map());
5871
+ (0, import_react30.useEffect)(() => {
5379
5872
  if (typeof IntersectionObserver === "undefined") return;
5380
5873
  const observer = new IntersectionObserver(
5381
5874
  (entries) => {
@@ -5407,7 +5900,7 @@ function useVisibleIds(options = {}) {
5407
5900
  observerRef.current = null;
5408
5901
  };
5409
5902
  }, [rootMargin, threshold]);
5410
- const register = (0, import_react28.useCallback)((id) => {
5903
+ const register = (0, import_react30.useCallback)((id) => {
5411
5904
  const existing = callbackRefsRef.current.get(id);
5412
5905
  if (existing) return existing;
5413
5906
  const callback = (el) => {
@@ -5440,12 +5933,12 @@ function useVisibleIds(options = {}) {
5440
5933
  }
5441
5934
 
5442
5935
  // src/use-app-config.ts
5443
- var import_react_query34 = require("@tanstack/react-query");
5936
+ var import_react_query35 = require("@tanstack/react-query");
5444
5937
  var FIVE_MINUTES = 5 * 60 * 1e3;
5445
5938
  function useAppConfig() {
5446
5939
  var _a, _b, _c, _d, _e, _f;
5447
5940
  const client = useAggClient();
5448
- const query = (0, import_react_query34.useQuery)({
5941
+ const query = (0, import_react_query35.useQuery)({
5449
5942
  queryKey: ["agg", "app-config"],
5450
5943
  queryFn: () => client.getAppConfig(),
5451
5944
  staleTime: FIVE_MINUTES
@@ -5541,6 +6034,7 @@ function useAppConfig() {
5541
6034
  useOnBalanceUpdate,
5542
6035
  useOnOrderSubmitted,
5543
6036
  useOnRedeemEvent,
6037
+ useOnWithdrawalLifecycle,
5544
6038
  useOrderBook,
5545
6039
  useOrderbookQuote,
5546
6040
  useOrders,
@@ -5564,5 +6058,7 @@ function useAppConfig() {
5564
6058
  useVenueMarkets,
5565
6059
  useViewportMidpoints,
5566
6060
  useVisibleIds,
5567
- useWithdrawManaged
6061
+ useWithdrawFlow,
6062
+ useWithdrawManaged,
6063
+ useWithdrawalLifecycle
5568
6064
  });