@agg-build/hooks 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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: {
@@ -698,6 +756,7 @@ var enUsLabels = {
698
756
  },
699
757
  eventList: {
700
758
  matchedTab: "Matched",
759
+ allTab: "All",
701
760
  loading: (title) => `Loading ${title}`,
702
761
  tabsAria: (title) => `${title} tabs`,
703
762
  emptyAria: "No events found",
@@ -826,6 +885,8 @@ var enUsLabels = {
826
885
  settlementDescriptionLabel: "Description",
827
886
  settlementRulesPrimaryLabel: "Resolution rules",
828
887
  settlementRulesSecondaryLabel: "Additional rules",
888
+ settlementPrimaryRulesLabel: "Resolution rules",
889
+ settlementEmpty: "No settlement details available.",
829
890
  disclaimer: "By trading, you agree to the Terms of Use of each exchange.",
830
891
  geoBlockTermsLink: "Terms of Use",
831
892
  geoBlockGenericMessage: "Trading is not available in your region. See ",
@@ -844,6 +905,7 @@ var enUsLabels = {
844
905
  minimumFractionDigits: Number.isInteger(value) ? 0 : 2,
845
906
  maximumFractionDigits: 6
846
907
  })} shares`,
908
+ maxShares: "Max",
847
909
  slippage: (value) => `Slippage: ${value}%`,
848
910
  editSlippage: (value) => `Edit ${value}`,
849
911
  collapseSlippage: (value) => `Collapse ${value}`,
@@ -890,7 +952,8 @@ var enUsLabels = {
890
952
  insufficientPositionGeneric: "You don't have enough shares to sell.",
891
953
  insufficientSellDepth: "Not enough bid liquidity on the matched venues for this sell amount.",
892
954
  noBidsAboveMinPrice: "No venue bids above the minimum price.",
893
- signInRequired: "Sign in to get a routed quote",
955
+ signInToTrade: "Sign in to trade",
956
+ deposit: "Deposit",
894
957
  kycRequired: "Verify to trade Kalshi",
895
958
  kycNotVerifiedTooltip: "You have not been verified yet",
896
959
  kycVerifyModalTitle: "Verify Your Identity",
@@ -905,7 +968,6 @@ var enUsLabels = {
905
968
  orderSplitting: "Order Splitting",
906
969
  splitOrderDescription: "We split your order for the best price:",
907
970
  viewAllRoutes: (count) => `View all (${count})`,
908
- hideRoutes: "Hide routes",
909
971
  venueUnavailableInRegion: "Unavailable in your region",
910
972
  toWin: (tab) => tab === "buy" ? "To win" : "Payout",
911
973
  buyingOutcome: (label) => `Buying ${label}`,
@@ -2190,6 +2252,20 @@ function useOnRedeemEvent(callback) {
2190
2252
  return listeners.addRedeemEventListener(handler);
2191
2253
  }, [listeners, hasCallback]);
2192
2254
  }
2255
+ function useOnWithdrawalLifecycle(callback) {
2256
+ const listeners = (0, import_react6.useContext)(AggWsUserEventContext);
2257
+ const callbackRef = (0, import_react6.useRef)(callback);
2258
+ callbackRef.current = callback;
2259
+ const hasCallback = callback !== null;
2260
+ (0, import_react6.useEffect)(() => {
2261
+ if (!listeners || !callbackRef.current) return;
2262
+ const handler = (msg) => {
2263
+ var _a;
2264
+ (_a = callbackRef.current) == null ? void 0 : _a.call(callbackRef, msg);
2265
+ };
2266
+ return listeners.addWithdrawalLifecycleListener(handler);
2267
+ }, [listeners, hasCallback]);
2268
+ }
2193
2269
  function AggWebSocketProvider({ children }) {
2194
2270
  const client = useAggClient();
2195
2271
  const { enableWebsocketsLogs } = useAggUiConfig();
@@ -2210,6 +2286,9 @@ function AggWebSocketProvider({ children }) {
2210
2286
  const balanceUpdateListenersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
2211
2287
  const orderEventListenersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
2212
2288
  const redeemEventListenersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
2289
+ const withdrawalLifecycleListenersRef = (0, import_react6.useRef)(
2290
+ /* @__PURE__ */ new Set()
2291
+ );
2213
2292
  const userEventListeners = (0, import_react6.useMemo)(
2214
2293
  () => ({
2215
2294
  addOrderSubmittedListener: (cb) => {
@@ -2235,6 +2314,12 @@ function AggWebSocketProvider({ children }) {
2235
2314
  return () => {
2236
2315
  redeemEventListenersRef.current.delete(cb);
2237
2316
  };
2317
+ },
2318
+ addWithdrawalLifecycleListener: (cb) => {
2319
+ withdrawalLifecycleListenersRef.current.add(cb);
2320
+ return () => {
2321
+ withdrawalLifecycleListenersRef.current.delete(cb);
2322
+ };
2238
2323
  }
2239
2324
  }),
2240
2325
  []
@@ -2409,6 +2494,14 @@ function AggWebSocketProvider({ children }) {
2409
2494
  listener(msg);
2410
2495
  }
2411
2496
  },
2497
+ onWithdrawalLifecycle: (msg) => {
2498
+ if (isClientAuthenticated) {
2499
+ invalidateBalanceCaches();
2500
+ }
2501
+ for (const listener of withdrawalLifecycleListenersRef.current) {
2502
+ listener(msg);
2503
+ }
2504
+ },
2412
2505
  onError: (msg) => {
2413
2506
  const outcomeId = resolveSnapshotUnavailableOutcomeId(msg.message);
2414
2507
  if (!outcomeId) return;
@@ -3135,6 +3228,9 @@ function useRampSession() {
3135
3228
  });
3136
3229
  }
3137
3230
 
3231
+ // src/withdraw/use-withdraw-flow.ts
3232
+ var import_react11 = require("react");
3233
+
3138
3234
  // src/execution/use-quote-managed.ts
3139
3235
  var import_react_query6 = require("@tanstack/react-query");
3140
3236
  function useQuoteManaged(options) {
@@ -3645,11 +3741,381 @@ var useRedeemEligibleCount = () => {
3645
3741
  return (_a = query.data) != null ? _a : 0;
3646
3742
  };
3647
3743
 
3744
+ // src/withdraw/use-withdraw-flow.ts
3745
+ var EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
3746
+ var SOLANA_ADDRESS_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
3747
+ var SOLANA_CHAIN_ID = 792703809;
3748
+ var WITHDRAWAL_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
3749
+ 1,
3750
+ // Ethereum
3751
+ 137,
3752
+ // Polygon
3753
+ 42161,
3754
+ // Arbitrum
3755
+ 8453,
3756
+ // Base
3757
+ 56,
3758
+ // BNB
3759
+ SOLANA_CHAIN_ID
3760
+ ]);
3761
+ var isValidDestinationAddress = (address, chainId) => {
3762
+ if (chainId === SOLANA_CHAIN_ID) return SOLANA_ADDRESS_REGEX.test(address);
3763
+ return EVM_ADDRESS_REGEX.test(address);
3764
+ };
3765
+ var DEFAULT_WITHDRAW_SUMMARY = {
3766
+ amountReceived: "",
3767
+ network: "",
3768
+ toWallet: "",
3769
+ fees: "\u2014"
3770
+ };
3771
+ var formatRawTokenAmount = (rawAmount, decimals) => {
3772
+ if (!rawAmount) return "0";
3773
+ const raw = BigInt(rawAmount);
3774
+ const divisor = BigInt(`1${"0".repeat(decimals)}`);
3775
+ const whole = raw / divisor;
3776
+ const remainder = raw % divisor;
3777
+ if (remainder === BigInt(0)) return whole.toString();
3778
+ return `${whole.toString()}.${remainder.toString().padStart(decimals, "0").replace(/0+$/, "")}`;
3779
+ };
3780
+ var formatRawTokenAmountForDisplay = (rawAmount, decimals, fractionDigits = 2) => {
3781
+ const [wholePart, fractionalPart = ""] = formatRawTokenAmount(rawAmount, decimals).split(".");
3782
+ const normalizedFraction = fractionalPart.padEnd(fractionDigits, "0").slice(0, fractionDigits);
3783
+ return `${wholePart}.${normalizedFraction}`;
3784
+ };
3785
+ var parseTokenAmountToRaw = (amount, decimals) => {
3786
+ const normalizedAmount = amount.trim();
3787
+ if (!normalizedAmount || !/^\d*(?:\.\d*)?$/.test(normalizedAmount)) {
3788
+ return null;
3789
+ }
3790
+ const [wholePart = "0", fractionalPart = ""] = normalizedAmount.split(".");
3791
+ if (fractionalPart.length > decimals) return null;
3792
+ const normalizedWhole = wholePart === "" ? "0" : wholePart;
3793
+ const normalizedFraction = fractionalPart.padEnd(decimals, "0");
3794
+ try {
3795
+ return `${BigInt(normalizedWhole)}${normalizedFraction}`.replace(/^0+(?=\d)/, "");
3796
+ } catch (e) {
3797
+ return null;
3798
+ }
3799
+ };
3800
+ var shortenAddress = (address) => address.length > 12 ? `${address.slice(0, 6)}...${address.slice(-4)}` : address;
3801
+ function useWithdrawFlow(options) {
3802
+ var _a, _b;
3803
+ const { open, onOpenChange } = options;
3804
+ const { totalBalance } = useAggBalanceState();
3805
+ const { balances } = useManagedBalances({ enabled: open });
3806
+ const { supportedChains } = useDepositAddresses({ enabled: open });
3807
+ const withdrawMutation = useWithdrawManaged();
3808
+ const syncBalances = useSyncBalances();
3809
+ const ws = useAggWebSocket();
3810
+ (0, import_react11.useEffect)(() => {
3811
+ if (!open) return;
3812
+ syncBalances.mutate(void 0, {
3813
+ onError: () => {
3814
+ }
3815
+ });
3816
+ }, [open]);
3817
+ const [withdrawDestination, setWithdrawDestination] = (0, import_react11.useState)("");
3818
+ const [withdrawAmount, setWithdrawAmount] = (0, import_react11.useState)("");
3819
+ const [withdrawToken, setWithdrawToken] = (0, import_react11.useState)("USDC");
3820
+ const [withdrawNetwork, setWithdrawNetwork] = (0, import_react11.useState)("");
3821
+ const [withdrawSummary, setWithdrawSummary] = (0, import_react11.useState)(DEFAULT_WITHDRAW_SUMMARY);
3822
+ const [withdrawalId, setWithdrawalId] = (0, import_react11.useState)(null);
3823
+ const networkOptions = (0, import_react11.useMemo)(
3824
+ () => (supportedChains != null ? supportedChains : []).filter((chain) => WITHDRAWAL_SUPPORTED_CHAIN_IDS.has(chain.chainId)).map((chain) => ({
3825
+ value: String(chain.chainId),
3826
+ label: chain.name
3827
+ })),
3828
+ [supportedChains]
3829
+ );
3830
+ const resolvedWithdrawNetwork = withdrawNetwork || ((_a = networkOptions[0]) == null ? void 0 : _a.value) || "";
3831
+ (0, import_react11.useEffect)(() => {
3832
+ if (!networkOptions.length) return;
3833
+ if (!withdrawNetwork || !networkOptions.some((option) => option.value === withdrawNetwork)) {
3834
+ setWithdrawNetwork(networkOptions[0].value);
3835
+ }
3836
+ }, [networkOptions, withdrawNetwork]);
3837
+ const tokenOptions = (0, import_react11.useMemo)(() => {
3838
+ var _a2, _b2, _c;
3839
+ const selectedChainId = Number(resolvedWithdrawNetwork);
3840
+ const supportedTokensForNetwork = (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === selectedChainId)) == null ? void 0 : _a2.tokens) != null ? _b2 : [];
3841
+ const withdrawableSymbols = new Set(supportedTokensForNetwork.map((token) => token.symbol));
3842
+ return ((_c = balances == null ? void 0 : balances.cash) != null ? _c : []).filter((cashEntry) => withdrawableSymbols.has(cashEntry.tokenSymbol)).map((cashEntry) => ({
3843
+ value: cashEntry.tokenSymbol,
3844
+ label: cashEntry.tokenSymbol
3845
+ }));
3846
+ }, [balances, resolvedWithdrawNetwork, supportedChains]);
3847
+ const resolvedWithdrawToken = tokenOptions.some((option) => option.value === withdrawToken) ? withdrawToken : ((_b = tokenOptions[0]) == null ? void 0 : _b.value) || "";
3848
+ (0, import_react11.useEffect)(() => {
3849
+ if (!tokenOptions.length) return;
3850
+ if (!tokenOptions.some((option) => option.value === withdrawToken)) {
3851
+ setWithdrawToken(tokenOptions[0].value);
3852
+ }
3853
+ }, [tokenOptions, withdrawToken]);
3854
+ const selectedCashEntry = (0, import_react11.useMemo)(
3855
+ () => balances == null ? void 0 : balances.cash.find((cashEntry) => cashEntry.tokenSymbol === resolvedWithdrawToken),
3856
+ [balances, resolvedWithdrawToken]
3857
+ );
3858
+ const selectedTokenDecimals = (0, import_react11.useMemo)(() => {
3859
+ var _a2, _b2, _c, _d;
3860
+ const selectedChainId = Number(resolvedWithdrawNetwork);
3861
+ 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;
3862
+ }, [
3863
+ resolvedWithdrawNetwork,
3864
+ resolvedWithdrawToken,
3865
+ selectedCashEntry == null ? void 0 : selectedCashEntry.decimals,
3866
+ supportedChains
3867
+ ]);
3868
+ const exactBalance = (0, import_react11.useMemo)(() => {
3869
+ if (!selectedCashEntry) return "0";
3870
+ return formatRawTokenAmount(selectedCashEntry.totalRaw, selectedCashEntry.decimals);
3871
+ }, [selectedCashEntry]);
3872
+ const balanceDisplay = (0, import_react11.useMemo)(() => {
3873
+ if (!selectedCashEntry) return `0.00 ${resolvedWithdrawToken || withdrawToken}`;
3874
+ return `${formatRawTokenAmountForDisplay(
3875
+ selectedCashEntry.totalRaw,
3876
+ selectedCashEntry.decimals
3877
+ )} ${resolvedWithdrawToken}`;
3878
+ }, [resolvedWithdrawToken, selectedCashEntry, withdrawToken]);
3879
+ const resetFlowState = (0, import_react11.useCallback)(() => {
3880
+ setWithdrawDestination("");
3881
+ setWithdrawAmount("");
3882
+ setWithdrawToken("USDC");
3883
+ setWithdrawNetwork("");
3884
+ setWithdrawSummary(DEFAULT_WITHDRAW_SUMMARY);
3885
+ setWithdrawalId(null);
3886
+ }, []);
3887
+ const handleWithdrawOpenChange = (0, import_react11.useCallback)(
3888
+ (isOpen) => {
3889
+ if (!isOpen) resetFlowState();
3890
+ onOpenChange(isOpen);
3891
+ },
3892
+ [onOpenChange, resetFlowState]
3893
+ );
3894
+ (0, import_react11.useEffect)(() => {
3895
+ if (!open) resetFlowState();
3896
+ }, [open, resetFlowState]);
3897
+ const handleWithdrawProvider = (0, import_react11.useCallback)(() => __async(null, null, function* () {
3898
+ var _a2, _b2;
3899
+ const destinationChainId = Number(resolvedWithdrawNetwork);
3900
+ const trimmedDestination = withdrawDestination.trim();
3901
+ const amountRaw = parseTokenAmountToRaw(withdrawAmount, selectedTokenDecimals);
3902
+ if (!amountRaw || BigInt(amountRaw) <= BigInt(0)) {
3903
+ throw new Error("Enter a withdrawal amount greater than zero.");
3904
+ }
3905
+ if (!Number.isFinite(destinationChainId) || destinationChainId <= 0) {
3906
+ throw new Error("Select a destination network.");
3907
+ }
3908
+ if (!isValidDestinationAddress(trimmedDestination, destinationChainId)) {
3909
+ const expected = destinationChainId === SOLANA_CHAIN_ID ? "a Solana wallet address (base58, 32\u201344 chars)" : "an EVM destination address (0x\u2026 40 hex chars)";
3910
+ throw new Error(`Enter ${expected}.`);
3911
+ }
3912
+ if (selectedCashEntry) {
3913
+ const scaleBy = (n, exp) => {
3914
+ if (exp <= 0) return n;
3915
+ return n * BigInt(`1${"0".repeat(exp)}`);
3916
+ };
3917
+ const balanceInDestFrame = (() => {
3918
+ const native = BigInt(selectedCashEntry.totalRaw);
3919
+ if (selectedCashEntry.decimals === selectedTokenDecimals) return native;
3920
+ if (selectedCashEntry.decimals > selectedTokenDecimals) {
3921
+ return native / scaleBy(BigInt(1), selectedCashEntry.decimals - selectedTokenDecimals);
3922
+ }
3923
+ return scaleBy(native, selectedTokenDecimals - selectedCashEntry.decimals);
3924
+ })();
3925
+ if (BigInt(amountRaw) > balanceInDestFrame) {
3926
+ throw new Error("Withdrawal amount exceeds your available balance.");
3927
+ }
3928
+ }
3929
+ ws == null ? void 0 : ws.connect();
3930
+ yield new Promise((resolve, reject) => {
3931
+ withdrawMutation.mutate(
3932
+ {
3933
+ amountRaw,
3934
+ tokenSymbol: resolvedWithdrawToken,
3935
+ destinationAddress: trimmedDestination,
3936
+ destinationChainId
3937
+ },
3938
+ {
3939
+ onSuccess: (data) => {
3940
+ setWithdrawalId(data.withdrawalId);
3941
+ resolve();
3942
+ },
3943
+ onError: reject
3944
+ }
3945
+ );
3946
+ });
3947
+ setWithdrawSummary({
3948
+ amountReceived: `${formatRawTokenAmountForDisplay(amountRaw, selectedTokenDecimals)} ${resolvedWithdrawToken}`,
3949
+ network: (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === destinationChainId)) == null ? void 0 : _a2.name) != null ? _b2 : resolvedWithdrawNetwork,
3950
+ toWallet: shortenAddress(trimmedDestination),
3951
+ fees: "\u2014"
3952
+ });
3953
+ }), [
3954
+ resolvedWithdrawNetwork,
3955
+ resolvedWithdrawToken,
3956
+ selectedCashEntry,
3957
+ selectedTokenDecimals,
3958
+ supportedChains,
3959
+ withdrawAmount,
3960
+ withdrawDestination,
3961
+ withdrawMutation,
3962
+ ws
3963
+ ]);
3964
+ return {
3965
+ open,
3966
+ onOpenChange: handleWithdrawOpenChange,
3967
+ withdrawFlow: {
3968
+ balance: totalBalance,
3969
+ balanceDisplay,
3970
+ amount: withdrawAmount,
3971
+ destinationWallet: withdrawDestination,
3972
+ tokenOptions,
3973
+ networkOptions,
3974
+ selectedToken: resolvedWithdrawToken,
3975
+ selectedNetwork: resolvedWithdrawNetwork,
3976
+ purchaseSummary: withdrawSummary,
3977
+ withdrawalId
3978
+ },
3979
+ onWithdrawDestinationChange: setWithdrawDestination,
3980
+ onWithdrawAmountChange: setWithdrawAmount,
3981
+ onWithdrawTokenChange: setWithdrawToken,
3982
+ onWithdrawNetworkChange: setWithdrawNetwork,
3983
+ onMaxClick: (0, import_react11.useCallback)(() => {
3984
+ setWithdrawAmount(exactBalance === "0" ? "0" : exactBalance);
3985
+ }, [exactBalance]),
3986
+ onSelectWithdrawProvider: (0, import_react11.useCallback)(
3987
+ (_providerId) => __async(null, null, function* () {
3988
+ return handleWithdrawProvider();
3989
+ }),
3990
+ [handleWithdrawProvider]
3991
+ ),
3992
+ onDoneWithdraw: (0, import_react11.useCallback)(() => handleWithdrawOpenChange(false), [handleWithdrawOpenChange])
3993
+ };
3994
+ }
3995
+
3996
+ // src/withdraw/use-withdrawal-lifecycle.ts
3997
+ var import_react12 = require("react");
3998
+ var import_react_query15 = require("@tanstack/react-query");
3999
+ var INITIAL_STATE = {
4000
+ pending: true,
4001
+ status: null,
4002
+ terminal: false,
4003
+ lastLeg: null,
4004
+ legs: [],
4005
+ errorMessage: null,
4006
+ timestamp: null
4007
+ };
4008
+ var restLegToWsLeg = (leg) => ({
4009
+ sourceChainId: leg.sourceChainId,
4010
+ destChainId: leg.destChainId,
4011
+ type: leg.type,
4012
+ // The wire-level WS leg status enum and the REST leg status enum are the
4013
+ // same union (planned/submitted/confirmed/failed). Keep the cast narrow to
4014
+ // avoid pulling the SDK enum apart for a one-line bridge.
4015
+ status: leg.status,
4016
+ amountRaw: leg.amountRaw,
4017
+ txHash: leg.txHash,
4018
+ bridgeOperationId: leg.bridgeOperationId
4019
+ });
4020
+ var mergeLegs = (prev, snapshot, delta) => {
4021
+ if (snapshot) return snapshot;
4022
+ if (!delta) return prev;
4023
+ const idx = prev.findIndex(
4024
+ (l) => l.sourceChainId === delta.sourceChainId && l.destChainId === delta.destChainId && l.type === delta.type
4025
+ );
4026
+ if (idx === -1) return [...prev, delta];
4027
+ const next = prev.slice();
4028
+ next[idx] = delta;
4029
+ return next;
4030
+ };
4031
+ var restToLifecycleState = (response) => {
4032
+ var _a;
4033
+ return {
4034
+ pending: false,
4035
+ status: response.status,
4036
+ terminal: response.status === "completed" || response.status === "partial" || response.status === "failed",
4037
+ lastLeg: null,
4038
+ legs: response.legs.map(restLegToWsLeg),
4039
+ errorMessage: (_a = response.errorMessage) != null ? _a : null,
4040
+ // No server timestamp on the REST response — we use 0 as "older than any
4041
+ // WS timestamp" so a subsequent WS event always wins. Callers that read
4042
+ // `timestamp` should treat 0/null interchangeably as "unset".
4043
+ timestamp: 0
4044
+ };
4045
+ };
4046
+ function useWithdrawalLifecycle(withdrawalId) {
4047
+ const client = useAggClient();
4048
+ const wsConnected = useAggWebSocketConnectionState();
4049
+ const queryClient = (0, import_react_query15.useQueryClient)();
4050
+ const [state, setState] = (0, import_react12.useState)(INITIAL_STATE);
4051
+ const stateRef = (0, import_react12.useRef)(state);
4052
+ stateRef.current = state;
4053
+ const balanceRefetchedForRef = (0, import_react12.useRef)(null);
4054
+ (0, import_react12.useEffect)(() => {
4055
+ setState(INITIAL_STATE);
4056
+ }, [withdrawalId]);
4057
+ (0, import_react12.useEffect)(() => {
4058
+ if (!withdrawalId) return;
4059
+ let cancelled = false;
4060
+ (() => __async(null, null, function* () {
4061
+ try {
4062
+ const response = yield client.getWithdrawalStatus(withdrawalId);
4063
+ if (cancelled) return;
4064
+ if (response.withdrawalId !== withdrawalId) return;
4065
+ const current = stateRef.current;
4066
+ const wsAlreadyWon = current.timestamp != null && current.timestamp > 0;
4067
+ if (wsAlreadyWon) return;
4068
+ setState(restToLifecycleState(response));
4069
+ } catch (e) {
4070
+ }
4071
+ }))();
4072
+ return () => {
4073
+ cancelled = true;
4074
+ };
4075
+ }, [client, withdrawalId, wsConnected]);
4076
+ const handler = (0, import_react12.useMemo)(() => {
4077
+ if (!withdrawalId) return null;
4078
+ return (msg) => {
4079
+ if (msg.withdrawalId !== withdrawalId) return;
4080
+ setState((prev) => {
4081
+ var _a, _b;
4082
+ return {
4083
+ pending: false,
4084
+ status: msg.status,
4085
+ terminal: msg.terminal,
4086
+ lastLeg: (_a = msg.leg) != null ? _a : null,
4087
+ // `legs[]` is the cumulative server-known truth. Snapshots
4088
+ // (`pending` / terminal rollup) carry a full `legs[]` and replace
4089
+ // it. Intermediate per-leg deltas carry only `leg` (no `legs[]`)
4090
+ // — merge the delta into the existing array by
4091
+ // (sourceChainId, destChainId, type) so the timeline UI doesn't
4092
+ // collapse to empty between snapshots.
4093
+ legs: mergeLegs(prev.legs, msg.legs, msg.leg),
4094
+ errorMessage: (_b = msg.errorMessage) != null ? _b : null,
4095
+ timestamp: msg.timestamp
4096
+ };
4097
+ });
4098
+ };
4099
+ }, [withdrawalId]);
4100
+ useOnWithdrawalLifecycle(handler);
4101
+ (0, import_react12.useEffect)(() => {
4102
+ if (!withdrawalId) return;
4103
+ if (!state.terminal) return;
4104
+ if (balanceRefetchedForRef.current === withdrawalId) return;
4105
+ balanceRefetchedForRef.current = withdrawalId;
4106
+ invalidateBalanceQueries(queryClient);
4107
+ client.syncManagedBalances().catch(() => {
4108
+ });
4109
+ }, [client, queryClient, state.terminal, withdrawalId]);
4110
+ const reset = (0, import_react12.useCallback)(() => setState(INITIAL_STATE), []);
4111
+ return { state, reset };
4112
+ }
4113
+
3648
4114
  // src/index.ts
3649
4115
  var import_sdk4 = require("@agg-build/sdk");
3650
4116
 
3651
4117
  // src/use-geo-block.ts
3652
- var import_react11 = require("react");
4118
+ var import_react13 = require("react");
3653
4119
  var DEFAULT_STATE = {
3654
4120
  isLocationBlocked: false,
3655
4121
  isTradingBlocked: false,
@@ -3657,7 +4123,7 @@ var DEFAULT_STATE = {
3657
4123
  };
3658
4124
  function useGeoBlock() {
3659
4125
  var _a, _b;
3660
- const authContext = (0, import_react11.useContext)(AggAuthContext);
4126
+ const authContext = (0, import_react13.useContext)(AggAuthContext);
3661
4127
  if (process.env.NEXT_PUBLIC_GEO_BLOCK_DISABLE === "true") return DEFAULT_STATE;
3662
4128
  const isBlocked = (_b = (_a = authContext == null ? void 0 : authContext.user) == null ? void 0 : _a.isLocationBlocked) != null ? _b : false;
3663
4129
  if (!isBlocked) return DEFAULT_STATE;
@@ -3669,7 +4135,7 @@ function useGeoBlock() {
3669
4135
  }
3670
4136
 
3671
4137
  // src/use-agg-auth.ts
3672
- var import_react12 = require("react");
4138
+ var import_react14 = require("react");
3673
4139
  function useAggAuth(options = {}) {
3674
4140
  const {
3675
4141
  isAuthenticated,
@@ -3679,7 +4145,7 @@ function useAggAuth(options = {}) {
3679
4145
  signIn: signInWithProvider,
3680
4146
  signOut
3681
4147
  } = useAggAuthContext();
3682
- const signIn = (0, import_react12.useCallback)(
4148
+ const signIn = (0, import_react14.useCallback)(
3683
4149
  (statement) => __async(null, null, function* () {
3684
4150
  if (!options.signMessage) {
3685
4151
  throw new Error(
@@ -3703,11 +4169,11 @@ function useAggAuth(options = {}) {
3703
4169
  }
3704
4170
 
3705
4171
  // src/use-link-account.ts
3706
- var import_react13 = require("react");
4172
+ var import_react15 = require("react");
3707
4173
  function useLinkAccount() {
3708
4174
  const client = useAggClient();
3709
- const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
3710
- const [error, setError] = (0, import_react13.useState)(null);
4175
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
4176
+ const [error, setError] = (0, import_react15.useState)(null);
3711
4177
  const run = (fn) => {
3712
4178
  setIsLoading(true);
3713
4179
  setError(null);
@@ -3717,11 +4183,11 @@ function useLinkAccount() {
3717
4183
  throw err;
3718
4184
  }).finally(() => setIsLoading(false));
3719
4185
  };
3720
- const startLink = (0, import_react13.useCallback)(
4186
+ const startLink = (0, import_react15.useCallback)(
3721
4187
  (body) => run(() => client.linkAccount(body)),
3722
4188
  [client]
3723
4189
  );
3724
- const confirmLink = (0, import_react13.useCallback)(
4190
+ const confirmLink = (0, import_react15.useCallback)(
3725
4191
  (token) => run(() => client.linkAccountConfirm(token)),
3726
4192
  [client]
3727
4193
  );
@@ -3736,13 +4202,13 @@ var requestAggAuthChooserOpen = () => {
3736
4202
  };
3737
4203
 
3738
4204
  // src/use-categories.ts
3739
- var import_react_query15 = require("@tanstack/react-query");
4205
+ var import_react_query16 = require("@tanstack/react-query");
3740
4206
  function useCategories(options) {
3741
4207
  var _a, _b, _c, _d;
3742
4208
  const client = useAggClient();
3743
4209
  const enabled = (_a = options == null ? void 0 : options.enabled) != null ? _a : true;
3744
4210
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
3745
- const query = (0, import_react_query15.useInfiniteQuery)({
4211
+ const query = (0, import_react_query16.useInfiniteQuery)({
3746
4212
  queryKey: ["categories", limit],
3747
4213
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
3748
4214
  const res = yield client.getCategories({
@@ -3767,10 +4233,10 @@ function useCategories(options) {
3767
4233
  }
3768
4234
 
3769
4235
  // src/use-debounced-value.ts
3770
- var import_react14 = require("react");
4236
+ var import_react16 = require("react");
3771
4237
  function useDebouncedValue(value, delay) {
3772
- const [debouncedValue, setDebouncedValue] = (0, import_react14.useState)(value);
3773
- (0, import_react14.useEffect)(() => {
4238
+ const [debouncedValue, setDebouncedValue] = (0, import_react16.useState)(value);
4239
+ (0, import_react16.useEffect)(() => {
3774
4240
  const timeoutId = window.setTimeout(() => {
3775
4241
  setDebouncedValue(value);
3776
4242
  }, delay);
@@ -3782,12 +4248,12 @@ function useDebouncedValue(value, delay) {
3782
4248
  }
3783
4249
 
3784
4250
  // src/use-execution-orders.ts
3785
- var import_react_query16 = require("@tanstack/react-query");
4251
+ var import_react_query17 = require("@tanstack/react-query");
3786
4252
  function useExecutionOrders(options = {}) {
3787
4253
  var _a, _b;
3788
4254
  const client = useAggClient();
3789
4255
  const { status, limit = 50, enabled = true, refetchIntervalMs = false } = options;
3790
- const query = (0, import_react_query16.useInfiniteQuery)({
4256
+ const query = (0, import_react_query17.useInfiniteQuery)({
3791
4257
  queryKey: ["execution-orders", status != null ? status : "all", limit],
3792
4258
  queryFn: ({ pageParam }) => client.getExecutionOrders({
3793
4259
  status,
@@ -3811,12 +4277,12 @@ function useExecutionOrders(options = {}) {
3811
4277
  }
3812
4278
 
3813
4279
  // src/use-user-activity.ts
3814
- var import_react_query17 = require("@tanstack/react-query");
4280
+ var import_react_query18 = require("@tanstack/react-query");
3815
4281
  function useUserActivity(options = {}) {
3816
4282
  var _a, _b;
3817
4283
  const client = useAggClient();
3818
4284
  const { type, limit = 50, enabled = true } = options;
3819
- const query = (0, import_react_query17.useInfiniteQuery)({
4285
+ const query = (0, import_react_query18.useInfiniteQuery)({
3820
4286
  queryKey: ["user-activity", type != null ? type : "all", limit],
3821
4287
  queryFn: ({ pageParam }) => client.getUserActivity({
3822
4288
  type,
@@ -3839,13 +4305,13 @@ function useUserActivity(options = {}) {
3839
4305
  }
3840
4306
 
3841
4307
  // src/use-external-id.ts
3842
- var import_react15 = require("react");
4308
+ var import_react17 = require("react");
3843
4309
  function useExternalId(options = {}) {
3844
4310
  const client = useAggClient();
3845
4311
  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)(
4312
+ const [isLoading, setIsLoading] = (0, import_react17.useState)(false);
4313
+ const [error, setError] = (0, import_react17.useState)(null);
4314
+ const linkExternalId = (0, import_react17.useCallback)(
3849
4315
  (assertion) => __async(null, null, function* () {
3850
4316
  setIsLoading(true);
3851
4317
  setError(null);
@@ -3868,12 +4334,12 @@ function useExternalId(options = {}) {
3868
4334
  }
3869
4335
 
3870
4336
  // src/use-execution-positions.ts
3871
- var import_react_query18 = require("@tanstack/react-query");
4337
+ var import_react_query19 = require("@tanstack/react-query");
3872
4338
  function useExecutionPositions(options = {}) {
3873
4339
  var _a, _b;
3874
4340
  const client = useAggClient();
3875
4341
  const { limit = 50, status, enabled = true } = options;
3876
- const query = (0, import_react_query18.useInfiniteQuery)({
4342
+ const query = (0, import_react_query19.useInfiniteQuery)({
3877
4343
  queryKey: executionKeys.positions(null, limit, status != null ? status : null),
3878
4344
  queryFn: ({ pageParam }) => client.getExecutionPositions({
3879
4345
  limit,
@@ -3896,17 +4362,17 @@ function useExecutionPositions(options = {}) {
3896
4362
  }
3897
4363
 
3898
4364
  // src/use-live-candle-overlay.ts
3899
- var import_react19 = require("react");
4365
+ var import_react21 = require("react");
3900
4366
 
3901
4367
  // src/use-live-candles.ts
3902
- var import_react18 = require("react");
4368
+ var import_react20 = require("react");
3903
4369
  var import_sdk3 = require("@agg-build/sdk");
3904
4370
 
3905
4371
  // src/use-market-chart.ts
3906
- var import_react_query19 = require("@tanstack/react-query");
4372
+ var import_react_query20 = require("@tanstack/react-query");
3907
4373
 
3908
4374
  // src/market-data/subscription.ts
3909
- var import_react16 = require("react");
4375
+ var import_react18 = require("react");
3910
4376
  function useMarketDataSubscription({
3911
4377
  marketId,
3912
4378
  additionalMarketIds,
@@ -3915,7 +4381,7 @@ function useMarketDataSubscription({
3915
4381
  trades = false
3916
4382
  }) {
3917
4383
  const ws = useAggWebSocket();
3918
- const allIds = (0, import_react16.useMemo)(() => {
4384
+ const allIds = (0, import_react18.useMemo)(() => {
3919
4385
  const ids = /* @__PURE__ */ new Set();
3920
4386
  if (marketId) ids.add(marketId);
3921
4387
  if (additionalMarketIds) {
@@ -3926,7 +4392,7 @@ function useMarketDataSubscription({
3926
4392
  return [...ids];
3927
4393
  }, [marketId, additionalMarketIds]);
3928
4394
  const stableKey = allIds.join("|");
3929
- (0, import_react16.useEffect)(() => {
4395
+ (0, import_react18.useEffect)(() => {
3930
4396
  if (!ws || !allIds.length || !enabled || !orderbook && !trades) return;
3931
4397
  const unsubscribers = [];
3932
4398
  for (const id of allIds) {
@@ -3989,7 +4455,7 @@ function useMarketChart(options) {
3989
4455
  orderbook: true,
3990
4456
  trades: true
3991
4457
  });
3992
- const queries = (0, import_react_query19.useQueries)({
4458
+ const queries = (0, import_react_query20.useQueries)({
3993
4459
  queries: outcomeIds.map((outcomeId) => ({
3994
4460
  queryKey: marketDataKeys.chart(outcomeId, interval, startTs, endTs, countBack),
3995
4461
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
@@ -4016,7 +4482,7 @@ function useMarketChart(options) {
4016
4482
  gcTime: 5 * 6e4,
4017
4483
  refetchOnWindowFocus: false,
4018
4484
  retry: 1,
4019
- placeholderData: import_react_query19.keepPreviousData
4485
+ placeholderData: import_react_query20.keepPreviousData
4020
4486
  }))
4021
4487
  });
4022
4488
  const successfulDatasets = queries.flatMap((query) => {
@@ -4045,13 +4511,13 @@ function useMarketChart(options) {
4045
4511
  }
4046
4512
 
4047
4513
  // src/use-live-market-stores.ts
4048
- var import_react17 = require("react");
4514
+ var import_react19 = require("react");
4049
4515
  function useLiveMarketStores(venueMarketIds) {
4050
4516
  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)(() => {
4517
+ const [, forceRender] = (0, import_react19.useReducer)((c) => c + 1, 0);
4518
+ const subsRef = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
4519
+ const stableKey = (0, import_react19.useMemo)(() => venueMarketIds.slice().sort().join("|"), [venueMarketIds]);
4520
+ (0, import_react19.useEffect)(() => {
4055
4521
  if (!ws || venueMarketIds.length === 0) return;
4056
4522
  const current = subsRef.current;
4057
4523
  const desired = new Set(venueMarketIds);
@@ -4088,7 +4554,7 @@ function candleToLive(c, source) {
4088
4554
  function useLiveCandles(options) {
4089
4555
  var _a;
4090
4556
  const { market, interval = "5m", mode = "venue", startTs, endTs } = options;
4091
- const venueMarketIds = (0, import_react18.useMemo)(() => {
4557
+ const venueMarketIds = (0, import_react20.useMemo)(() => {
4092
4558
  if (!market) return [];
4093
4559
  if (mode === "venue") return [market.id];
4094
4560
  const ids = [market.id];
@@ -4108,7 +4574,7 @@ function useLiveCandles(options) {
4108
4574
  endTs: endTs != null ? endTs : null,
4109
4575
  enabled: !!restMarketId && startTs != null && endTs != null
4110
4576
  });
4111
- const liveData = (0, import_react18.useMemo)(() => {
4577
+ const liveData = (0, import_react20.useMemo)(() => {
4112
4578
  if (builders2.length === 0) return { closed: [], forming: null };
4113
4579
  if (mode === "venue" || builders2.length === 1) {
4114
4580
  return {
@@ -4121,7 +4587,7 @@ function useLiveCandles(options) {
4121
4587
  forming: (0, import_sdk3.mergeCandles)(builders2.map((b) => b.getForming(interval)))
4122
4588
  };
4123
4589
  }, [builders2, interval, mode]);
4124
- const candles = (0, import_react18.useMemo)(() => {
4590
+ const candles = (0, import_react20.useMemo)(() => {
4125
4591
  const byTime = /* @__PURE__ */ new Map();
4126
4592
  if (chartData) {
4127
4593
  const venueEntries = Object.values(chartData.venues);
@@ -4146,7 +4612,7 @@ function useLiveCandles(options) {
4146
4612
  merged.sort((a, b) => a.time - b.time);
4147
4613
  return merged;
4148
4614
  }, [chartData, liveData.closed]);
4149
- const liveCandle = (0, import_react18.useMemo)(() => {
4615
+ const liveCandle = (0, import_react20.useMemo)(() => {
4150
4616
  if (!liveData.forming) return null;
4151
4617
  return candleToLive(liveData.forming, "live");
4152
4618
  }, [liveData.forming]);
@@ -4194,7 +4660,7 @@ function useLiveCandleOverlay(options) {
4194
4660
  startTs,
4195
4661
  endTs
4196
4662
  });
4197
- const scaleCandle = (0, import_react19.useCallback)(
4663
+ const scaleCandle = (0, import_react21.useCallback)(
4198
4664
  (candle) => ({
4199
4665
  time: candle.time,
4200
4666
  open: candle.o * scale,
@@ -4205,8 +4671,8 @@ function useLiveCandleOverlay(options) {
4205
4671
  }),
4206
4672
  [scale]
4207
4673
  );
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]);
4674
+ const scaledCandles = (0, import_react21.useMemo)(() => rawCandles.map(scaleCandle), [rawCandles, scaleCandle]);
4675
+ const liveCandle = (0, import_react21.useMemo)(() => rawLive ? scaleCandle(rawLive) : null, [rawLive, scaleCandle]);
4210
4676
  return {
4211
4677
  liveCandle,
4212
4678
  scaledCandles,
@@ -4217,7 +4683,7 @@ function useLiveCandleOverlay(options) {
4217
4683
  }
4218
4684
 
4219
4685
  // src/use-event-orderbook-data.ts
4220
- var import_react20 = require("react");
4686
+ var import_react22 = require("react");
4221
4687
  function extractSelectedOutcomeIds(selectedMarket) {
4222
4688
  var _a, _b, _c;
4223
4689
  if (!selectedMarket) return [];
@@ -4237,17 +4703,17 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
4237
4703
  const {
4238
4704
  features: { enableLiveUpdates }
4239
4705
  } = useAggUiConfig();
4240
- const selectedMarket = (0, import_react20.useMemo)(() => {
4706
+ const selectedMarket = (0, import_react22.useMemo)(() => {
4241
4707
  var _a;
4242
4708
  if (!selectedMarketId || !(venueMarkets == null ? void 0 : venueMarkets.length)) return null;
4243
4709
  return (_a = venueMarkets.find((m) => m.id === selectedMarketId)) != null ? _a : null;
4244
4710
  }, [venueMarkets, selectedMarketId]);
4245
- const selectedOutcomeIds = (0, import_react20.useMemo)(
4711
+ const selectedOutcomeIds = (0, import_react22.useMemo)(
4246
4712
  () => extractSelectedOutcomeIds(selectedMarket),
4247
4713
  [selectedMarket]
4248
4714
  );
4249
4715
  const selectedKey = selectedOutcomeIds.join("|");
4250
- (0, import_react20.useEffect)(() => {
4716
+ (0, import_react22.useEffect)(() => {
4251
4717
  if (!ws || !enableLiveUpdates || !selectedOutcomeIds.length) return;
4252
4718
  const unsubscribers = selectedOutcomeIds.map((id) => ws.subscribe(id, "orderbook"));
4253
4719
  return () => {
@@ -4257,7 +4723,7 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
4257
4723
  }
4258
4724
 
4259
4725
  // src/use-live-market.ts
4260
- var import_react_query20 = require("@tanstack/react-query");
4726
+ var import_react_query21 = require("@tanstack/react-query");
4261
4727
  function outcomeOrderbookToState(response, marketId) {
4262
4728
  var _a, _b, _c, _d;
4263
4729
  const { venue, orderbook, midpoint, spread, seq, checksum, timestamp, venueMarketOutcomeId } = response;
@@ -4307,7 +4773,7 @@ function useLiveMarket(canonicalMarketId) {
4307
4773
  enabled: isLiveSubscriptionEnabled,
4308
4774
  orderbook: true
4309
4775
  });
4310
- const query = (0, import_react_query20.useQuery)({
4776
+ const query = (0, import_react_query21.useQuery)({
4311
4777
  queryKey: marketDataKeys.live(canonicalMarketId != null ? canonicalMarketId : "__disabled__"),
4312
4778
  queryFn: () => __async(null, null, function* () {
4313
4779
  return createMarketLiveState(canonicalMarketId != null ? canonicalMarketId : "__disabled__");
@@ -4319,7 +4785,7 @@ function useLiveMarket(canonicalMarketId) {
4319
4785
  isConnected: Boolean(isLiveSubscriptionEnabled && isConnected)
4320
4786
  })
4321
4787
  });
4322
- const seedQuery = (0, import_react_query20.useQuery)({
4788
+ const seedQuery = (0, import_react_query21.useQuery)({
4323
4789
  queryKey: ["live-market-seed", canonicalMarketId],
4324
4790
  queryFn: ({ signal }) => canonicalMarketId ? client.getOutcomeOrderbook(canonicalMarketId, { signal }) : Promise.resolve(null),
4325
4791
  enabled: Boolean(canonicalMarketId),
@@ -4339,8 +4805,8 @@ function useLiveMarket(canonicalMarketId) {
4339
4805
  }
4340
4806
 
4341
4807
  // src/use-live-outcome-prices.ts
4342
- var import_react21 = require("react");
4343
- var import_react_query21 = require("@tanstack/react-query");
4808
+ var import_react23 = require("react");
4809
+ var import_react_query22 = require("@tanstack/react-query");
4344
4810
  var EMPTY_PRICES = /* @__PURE__ */ new Map();
4345
4811
  var buildMidpointFingerprint = (outcomeIds, queries) => {
4346
4812
  var _a, _b, _c;
@@ -4355,7 +4821,7 @@ function useLiveOutcomePrices(venueMarkets) {
4355
4821
  const {
4356
4822
  features: { enableLiveUpdates }
4357
4823
  } = useAggUiConfig();
4358
- const outcomeIds = (0, import_react21.useMemo)(() => {
4824
+ const outcomeIds = (0, import_react23.useMemo)(() => {
4359
4825
  var _a;
4360
4826
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
4361
4827
  const ids = /* @__PURE__ */ new Set();
@@ -4366,7 +4832,7 @@ function useLiveOutcomePrices(venueMarkets) {
4366
4832
  }
4367
4833
  return [...ids].sort();
4368
4834
  }, [venueMarkets]);
4369
- const queries = (0, import_react_query21.useQueries)({
4835
+ const queries = (0, import_react_query22.useQueries)({
4370
4836
  queries: outcomeIds.map((id) => ({
4371
4837
  queryKey: marketDataKeys.live(id),
4372
4838
  queryFn: () => createMarketLiveState(id),
@@ -4377,11 +4843,11 @@ function useLiveOutcomePrices(venueMarkets) {
4377
4843
  }))
4378
4844
  });
4379
4845
  const fingerprint = buildMidpointFingerprint(outcomeIds, queries);
4380
- const prevRef = (0, import_react21.useRef)({
4846
+ const prevRef = (0, import_react23.useRef)({
4381
4847
  fingerprint: "",
4382
4848
  prices: EMPTY_PRICES
4383
4849
  });
4384
- const data = (0, import_react21.useMemo)(() => {
4850
+ const data = (0, import_react23.useMemo)(() => {
4385
4851
  var _a, _b, _c, _d;
4386
4852
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return EMPTY_PRICES;
4387
4853
  if (fingerprint === prevRef.current.fingerprint) {
@@ -4400,7 +4866,9 @@ function useLiveOutcomePrices(venueMarkets) {
4400
4866
  continue;
4401
4867
  }
4402
4868
  const liveMidpoint = liveByOutcomeId.get(outcome.id);
4403
- prices.set(outcome.id, liveMidpoint != null ? liveMidpoint : outcome.price);
4869
+ if (liveMidpoint != null) {
4870
+ prices.set(outcome.id, liveMidpoint);
4871
+ }
4404
4872
  }
4405
4873
  }
4406
4874
  prevRef.current = { fingerprint, prices };
@@ -4428,8 +4896,8 @@ function useLiveTrades(canonicalMarketId) {
4428
4896
  }
4429
4897
 
4430
4898
  // src/use-midpoints.ts
4431
- var import_react22 = require("react");
4432
- var import_react_query22 = require("@tanstack/react-query");
4899
+ var import_react24 = require("react");
4900
+ var import_react_query23 = require("@tanstack/react-query");
4433
4901
  var normalizeVenueMarketIds = (venueMarkets) => {
4434
4902
  return [...new Set((venueMarkets != null ? venueMarkets : []).map((market) => market.id).filter(Boolean))].sort(
4435
4903
  (left, right) => left.localeCompare(right)
@@ -4437,8 +4905,8 @@ var normalizeVenueMarketIds = (venueMarkets) => {
4437
4905
  };
4438
4906
  function useMidpoints(venueMarkets) {
4439
4907
  const client = useAggClient();
4440
- const ids = (0, import_react22.useMemo)(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
4441
- const { data, isLoading } = (0, import_react_query22.useQuery)({
4908
+ const ids = (0, import_react24.useMemo)(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
4909
+ const { data, isLoading } = (0, import_react_query23.useQuery)({
4442
4910
  queryKey: ["midpoints", ids],
4443
4911
  queryFn: () => client.getMidpoints(ids),
4444
4912
  enabled: ids.length > 0,
@@ -4448,29 +4916,43 @@ function useMidpoints(venueMarkets) {
4448
4916
  refetchOnWindowFocus: false,
4449
4917
  refetchOnReconnect: false
4450
4918
  });
4451
- const prices = (0, import_react22.useMemo)(() => {
4452
- var _a, _b, _c, _d;
4919
+ const result = (0, import_react24.useMemo)(() => {
4920
+ var _a, _b, _c, _d, _e, _f;
4453
4921
  const map = /* @__PURE__ */ new Map();
4454
- if (!(data == null ? void 0 : data.data) || !venueMarkets) return map;
4922
+ const venueMap = /* @__PURE__ */ new Map();
4923
+ if (!(data == null ? void 0 : data.data) || !venueMarkets) return { map, venueMap };
4455
4924
  for (const item of data.data) {
4456
4925
  if ((_a = item.outcomes) == null ? void 0 : _a.length) {
4457
4926
  for (const o of item.outcomes) {
4458
4927
  if (o.midpoint != null) {
4459
4928
  map.set(o.venueMarketOutcomeId, o.midpoint);
4929
+ if (item.venue) venueMap.set(o.venueMarketOutcomeId, item.venue);
4460
4930
  }
4461
4931
  }
4462
4932
  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;
4933
+ const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
4934
+ if (market) {
4935
+ const primaryYesOutcome = market.venueMarketOutcomes.find(
4936
+ (o) => {
4937
+ var _a2;
4938
+ return ((_a2 = o.label) == null ? void 0 : _a2.toLowerCase()) === "yes";
4939
+ }
4940
+ );
4941
+ const primaryYesMidpoint = primaryYesOutcome ? (_c = map.get(primaryYesOutcome.id)) != null ? _c : null : null;
4942
+ let bestMatchedMidpoint = null;
4943
+ let bestMatchedVenue = null;
4944
+ for (const m of item.matched) {
4945
+ if (m.midpoint == null) continue;
4946
+ if (bestMatchedMidpoint == null || m.midpoint < bestMatchedMidpoint) {
4947
+ bestMatchedMidpoint = m.midpoint;
4948
+ bestMatchedVenue = (_d = m.venue) != null ? _d : null;
4949
+ }
4950
+ }
4951
+ if (bestMatchedMidpoint != null && (primaryYesMidpoint == null || bestMatchedMidpoint < primaryYesMidpoint)) {
4467
4952
  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
- }
4953
+ const isYes = ((_e = outcome.label) == null ? void 0 : _e.toLowerCase()) === "yes";
4954
+ map.set(outcome.id, isYes ? bestMatchedMidpoint : 1 - bestMatchedMidpoint);
4955
+ if (bestMatchedVenue) venueMap.set(outcome.id, bestMatchedVenue);
4474
4956
  }
4475
4957
  }
4476
4958
  }
@@ -4481,21 +4963,26 @@ function useMidpoints(venueMarkets) {
4481
4963
  const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
4482
4964
  if (!market) continue;
4483
4965
  for (const outcome of market.venueMarketOutcomes) {
4484
- const isYes = ((_d = outcome.label) == null ? void 0 : _d.toLowerCase()) === "yes";
4966
+ const isYes = ((_f = outcome.label) == null ? void 0 : _f.toLowerCase()) === "yes";
4485
4967
  map.set(outcome.id, isYes ? item.midpoint : 1 - item.midpoint);
4968
+ if (item.venue) venueMap.set(outcome.id, item.venue);
4486
4969
  }
4487
4970
  }
4488
4971
  }
4489
- return map;
4972
+ return { map, venueMap };
4490
4973
  }, [data, venueMarkets]);
4491
- return { prices, isLoading: isLoading && ids.length > 0 };
4974
+ return {
4975
+ prices: result.map,
4976
+ venueByOutcomeId: result.venueMap,
4977
+ isLoading: isLoading && ids.length > 0
4978
+ };
4492
4979
  }
4493
4980
 
4494
4981
  // src/use-market-orderbook.ts
4495
- var import_react_query23 = require("@tanstack/react-query");
4982
+ var import_react_query24 = require("@tanstack/react-query");
4496
4983
  function useMarketOrderbook(options) {
4497
4984
  var _a, _b, _c, _d, _e, _f, _g;
4498
- const queryClient = (0, import_react_query23.useQueryClient)();
4985
+ const queryClient = (0, import_react_query24.useQueryClient)();
4499
4986
  const ws = useAggWebSocket();
4500
4987
  const isConnected = useAggWebSocketConnectionState();
4501
4988
  const {
@@ -4512,7 +4999,7 @@ function useMarketOrderbook(options) {
4512
4999
  enabled: enabled && !!selectedOutcomeId,
4513
5000
  orderbook: true
4514
5001
  });
4515
- const liveQueries = (0, import_react_query23.useQueries)({
5002
+ const liveQueries = (0, import_react_query24.useQueries)({
4516
5003
  queries: subscriptionIds.map((subscriptionId) => ({
4517
5004
  queryKey: marketDataKeys.live(subscriptionId),
4518
5005
  queryFn: () => createMarketLiveState(subscriptionId),
@@ -4578,7 +5065,7 @@ function useMarketOrderbook(options) {
4578
5065
  }
4579
5066
 
4580
5067
  // src/use-order-book.ts
4581
- var import_react_query24 = require("@tanstack/react-query");
5068
+ var import_react_query25 = require("@tanstack/react-query");
4582
5069
  function useOrderBook(options) {
4583
5070
  const client = useAggClient();
4584
5071
  const { orderbooks, enabled = true, canonicalMarketId } = options;
@@ -4591,7 +5078,7 @@ function useOrderBook(options) {
4591
5078
  venueMarketOutcomeId: outcome.id
4592
5079
  })) : void 0
4593
5080
  });
4594
- const batchedResult = (0, import_react_query24.useQuery)({
5081
+ const batchedResult = (0, import_react_query25.useQuery)({
4595
5082
  queryKey: requestedVenueMarketIds.length ? ["orderbooks", requestedVenueMarketIds, null] : ["orderbooks", "__disabled__", null],
4596
5083
  queryFn: ({ signal }) => client.getOrderbooks(
4597
5084
  {
@@ -4604,7 +5091,7 @@ function useOrderBook(options) {
4604
5091
  gcTime: 5 * 6e4,
4605
5092
  refetchOnWindowFocus: false,
4606
5093
  retry: 1,
4607
- placeholderData: import_react_query24.keepPreviousData
5094
+ placeholderData: import_react_query25.keepPreviousData
4608
5095
  });
4609
5096
  const data = (() => {
4610
5097
  var _a, _b;
@@ -4659,7 +5146,7 @@ function useOrderBook(options) {
4659
5146
  }
4660
5147
 
4661
5148
  // src/use-orderbook-quote.ts
4662
- var import_react_query25 = require("@tanstack/react-query");
5149
+ var import_react_query26 = require("@tanstack/react-query");
4663
5150
  var QUOTE_DEBOUNCE_MS = 300;
4664
5151
  var createUnavailableOrderbookError = (message, code, retryable) => {
4665
5152
  const error = new Error(message);
@@ -4721,7 +5208,7 @@ function useOrderbookQuote(options) {
4721
5208
  const { marketId, side, size, enabled = true } = options;
4722
5209
  const debouncedSize = useDebouncedValue(size, QUOTE_DEBOUNCE_MS);
4723
5210
  const shouldFetch = enabled && !!marketId && debouncedSize > 0;
4724
- const query = (0, import_react_query25.useQuery)({
5211
+ const query = (0, import_react_query26.useQuery)({
4725
5212
  queryKey: marketId ? marketDataKeys.orderbookQuote(marketId, side, debouncedSize) : ["market-data", "orderbook-quote", "__disabled__"],
4726
5213
  queryFn: () => __async(null, null, function* () {
4727
5214
  var _a2, _b, _c, _d;
@@ -4752,7 +5239,7 @@ function useOrderbookQuote(options) {
4752
5239
  staleTime: 1e4,
4753
5240
  gcTime: 5 * 6e4,
4754
5241
  retry: 1,
4755
- placeholderData: import_react_query25.keepPreviousData
5242
+ placeholderData: import_react_query26.keepPreviousData
4756
5243
  });
4757
5244
  return {
4758
5245
  data: (_a = query.data) != null ? _a : null,
@@ -4763,12 +5250,12 @@ function useOrderbookQuote(options) {
4763
5250
  }
4764
5251
 
4765
5252
  // src/use-orders.ts
4766
- var import_react_query26 = require("@tanstack/react-query");
5253
+ var import_react_query27 = require("@tanstack/react-query");
4767
5254
  function useOrders(options = {}) {
4768
5255
  var _a, _b, _c, _d;
4769
5256
  const client = useAggClient();
4770
5257
  const { userId, status, limit = 50, offset = 0, enabled = true } = options;
4771
- const query = (0, import_react_query26.useQuery)({
5258
+ const query = (0, import_react_query27.useQuery)({
4772
5259
  queryKey: ["orders", userId != null ? userId : "me", status != null ? status : "all", limit, offset],
4773
5260
  queryFn: () => client.getOrders({
4774
5261
  userId,
@@ -4785,16 +5272,16 @@ function useOrders(options = {}) {
4785
5272
  }
4786
5273
 
4787
5274
  // src/use-search.ts
4788
- var import_react_query27 = require("@tanstack/react-query");
4789
- var import_react23 = require("react");
5275
+ var import_react_query28 = require("@tanstack/react-query");
5276
+ var import_react25 = require("react");
4790
5277
  function useSearch(options) {
4791
5278
  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());
5279
+ const client = (0, import_react25.useContext)(AggClientContext);
5280
+ const queryClient = (0, import_react25.useContext)(import_react_query28.QueryClientContext);
5281
+ const [fallbackQueryClient] = (0, import_react25.useState)(() => new import_react_query28.QueryClient());
4795
5282
  const { q, type, categoryIds, limit = 20, enabled = true } = options;
4796
5283
  const isEnabled = enabled && q.length > 0;
4797
- (0, import_react23.useEffect)(() => {
5284
+ (0, import_react25.useEffect)(() => {
4798
5285
  if (queryClient) return void 0;
4799
5286
  fallbackQueryClient.mount();
4800
5287
  return () => {
@@ -4804,7 +5291,7 @@ function useSearch(options) {
4804
5291
  if (isEnabled && !client) {
4805
5292
  throw new Error("useSearch must be used within an <AggProvider>");
4806
5293
  }
4807
- const query = (0, import_react_query27.useInfiniteQuery)(
5294
+ const query = (0, import_react_query28.useInfiniteQuery)(
4808
5295
  {
4809
5296
  queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit],
4810
5297
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
@@ -4826,7 +5313,7 @@ function useSearch(options) {
4826
5313
  if (!lastPage.hasMore) return void 0;
4827
5314
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
4828
5315
  },
4829
- placeholderData: import_react_query27.keepPreviousData,
5316
+ placeholderData: import_react_query28.keepPreviousData,
4830
5317
  enabled: isEnabled && !!client
4831
5318
  },
4832
5319
  queryClient != null ? queryClient : fallbackQueryClient
@@ -4845,7 +5332,7 @@ function useSearch(options) {
4845
5332
  }
4846
5333
 
4847
5334
  // src/use-smart-route.ts
4848
- var import_react_query28 = require("@tanstack/react-query");
5335
+ var import_react_query29 = require("@tanstack/react-query");
4849
5336
  function useSmartRoute(options) {
4850
5337
  var _a, _b;
4851
5338
  const client = useAggClient();
@@ -4863,7 +5350,7 @@ function useSmartRoute(options) {
4863
5350
  enabled = true
4864
5351
  } = options;
4865
5352
  const resolvedVenueMarketOutcomeId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : venueMarketId) != null ? _a : outcomeId;
4866
- const query = (0, import_react_query28.useQuery)({
5353
+ const query = (0, import_react_query29.useQuery)({
4867
5354
  queryKey: [
4868
5355
  "smart-route",
4869
5356
  resolvedVenueMarketOutcomeId,
@@ -4895,7 +5382,7 @@ function useSmartRoute(options) {
4895
5382
  gcTime: 6e4,
4896
5383
  refetchOnWindowFocus: false,
4897
5384
  retry: 1,
4898
- placeholderData: import_react_query28.keepPreviousData
5385
+ placeholderData: import_react_query29.keepPreviousData
4899
5386
  });
4900
5387
  const error = query.error;
4901
5388
  return {
@@ -4908,12 +5395,12 @@ function useSmartRoute(options) {
4908
5395
  }
4909
5396
 
4910
5397
  // src/use-user-holdings.ts
4911
- var import_react_query29 = require("@tanstack/react-query");
5398
+ var import_react_query30 = require("@tanstack/react-query");
4912
5399
  function useUserHoldings(options) {
4913
5400
  var _a, _b;
4914
5401
  const client = useAggClient();
4915
5402
  const { venue, venueMarketId, venueEventId, enabled = true } = options;
4916
- const query = (0, import_react_query29.useInfiniteQuery)({
5403
+ const query = (0, import_react_query30.useInfiniteQuery)({
4917
5404
  queryKey: ["user-holdings", venue, venueMarketId, venueEventId],
4918
5405
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
4919
5406
  return client.getUserHoldings({
@@ -4939,15 +5426,15 @@ function useUserHoldings(options) {
4939
5426
  }
4940
5427
 
4941
5428
  // src/use-enriched-venue-event.ts
4942
- var import_react25 = require("react");
5429
+ var import_react27 = require("react");
4943
5430
 
4944
5431
  // src/use-venue-event.ts
4945
- var import_react_query30 = require("@tanstack/react-query");
5432
+ var import_react_query31 = require("@tanstack/react-query");
4946
5433
  function useVenueEvent(options) {
4947
5434
  var _a;
4948
5435
  const client = useAggClient();
4949
5436
  const { eventId, enabled = true } = options;
4950
- const query = (0, import_react_query30.useQuery)({
5437
+ const query = (0, import_react_query31.useQuery)({
4951
5438
  queryKey: ["venue-event", eventId],
4952
5439
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
4953
5440
  return client.getVenueEventById(eventId, { signal });
@@ -4966,13 +5453,13 @@ function useVenueEvent(options) {
4966
5453
  }
4967
5454
 
4968
5455
  // src/use-venue-markets.ts
4969
- var import_react_query31 = require("@tanstack/react-query");
4970
- var import_react24 = require("react");
5456
+ var import_react_query32 = require("@tanstack/react-query");
5457
+ var import_react26 = require("react");
4971
5458
  function useVenueMarkets(options) {
4972
5459
  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());
5460
+ const client = (0, import_react26.useContext)(AggClientContext);
5461
+ const queryClient = (0, import_react26.useContext)(import_react_query32.QueryClientContext);
5462
+ const [fallbackQueryClient] = (0, import_react26.useState)(() => new import_react_query32.QueryClient());
4976
5463
  const venue = options == null ? void 0 : options.venue;
4977
5464
  const venueEventId = options == null ? void 0 : options.venueEventId;
4978
5465
  const search = options == null ? void 0 : options.search;
@@ -4983,7 +5470,7 @@ function useVenueMarkets(options) {
4983
5470
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
4984
5471
  const sortBy = options == null ? void 0 : options.sortBy;
4985
5472
  const sortDir = options == null ? void 0 : options.sortDir;
4986
- (0, import_react24.useEffect)(() => {
5473
+ (0, import_react26.useEffect)(() => {
4987
5474
  if (queryClient) return void 0;
4988
5475
  fallbackQueryClient.mount();
4989
5476
  return () => {
@@ -4993,7 +5480,7 @@ function useVenueMarkets(options) {
4993
5480
  if (enabled && !client) {
4994
5481
  throw new Error("useVenueMarkets must be used within an <AggProvider>");
4995
5482
  }
4996
- const query = (0, import_react_query31.useInfiniteQuery)(
5483
+ const query = (0, import_react_query32.useInfiniteQuery)(
4997
5484
  {
4998
5485
  queryKey: [
4999
5486
  "venue-markets",
@@ -5063,7 +5550,7 @@ function useEnrichedVenueEvent(options) {
5063
5550
  sortBy: "yesPrice",
5064
5551
  sortDir: "desc"
5065
5552
  });
5066
- const enrichedEvent = (0, import_react25.useMemo)(() => {
5553
+ const enrichedEvent = (0, import_react27.useMemo)(() => {
5067
5554
  if (!event) return void 0;
5068
5555
  if (markets.length === 0) return event;
5069
5556
  return mergeEventWithFullMarkets(event, markets);
@@ -5077,13 +5564,13 @@ function useEnrichedVenueEvent(options) {
5077
5564
  }
5078
5565
 
5079
5566
  // src/use-venue-events.ts
5080
- var import_react_query32 = require("@tanstack/react-query");
5081
- var import_react26 = require("react");
5567
+ var import_react_query33 = require("@tanstack/react-query");
5568
+ var import_react28 = require("react");
5082
5569
  function useVenueEvents(options) {
5083
5570
  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());
5571
+ const client = (0, import_react28.useContext)(AggClientContext);
5572
+ const queryClient = (0, import_react28.useContext)(import_react_query33.QueryClientContext);
5573
+ const [fallbackQueryClient] = (0, import_react28.useState)(() => new import_react_query33.QueryClient());
5087
5574
  const venues = options == null ? void 0 : options.venues;
5088
5575
  const search = options == null ? void 0 : options.search;
5089
5576
  const categoryIds = options == null ? void 0 : options.categoryIds;
@@ -5098,7 +5585,7 @@ function useVenueEvents(options) {
5098
5585
  const maxYesPrice = options == null ? void 0 : options.maxYesPrice;
5099
5586
  const endDateFrom = options == null ? void 0 : options.endDateFrom;
5100
5587
  const initialPages = options == null ? void 0 : options.initialPages;
5101
- (0, import_react26.useEffect)(() => {
5588
+ (0, import_react28.useEffect)(() => {
5102
5589
  if (queryClient) return void 0;
5103
5590
  fallbackQueryClient.mount();
5104
5591
  return () => {
@@ -5108,7 +5595,7 @@ function useVenueEvents(options) {
5108
5595
  if (enabled && !client) {
5109
5596
  throw new Error("useVenueEvents must be used within an <AggProvider>");
5110
5597
  }
5111
- const query = (0, import_react_query32.useInfiniteQuery)(
5598
+ const query = (0, import_react_query33.useInfiniteQuery)(
5112
5599
  {
5113
5600
  queryKey: [
5114
5601
  queryKeyScope,
@@ -5150,13 +5637,14 @@ function useVenueEvents(options) {
5150
5637
  if (!lastPage.hasMore) return void 0;
5151
5638
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
5152
5639
  },
5153
- placeholderData: import_react_query32.keepPreviousData,
5640
+ // TODO: RMIK - Comment out to show skeletons on category switch
5641
+ placeholderData: import_react_query33.keepPreviousData,
5154
5642
  enabled: enabled && !!client
5155
5643
  },
5156
5644
  queryClient != null ? queryClient : fallbackQueryClient
5157
5645
  );
5158
- const prefetchedRef = (0, import_react26.useRef)(false);
5159
- (0, import_react26.useEffect)(() => {
5646
+ const prefetchedRef = (0, import_react28.useRef)(false);
5647
+ (0, import_react28.useEffect)(() => {
5160
5648
  var _a2, _b2;
5161
5649
  if (prefetchedRef.current) return;
5162
5650
  if (!initialPages || initialPages <= 1) return;
@@ -5174,7 +5662,7 @@ function useVenueEvents(options) {
5174
5662
  query.hasNextPage,
5175
5663
  query.fetchNextPage
5176
5664
  ]);
5177
- const events = (0, import_react26.useMemo)(
5665
+ const events = (0, import_react28.useMemo)(
5178
5666
  () => {
5179
5667
  var _a2, _b2;
5180
5668
  return (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.flatMap((page) => page.data)) != null ? _b2 : [];
@@ -5192,7 +5680,7 @@ function useVenueEvents(options) {
5192
5680
  }
5193
5681
 
5194
5682
  // src/use-venue-market-midpoints.ts
5195
- var import_react_query33 = require("@tanstack/react-query");
5683
+ var import_react_query34 = require("@tanstack/react-query");
5196
5684
  var MAX_VENUE_MARKET_IDS_PER_REQUEST = 200;
5197
5685
  var normalizeVenueMarketIds2 = (venueMarketIds) => {
5198
5686
  return [
@@ -5228,7 +5716,7 @@ function useVenueMarketMidpoints(options) {
5228
5716
  const client = useAggClient();
5229
5717
  const enabled = (_a = options.enabled) != null ? _a : true;
5230
5718
  const requestedVenueMarketIds = normalizeVenueMarketIds2(options.venueMarketIds);
5231
- const query = (0, import_react_query33.useQuery)({
5719
+ const query = (0, import_react_query34.useQuery)({
5232
5720
  queryKey: requestedVenueMarketIds.length ? ["venue-market-midpoints", requestedVenueMarketIds] : ["venue-market-midpoints", "__disabled__"],
5233
5721
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
5234
5722
  const venueMarketIdChunks = chunkVenueMarketIds(requestedVenueMarketIds);
@@ -5247,7 +5735,7 @@ function useVenueMarketMidpoints(options) {
5247
5735
  gcTime: 5 * 6e4,
5248
5736
  refetchOnWindowFocus: false,
5249
5737
  retry: 1,
5250
- placeholderData: import_react_query33.keepPreviousData
5738
+ placeholderData: import_react_query34.keepPreviousData
5251
5739
  });
5252
5740
  const midpointRows = (_c = (_b = query.data) == null ? void 0 : _b.data) != null ? _c : [];
5253
5741
  const midpointsByVenueMarketId = mapMidpointsByVenueMarketId(midpointRows);
@@ -5282,7 +5770,13 @@ function computePriceGaps(input) {
5282
5770
  }
5283
5771
 
5284
5772
  // src/use-viewport-midpoints.ts
5285
- var import_react27 = require("react");
5773
+ var import_react29 = require("react");
5774
+ var normalizeOutcomeLabel = (value) => value.trim().toLowerCase();
5775
+ var resolveYesMidpoint = (outcomes) => {
5776
+ if (!(outcomes == null ? void 0 : outcomes.length)) return void 0;
5777
+ const yesOutcome = outcomes.find((outcome) => normalizeOutcomeLabel(outcome.label) === "yes");
5778
+ return yesOutcome == null ? void 0 : yesOutcome.midpoint;
5779
+ };
5286
5780
  var resolveUncachedVisibleMarketIds = (visibleMarkets, cache, inFlightIds) => {
5287
5781
  const idsToFetch = [];
5288
5782
  for (const market of visibleMarkets) {
@@ -5293,35 +5787,38 @@ var resolveUncachedVisibleMarketIds = (visibleMarkets, cache, inFlightIds) => {
5293
5787
  return idsToFetch;
5294
5788
  };
5295
5789
  var buildCachedMidpointEntries = (requestedVenueMarketIds, rows) => {
5296
- var _a, _b;
5790
+ var _a, _b, _c;
5297
5791
  const rowsByVenueMarketId = new Map(rows.map((item) => [item.venueMarketId, item]));
5298
5792
  const nextCacheEntries = /* @__PURE__ */ new Map();
5299
5793
  for (const venueMarketId of requestedVenueMarketIds) {
5300
5794
  const item = rowsByVenueMarketId.get(venueMarketId);
5301
- nextCacheEntries.set(venueMarketId, {
5302
- 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 {
5795
+ const yesMidpoint = resolveYesMidpoint(item == null ? void 0 : item.outcomes);
5796
+ nextCacheEntries.set(venueMarketId, __spreadProps(__spreadValues({}, (item == null ? void 0 : item.venue) ? { venue: item.venue } : {}), {
5797
+ midpoint: (_a = yesMidpoint != null ? yesMidpoint : item == null ? void 0 : item.midpoint) != null ? _a : null,
5798
+ spread: (_b = item == null ? void 0 : item.spread) != null ? _b : null,
5799
+ matched: ((_c = item == null ? void 0 : item.matched) != null ? _c : []).map((matched) => {
5800
+ var _a2, _b2;
5801
+ return __spreadValues({
5306
5802
  venueMarketId: matched.venueMarketId,
5307
- midpoint: (_a2 = matched.midpoint) != null ? _a2 : null
5308
- };
5803
+ midpoint: (_a2 = matched.midpoint) != null ? _a2 : null,
5804
+ spread: (_b2 = matched.spread) != null ? _b2 : null
5805
+ }, matched.venue ? { venue: matched.venue } : {});
5309
5806
  })
5310
- });
5807
+ }));
5311
5808
  }
5312
5809
  return nextCacheEntries;
5313
5810
  };
5314
5811
  function useViewportMidpoints(visibleMarkets) {
5315
5812
  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);
5813
+ const [cache, setCache] = (0, import_react29.useState)(() => /* @__PURE__ */ new Map());
5814
+ const inFlightRef = (0, import_react29.useRef)(/* @__PURE__ */ new Set());
5815
+ const visibleRef = (0, import_react29.useRef)(visibleMarkets);
5319
5816
  visibleRef.current = visibleMarkets;
5320
- const visibleFp = (0, import_react27.useMemo)(
5817
+ const visibleFp = (0, import_react29.useMemo)(
5321
5818
  () => [...new Set(visibleMarkets.map((m) => m.id))].sort().join("|"),
5322
5819
  [visibleMarkets]
5323
5820
  );
5324
- (0, import_react27.useEffect)(() => {
5821
+ (0, import_react29.useEffect)(() => {
5325
5822
  const toFetch = resolveUncachedVisibleMarketIds(visibleRef.current, cache, inFlightRef.current);
5326
5823
  if (!toFetch.length) return;
5327
5824
  let cancelled = false;
@@ -5345,37 +5842,46 @@ function useViewportMidpoints(visibleMarkets) {
5345
5842
  cancelled = true;
5346
5843
  };
5347
5844
  }, [visibleFp, cache]);
5348
- const prices = (0, import_react27.useMemo)(() => {
5349
- var _a;
5845
+ const { prices, venueByOutcomeId } = (0, import_react29.useMemo)(() => {
5846
+ var _a, _b, _c, _d, _e, _f;
5350
5847
  const map = /* @__PURE__ */ new Map();
5848
+ const venueMap = /* @__PURE__ */ new Map();
5351
5849
  for (const market of visibleMarkets) {
5352
5850
  const entry = cache.get(market.id);
5353
5851
  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);
5852
+ let mid = entry.midpoint;
5853
+ let midVenue = (_a = entry.venue) != null ? _a : market.venue;
5854
+ for (const m of entry.matched) {
5855
+ const matchedFromCache = (_b = cache.get(m.venueMarketId)) == null ? void 0 : _b.midpoint;
5856
+ const candidateMidpoint = matchedFromCache != null ? matchedFromCache : m.midpoint;
5857
+ if (candidateMidpoint == null) continue;
5858
+ if (mid == null || candidateMidpoint < mid) {
5859
+ mid = candidateMidpoint;
5860
+ midVenue = (_e = (_d = (_c = cache.get(m.venueMarketId)) == null ? void 0 : _c.venue) != null ? _d : m.venue) != null ? _e : market.venue;
5861
+ }
5862
+ }
5863
+ if (mid == null) continue;
5359
5864
  for (const outcome of market.venueMarketOutcomes) {
5360
- const isYes = ((_a = outcome.label) == null ? void 0 : _a.toLowerCase()) === "yes";
5865
+ const isYes = ((_f = outcome.label) == null ? void 0 : _f.toLowerCase()) === "yes";
5361
5866
  map.set(outcome.id, isYes ? mid : 1 - mid);
5867
+ venueMap.set(outcome.id, midVenue);
5362
5868
  }
5363
5869
  }
5364
- return map;
5870
+ return { prices: map, venueByOutcomeId: venueMap };
5365
5871
  }, [cache, visibleMarkets]);
5366
- return { prices };
5872
+ return { prices, venueByOutcomeId };
5367
5873
  }
5368
5874
 
5369
5875
  // src/use-visible-ids.ts
5370
- var import_react28 = require("react");
5876
+ var import_react30 = require("react");
5371
5877
  function useVisibleIds(options = {}) {
5372
5878
  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)(() => {
5879
+ const [visibleIds, setVisibleIds] = (0, import_react30.useState)(() => /* @__PURE__ */ new Set());
5880
+ const observerRef = (0, import_react30.useRef)(null);
5881
+ const elementsRef = (0, import_react30.useRef)(/* @__PURE__ */ new Map());
5882
+ const elementIdRef = (0, import_react30.useRef)(/* @__PURE__ */ new WeakMap());
5883
+ const callbackRefsRef = (0, import_react30.useRef)(/* @__PURE__ */ new Map());
5884
+ (0, import_react30.useEffect)(() => {
5379
5885
  if (typeof IntersectionObserver === "undefined") return;
5380
5886
  const observer = new IntersectionObserver(
5381
5887
  (entries) => {
@@ -5407,7 +5913,7 @@ function useVisibleIds(options = {}) {
5407
5913
  observerRef.current = null;
5408
5914
  };
5409
5915
  }, [rootMargin, threshold]);
5410
- const register = (0, import_react28.useCallback)((id) => {
5916
+ const register = (0, import_react30.useCallback)((id) => {
5411
5917
  const existing = callbackRefsRef.current.get(id);
5412
5918
  if (existing) return existing;
5413
5919
  const callback = (el) => {
@@ -5440,12 +5946,12 @@ function useVisibleIds(options = {}) {
5440
5946
  }
5441
5947
 
5442
5948
  // src/use-app-config.ts
5443
- var import_react_query34 = require("@tanstack/react-query");
5949
+ var import_react_query35 = require("@tanstack/react-query");
5444
5950
  var FIVE_MINUTES = 5 * 60 * 1e3;
5445
5951
  function useAppConfig() {
5446
5952
  var _a, _b, _c, _d, _e, _f;
5447
5953
  const client = useAggClient();
5448
- const query = (0, import_react_query34.useQuery)({
5954
+ const query = (0, import_react_query35.useQuery)({
5449
5955
  queryKey: ["agg", "app-config"],
5450
5956
  queryFn: () => client.getAppConfig(),
5451
5957
  staleTime: FIVE_MINUTES
@@ -5541,6 +6047,7 @@ function useAppConfig() {
5541
6047
  useOnBalanceUpdate,
5542
6048
  useOnOrderSubmitted,
5543
6049
  useOnRedeemEvent,
6050
+ useOnWithdrawalLifecycle,
5544
6051
  useOrderBook,
5545
6052
  useOrderbookQuote,
5546
6053
  useOrders,
@@ -5564,5 +6071,7 @@ function useAppConfig() {
5564
6071
  useVenueMarkets,
5565
6072
  useViewportMidpoints,
5566
6073
  useVisibleIds,
5567
- useWithdrawManaged
6074
+ useWithdrawFlow,
6075
+ useWithdrawManaged,
6076
+ useWithdrawalLifecycle
5568
6077
  });