@agg-build/hooks 4.7.4 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,9 +74,10 @@ var ACTIVE_VENUES = [
74
74
  "probable" /* probable */,
75
75
  "myriad" /* myriad */,
76
76
  "hyperliquid" /* hyperliquid */,
77
- "novig" /* novig */
77
+ "novig" /* novig */,
78
+ "prophetx" /* prophetx */
78
79
  ];
79
- var INACTIVE_VENUES = ["prophetx" /* prophetx */];
80
+ var INACTIVE_VENUES = [];
80
81
  var ACTIVE_VENUE_SET = new Set(ACTIVE_VENUES);
81
82
  var INACTIVE_VENUE_SET = new Set(INACTIVE_VENUES);
82
83
 
@@ -876,7 +877,7 @@ var enUsLabels = {
876
877
  venueMinOrderSize: "Order size is below the venue minimum. Try a larger amount.",
877
878
  sourceBalanceChanged: "Your balance changed since the quote. Refresh and try again, or pick a smaller amount.",
878
879
  venueMarketResolved: "This market just resolved. Pick a different market or wait for the next round.",
879
- dflowWalletUnverified: "Your Solana wallet needs to be verified with dFlow before you can trade Kalshi markets. Verify at https://dflow.net/proof, then try again.",
880
+ dflowWalletUnverified: "This route is unavailable for your wallet. Check your account connection and try again.",
880
881
  venueNoQuotePath: "No active quote path for this market right now. Try a different size, or wait a moment and re-quote.",
881
882
  solanaBlockhashExpired: "Solana transaction expired before submission. Please re-quote and try again.",
882
883
  venueRateLimited: "The venue is rate-limiting requests right now. Please wait a moment and try again.",
@@ -920,6 +921,25 @@ var enUsLabels = {
920
921
  kycSuccessTitle: "Verification successful",
921
922
  kycSuccessDescription: "Your identity has been confirmed and you now have full access to trade on Kalshi markets.",
922
923
  kycSuccessDone: "Done",
924
+ sharedKyc: {
925
+ required: "KYC required",
926
+ completeToTrade: "Complete KYC to trade",
927
+ checkingStatus: "Checking verification status",
928
+ modal: {
929
+ ariaLabel: "Identity verification",
930
+ title: "Verify Your Identity",
931
+ freeDescription: "Complete a one-time identity verification to trade all KYC-required venues.",
932
+ pendingTitle: "Verification pending",
933
+ pendingDescription: "Your verification is being reviewed. Check back for approval before trading.",
934
+ checkStatus: "Check verification status",
935
+ startVerification: "Start verification",
936
+ doItLater: "Do it later",
937
+ successTitle: "Verification successful",
938
+ successDescription: "Your identity has been verified. You can now trade on all KYC-required venues.",
939
+ done: "Done",
940
+ error: "We couldn't confirm your verification."
941
+ }
942
+ },
923
943
  connectKalshi: "Connect to trade Kalshi",
924
944
  tradingAccessVenues: "Venues",
925
945
  tradingAccessAvailable: "Available",
@@ -964,9 +984,13 @@ var enUsLabels = {
964
984
  insufficientVenueInventory: (sharesLabel, priceLabel) => `Only ${sharesLabel} \xB7 ${priceLabel}`,
965
985
  viewAllRoutes: (count) => `View all (${count})`,
966
986
  venueUnavailableInRegion: "Unavailable in your region",
987
+ venueTemporarilyUnavailable: "Temporarily unavailable",
967
988
  verified: "Verified",
968
989
  platformFee: "0% platform fees",
969
990
  estimatedFees: "Estimated fees",
991
+ executionReserve: "Execution reserve",
992
+ executionReserveTooltipAria: "Why funds are reserved",
993
+ executionReserveDescription: "Held for price movement or possible venue charges, not a confirmed fee. Unused funds are returned after execution.",
970
994
  estimatedFeesTooltipAria: "Estimated fees breakdown",
971
995
  feeBreakdownVenueFees: "Venue",
972
996
  feeBreakdownBridgeFees: "Bridging",
@@ -1241,6 +1265,35 @@ var enUsLabels = {
1241
1265
  bannerAria: "Site header",
1242
1266
  logoAria: "Home"
1243
1267
  },
1268
+ paperTrading: {
1269
+ badge: "Paper trading",
1270
+ badgeTooltip: "Trade real prediction markets with simulated funds. No real money at risk.",
1271
+ profile: {
1272
+ buyingPower: "Paper Buying Power",
1273
+ earnings: "Paper Earnings",
1274
+ earningsCaption: "Keep what you earn"
1275
+ },
1276
+ onboarding: {
1277
+ stepEyebrow: ({ current, total }) => `STEP ${current} OF ${total}`,
1278
+ skip: "Skip",
1279
+ back: "Back",
1280
+ next: "Next",
1281
+ // Figma reads "Get Strated" (node 4772:31236) — a typo, not copy.
1282
+ done: "Get started",
1283
+ realMarkets: {
1284
+ title: "Real markets, real prices",
1285
+ body: "Follow live prediction markets and trade using real-time market prices from leading venues."
1286
+ },
1287
+ zeroRisk: {
1288
+ title: "Paper trading, zero risk",
1289
+ body: ({ amount }) => `Start with ${amount} in simulated funds. No deposit, no real money, and no risk.`
1290
+ },
1291
+ readyToTrade: {
1292
+ title: "You're ready to trade",
1293
+ body: "Pick a market, make your prediction, and track your performance."
1294
+ }
1295
+ }
1296
+ },
1244
1297
  notifications: {
1245
1298
  order: {
1246
1299
  filledTitle: "Order filled",
@@ -1588,91 +1641,504 @@ var invalidateUserClaimState = (queryClient, options) => {
1588
1641
  invalidateUserActivityQueries(queryClient, { strategy: options == null ? void 0 : options.activityStrategy });
1589
1642
  };
1590
1643
 
1591
- // src/core/providers/balance-provider.tsx
1592
- import { useQuery } from "@tanstack/react-query";
1593
- import { useCallback, useContext, useMemo } from "react";
1644
+ // src/use-resolved-execution-mode.ts
1645
+ import { useContext as useContext7 } from "react";
1646
+
1647
+ // src/core/providers/agg-provider.tsx
1648
+ import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
1649
+
1650
+ // src/core/providers/auth-provider.tsx
1651
+ import { QueryClient, QueryClientContext } from "@tanstack/react-query";
1652
+ import { useCallback, useContext, useEffect, useMemo, useState } from "react";
1653
+
1654
+ // src/current-user-query.ts
1655
+ var CURRENT_USER_QUERY_KEY = ["current-user"];
1656
+ var CURRENT_USER_STALE_TIME_MS = 6e4;
1657
+ var fetchCurrentUserProfile = (queryClient, client, queryKey = CURRENT_USER_QUERY_KEY) => {
1658
+ return queryClient.fetchQuery({
1659
+ queryKey,
1660
+ queryFn: () => client.getCurrentUser(),
1661
+ staleTime: CURRENT_USER_STALE_TIME_MS
1662
+ });
1663
+ };
1664
+
1665
+ // src/core/providers/auth-utils.ts
1666
+ import { TurnstileChallengeError } from "@agg-build/sdk";
1667
+ var createPlaceholderUserProfile = (input) => {
1668
+ return {
1669
+ id: input.id,
1670
+ username: null,
1671
+ avatarUrl: null,
1672
+ externalId: null,
1673
+ isLocationBlocked: false,
1674
+ venueAccounts: null,
1675
+ accounts: [],
1676
+ wallets: []
1677
+ };
1678
+ };
1679
+ var createWalletSessionUser = (input) => {
1680
+ return __spreadProps(__spreadValues({}, createPlaceholderUserProfile({ id: input.id })), {
1681
+ accounts: [
1682
+ {
1683
+ type: "siwe" /* siwe */,
1684
+ provider: "wallet" /* wallet */,
1685
+ providerAccountId: input.address
1686
+ }
1687
+ ]
1688
+ });
1689
+ };
1690
+ var getBrowserAuthLocation = () => {
1691
+ if (typeof window === "undefined") {
1692
+ return {
1693
+ domain: "localhost",
1694
+ uri: "http://localhost"
1695
+ };
1696
+ }
1697
+ return {
1698
+ domain: window.location.host,
1699
+ uri: window.location.origin
1700
+ };
1701
+ };
1702
+ var resolveAuthCallbackUrl = (callbackUrl) => {
1703
+ return callbackUrl instanceof URL ? callbackUrl : typeof callbackUrl === "string" ? new URL(
1704
+ callbackUrl,
1705
+ typeof window === "undefined" ? "http://localhost" : window.location.origin
1706
+ ) : typeof window === "undefined" ? null : new URL(window.location.href);
1707
+ };
1708
+ var parseAuthCallbackCode = (callbackUrl) => {
1709
+ var _a;
1710
+ const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
1711
+ return (_a = resolvedUrl == null ? void 0 : resolvedUrl.searchParams.get("code")) != null ? _a : null;
1712
+ };
1713
+ var parseLinkConfirmToken = (callbackUrl) => {
1714
+ var _a;
1715
+ const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
1716
+ return (_a = resolvedUrl == null ? void 0 : resolvedUrl.searchParams.get("link_confirm_token")) != null ? _a : null;
1717
+ };
1718
+ var getAuthCallbackCleanupPath = (callbackUrl) => {
1719
+ const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
1720
+ if (!resolvedUrl) return null;
1721
+ const params = new URLSearchParams(resolvedUrl.search);
1722
+ params.delete("code");
1723
+ params.delete("link_confirm_token");
1724
+ const search = params.toString();
1725
+ return `${resolvedUrl.pathname}${search ? `?${search}` : ""}`;
1726
+ };
1727
+ var exchangeAuthCallbackCode = (client, callbackUrl) => __async(null, null, function* () {
1728
+ const code = parseAuthCallbackCode(callbackUrl);
1729
+ if (!code) return null;
1730
+ const result = yield client.exchangeAuthCode(code);
1731
+ return {
1732
+ cleanupPath: getAuthCallbackCleanupPath(callbackUrl),
1733
+ user: result.user
1734
+ };
1735
+ });
1736
+ var confirmLinkAccountCallback = (client, callbackUrl) => __async(null, null, function* () {
1737
+ const token = parseLinkConfirmToken(callbackUrl);
1738
+ if (!token) return null;
1739
+ yield client.linkAccountConfirm(token);
1740
+ return { cleanupPath: getAuthCallbackCleanupPath(callbackUrl) };
1741
+ });
1742
+ var parseAuthCallbackTokens = (callbackUrl) => {
1743
+ var _a, _b;
1744
+ const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
1745
+ if (!resolvedUrl) return null;
1746
+ const hash = resolvedUrl.hash.startsWith("#") ? resolvedUrl.hash.slice(1) : resolvedUrl.hash;
1747
+ if (!hash) return null;
1748
+ const params = new URLSearchParams(hash);
1749
+ const accessToken = params.get("access_token");
1750
+ const refreshToken = params.get("refresh_token");
1751
+ if (!accessToken || !refreshToken) return null;
1752
+ const userId = (_a = params.get("user_id")) != null ? _a : void 0;
1753
+ const tokenType = (_b = params.get("token_type")) != null ? _b : void 0;
1754
+ return {
1755
+ accessToken,
1756
+ refreshToken,
1757
+ tokenType,
1758
+ userId
1759
+ };
1760
+ };
1761
+ var createAuthCallbackSession = (tokens) => {
1762
+ return {
1763
+ accessToken: tokens.accessToken,
1764
+ refreshToken: tokens.refreshToken,
1765
+ user: tokens.userId ? createPlaceholderUserProfile({ id: tokens.userId }) : void 0
1766
+ };
1767
+ };
1768
+ var executeWalletAuthFlow = (input) => __async(null, null, function* () {
1769
+ var _a, _b, _c, _d;
1770
+ const address = input.options.address.trim();
1771
+ const chain = (_a = input.options.chain) != null ? _a : "ethereum";
1772
+ const provider = chain === "solana" ? "siws" : "siwe";
1773
+ const location = (_b = input.location) != null ? _b : getBrowserAuthLocation();
1774
+ const startResult = yield input.client.authStart(__spreadValues({
1775
+ provider
1776
+ }, input.options.turnstileToken ? { turnstileToken: input.options.turnstileToken } : {}));
1777
+ if (startResult.type === "challenge_required") {
1778
+ if (!startResult.siteKey) {
1779
+ throw new Error("Server returned challenge_required but no siteKey was provided.");
1780
+ }
1781
+ throw new TurnstileChallengeError(startResult.siteKey);
1782
+ }
1783
+ if (startResult.type !== "nonce") {
1784
+ throw new Error(`AGG auth start returned an unexpected "${startResult.type}" response`);
1785
+ }
1786
+ const message = chain === "solana" ? input.client.buildSiwsMessage({
1787
+ domain: location.domain,
1788
+ address,
1789
+ uri: location.uri,
1790
+ nonce: startResult.nonce,
1791
+ chainId: typeof input.options.chainId === "string" ? input.options.chainId : "mainnet",
1792
+ statement: (_c = startResult.statement) != null ? _c : input.options.statement
1793
+ }) : input.client.buildSiweMessage({
1794
+ domain: location.domain,
1795
+ // Any casing: `buildSiweMessage` applies the EIP-55 checksum itself.
1796
+ address,
1797
+ uri: location.uri,
1798
+ nonce: startResult.nonce,
1799
+ chainId: typeof input.options.chainId === "number" ? input.options.chainId : void 0,
1800
+ statement: (_d = startResult.statement) != null ? _d : input.options.statement
1801
+ });
1802
+ const signature = yield input.options.signMessage(message);
1803
+ const result = yield input.client.verify({ message, signature });
1804
+ return {
1805
+ accessToken: result.accessToken,
1806
+ refreshToken: result.refreshToken,
1807
+ user: createWalletSessionUser({
1808
+ id: result.user.id,
1809
+ address
1810
+ })
1811
+ };
1812
+ });
1594
1813
 
1595
1814
  // src/core/providers/contexts.ts
1596
1815
  import { createContext } from "react";
1597
1816
  var AggClientContext = createContext(null);
1598
1817
  var AggUiContext = createContext(defaultAggUiConfig);
1818
+ var AggExecutionModeContext = createContext(null);
1599
1819
  var AggLabelsContext = createContext(defaultAggUiConfig.general.labels);
1600
1820
  var AggAuthContext = createContext(null);
1601
1821
  var AggBalanceContext = createContext(null);
1602
1822
 
1603
- // src/core/providers/balance-provider.tsx
1823
+ // src/core/providers/auth-provider.tsx
1604
1824
  import { jsx } from "react/jsx-runtime";
1605
- var CHAIN_LABELS = {
1606
- 0: "Paper",
1607
- 1: "Ethereum",
1608
- 10: "Optimism",
1609
- 56: "BNB",
1610
- 137: "Polygon",
1611
- 1337: "Hyperliquid",
1612
- 8453: "Base",
1613
- 42161: "Arbitrum",
1614
- 43114: "Avalanche",
1615
- 11155111: "Sepolia",
1616
- 792703809: "Solana"
1617
- };
1618
- var chainLabelFromId = (chainId) => {
1825
+ var getClientAuthSnapshot = (client) => {
1619
1826
  var _a;
1620
- return (_a = CHAIN_LABELS[chainId]) != null ? _a : `Chain ${chainId}`;
1621
- };
1622
- var toTokenUnits = (raw, decimals) => {
1623
- const numeric = Number(raw);
1624
- if (!Number.isFinite(numeric)) return 0;
1625
- return numeric / __pow(10, decimals);
1827
+ return {
1828
+ isAuthenticated: (_a = client == null ? void 0 : client.isAuthenticated) != null ? _a : false,
1829
+ user: client == null ? void 0 : client.user
1830
+ };
1626
1831
  };
1627
- var isUsdBasedToken = (tokenSymbol) => {
1628
- var _a;
1629
- return (_a = tokenSymbol == null ? void 0 : tokenSymbol.toUpperCase()) == null ? void 0 : _a.includes("USD");
1832
+ var toError = (value) => {
1833
+ return value instanceof Error ? value : new Error(String(value));
1630
1834
  };
1631
- var EMPTY_MANAGED_BALANCES = {
1632
- cash: [],
1633
- positions: []
1835
+ var replaceAuthCallbackUrl = (cleanupPath) => {
1836
+ if (!cleanupPath || typeof window === "undefined") return;
1837
+ window.history.replaceState(null, "", cleanupPath);
1634
1838
  };
1635
- function AggBalanceProvider({ children }) {
1636
- var _a;
1839
+ function AggAuthProvider({ children }) {
1637
1840
  const client = useContext(AggClientContext);
1638
- const authContext = useContext(AggAuthContext);
1639
- const {
1640
- trading: { executionMode }
1641
- } = useContext(AggUiContext);
1642
- if (!authContext) {
1643
- throw new Error("AggBalanceProvider must be used within an <AggAuthProvider>");
1644
- }
1645
- const { isAuthenticated } = authContext;
1646
- const queryExecutionMode = executionMode === "paper" ? "paper" : void 0;
1647
- const balancesQuery = useQuery({
1648
- queryKey: balanceQueryKeys.provider(queryExecutionMode),
1649
- queryFn: () => __async(null, null, function* () {
1650
- if (!client || !isAuthenticated) {
1651
- return EMPTY_MANAGED_BALANCES;
1652
- }
1653
- return client.getManagedBalances(
1654
- queryExecutionMode ? { mode: queryExecutionMode } : void 0
1655
- );
1841
+ const queryClientFromContext = useContext(QueryClientContext);
1842
+ const fallbackQueryClient = useMemo(() => new QueryClient(), []);
1843
+ const queryClient = queryClientFromContext && "fetchQuery" in queryClientFromContext ? queryClientFromContext : fallbackQueryClient;
1844
+ const snapshot = getClientAuthSnapshot(client);
1845
+ const [isAuthenticated, setIsAuthenticated] = useState(snapshot.isAuthenticated);
1846
+ const [user, setUser] = useState(snapshot.user);
1847
+ const [isLoading, setIsLoading] = useState(false);
1848
+ const [error, setError] = useState(null);
1849
+ const isWeb3User = useMemo(() => {
1850
+ const accounts = user == null ? void 0 : user.accounts;
1851
+ if (!Array.isArray(accounts)) return true;
1852
+ return accounts.some((account) => {
1853
+ var _a;
1854
+ const provider = String((_a = account.provider) != null ? _a : "").toLowerCase();
1855
+ return provider === "wallet" || provider === "solana_wallet";
1856
+ });
1857
+ }, [user]);
1858
+ const refreshCurrentUser = useCallback(
1859
+ (targetClient) => __async(null, null, function* () {
1860
+ const fullUser = yield fetchCurrentUserProfile(queryClient, targetClient);
1861
+ setIsAuthenticated(true);
1862
+ setUser(fullUser);
1863
+ return fullUser;
1656
1864
  }),
1657
- enabled: Boolean(client && isAuthenticated),
1658
- staleTime: 60 * 1e3,
1659
- refetchOnWindowFocus: "always",
1660
- refetchOnReconnect: "always"
1661
- });
1662
- const managedBalancesData = balancesQuery.data;
1663
- const managedBalances = useMemo(
1664
- () => managedBalancesData != null ? managedBalancesData : EMPTY_MANAGED_BALANCES,
1665
- [managedBalancesData]
1865
+ [queryClient]
1666
1866
  );
1667
- const connectedVenues = useMemo(() => {
1668
- return Array.from(new Set(managedBalances.positions.map((position) => position.venue))).sort(
1867
+ useEffect(() => {
1868
+ const state = getClientAuthSnapshot(client);
1869
+ setIsAuthenticated(state.isAuthenticated);
1870
+ setUser(state.user);
1871
+ setIsLoading(false);
1872
+ setError(null);
1873
+ if (!client) return;
1874
+ if (state.isAuthenticated) {
1875
+ refreshCurrentUser(client).catch(() => {
1876
+ client.clearAccessToken();
1877
+ });
1878
+ } else if (client.authStatus === "unknown") {
1879
+ client.refreshAccessToken().then(() => refreshCurrentUser(client)).catch(() => {
1880
+ client.clearAccessToken();
1881
+ });
1882
+ }
1883
+ }, [client, refreshCurrentUser]);
1884
+ useEffect(() => {
1885
+ if (!client) return;
1886
+ return client.onAuthStateChange((authenticated) => {
1887
+ setIsAuthenticated(authenticated);
1888
+ setUser(client.user);
1889
+ if (!authenticated) {
1890
+ setIsLoading(false);
1891
+ setError(null);
1892
+ }
1893
+ });
1894
+ }, [client]);
1895
+ const signIn = useCallback(
1896
+ (options) => __async(null, null, function* () {
1897
+ if (!client) {
1898
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
1899
+ setError(missingClientError);
1900
+ throw missingClientError;
1901
+ }
1902
+ const address = options.address.trim();
1903
+ if (!address) {
1904
+ const missingAddressError = new Error("Wallet address is required");
1905
+ setError(missingAddressError);
1906
+ throw missingAddressError;
1907
+ }
1908
+ setIsLoading(true);
1909
+ setError(null);
1910
+ try {
1911
+ const result = yield executeWalletAuthFlow({
1912
+ client,
1913
+ options: __spreadProps(__spreadValues({}, options), {
1914
+ address
1915
+ })
1916
+ });
1917
+ client.setSession(result);
1918
+ setIsAuthenticated(true);
1919
+ setUser(result.user);
1920
+ yield refreshCurrentUser(client);
1921
+ } catch (signInError) {
1922
+ const resolvedError = toError(signInError);
1923
+ setError(resolvedError);
1924
+ throw resolvedError;
1925
+ } finally {
1926
+ setIsLoading(false);
1927
+ }
1928
+ }),
1929
+ [client, refreshCurrentUser]
1930
+ );
1931
+ const startAuth = useCallback(
1932
+ (options) => __async(null, null, function* () {
1933
+ if (!client) {
1934
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
1935
+ setError(missingClientError);
1936
+ throw missingClientError;
1937
+ }
1938
+ setIsLoading(true);
1939
+ setError(null);
1940
+ try {
1941
+ return yield client.authStart(options);
1942
+ } catch (startAuthError) {
1943
+ const resolvedError = toError(startAuthError);
1944
+ setError(resolvedError);
1945
+ throw resolvedError;
1946
+ } finally {
1947
+ setIsLoading(false);
1948
+ }
1949
+ }),
1950
+ [client]
1951
+ );
1952
+ const setSession = useCallback(
1953
+ (session) => __async(null, null, function* () {
1954
+ if (!client) {
1955
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
1956
+ setError(missingClientError);
1957
+ throw missingClientError;
1958
+ }
1959
+ setIsLoading(true);
1960
+ setError(null);
1961
+ try {
1962
+ client.setSession(session);
1963
+ const resolvedUser = yield refreshCurrentUser(client);
1964
+ setIsAuthenticated(true);
1965
+ setUser(resolvedUser);
1966
+ return resolvedUser;
1967
+ } catch (sessionError) {
1968
+ client.clearAccessToken();
1969
+ setIsAuthenticated(false);
1970
+ setUser(void 0);
1971
+ const resolvedError = toError(sessionError);
1972
+ setError(resolvedError);
1973
+ throw resolvedError;
1974
+ } finally {
1975
+ setIsLoading(false);
1976
+ }
1977
+ }),
1978
+ [client, refreshCurrentUser]
1979
+ );
1980
+ const handleAuthCallback = useCallback(
1981
+ (callbackUrl) => __async(null, null, function* () {
1982
+ if (!client) {
1983
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
1984
+ setError(missingClientError);
1985
+ throw missingClientError;
1986
+ }
1987
+ setIsLoading(true);
1988
+ setError(null);
1989
+ try {
1990
+ const exchangedSession = yield exchangeAuthCallbackCode(client, callbackUrl);
1991
+ if (exchangedSession) {
1992
+ const resolvedUser2 = yield refreshCurrentUser(client);
1993
+ if (callbackUrl === void 0) {
1994
+ replaceAuthCallbackUrl(exchangedSession.cleanupPath);
1995
+ }
1996
+ return resolvedUser2;
1997
+ }
1998
+ const confirmedLink = yield confirmLinkAccountCallback(client, callbackUrl);
1999
+ if (confirmedLink) {
2000
+ const resolvedUser2 = yield refreshCurrentUser(client);
2001
+ if (callbackUrl === void 0) {
2002
+ replaceAuthCallbackUrl(confirmedLink.cleanupPath);
2003
+ }
2004
+ return resolvedUser2;
2005
+ }
2006
+ const tokens = parseAuthCallbackTokens(callbackUrl);
2007
+ if (!tokens) return null;
2008
+ client.setSession(createAuthCallbackSession(tokens));
2009
+ setIsAuthenticated(client.isAuthenticated);
2010
+ setUser(client.user);
2011
+ const resolvedUser = yield refreshCurrentUser(client);
2012
+ if (callbackUrl === void 0) {
2013
+ replaceAuthCallbackUrl(getAuthCallbackCleanupPath(callbackUrl));
2014
+ }
2015
+ return resolvedUser;
2016
+ } catch (callbackError) {
2017
+ const resolvedError = toError(callbackError);
2018
+ setError(resolvedError);
2019
+ throw resolvedError;
2020
+ } finally {
2021
+ setIsLoading(false);
2022
+ }
2023
+ }),
2024
+ [client, refreshCurrentUser]
2025
+ );
2026
+ const signOut = useCallback(() => __async(null, null, function* () {
2027
+ yield client == null ? void 0 : client.signOut();
2028
+ setIsAuthenticated(false);
2029
+ setUser(void 0);
2030
+ setError(null);
2031
+ }), [client]);
2032
+ const clearError = useCallback(() => {
2033
+ setError(null);
2034
+ }, []);
2035
+ const value = useMemo(() => {
2036
+ return {
2037
+ isAuthenticated,
2038
+ isWeb3User,
2039
+ user,
2040
+ isLoading,
2041
+ error,
2042
+ signIn,
2043
+ startAuth,
2044
+ setSession,
2045
+ handleAuthCallback,
2046
+ signOut,
2047
+ clearError
2048
+ };
2049
+ }, [
2050
+ clearError,
2051
+ error,
2052
+ handleAuthCallback,
2053
+ isAuthenticated,
2054
+ isWeb3User,
2055
+ isLoading,
2056
+ setSession,
2057
+ signIn,
2058
+ signOut,
2059
+ startAuth,
2060
+ user
2061
+ ]);
2062
+ return /* @__PURE__ */ jsx(AggAuthContext.Provider, { value, children });
2063
+ }
2064
+
2065
+ // src/core/providers/balance-provider.tsx
2066
+ import { useQuery } from "@tanstack/react-query";
2067
+ import { useCallback as useCallback2, useContext as useContext2, useMemo as useMemo2 } from "react";
2068
+ import { jsx as jsx2 } from "react/jsx-runtime";
2069
+ var CHAIN_LABELS = {
2070
+ 0: "Paper",
2071
+ 1: "Ethereum",
2072
+ 10: "Optimism",
2073
+ 56: "BNB",
2074
+ 137: "Polygon",
2075
+ 1337: "Hyperliquid",
2076
+ 8453: "Base",
2077
+ 42161: "Arbitrum",
2078
+ 43114: "Avalanche",
2079
+ 11155111: "Sepolia",
2080
+ 792703809: "Solana"
2081
+ };
2082
+ var chainLabelFromId = (chainId) => {
2083
+ var _a;
2084
+ return (_a = CHAIN_LABELS[chainId]) != null ? _a : `Chain ${chainId}`;
2085
+ };
2086
+ var toTokenUnits = (raw, decimals) => {
2087
+ const numeric = Number(raw);
2088
+ if (!Number.isFinite(numeric)) return 0;
2089
+ return numeric / __pow(10, decimals);
2090
+ };
2091
+ var isUsdBasedToken = (tokenSymbol) => {
2092
+ var _a;
2093
+ return (_a = tokenSymbol == null ? void 0 : tokenSymbol.toUpperCase()) == null ? void 0 : _a.includes("USD");
2094
+ };
2095
+ var EMPTY_MANAGED_BALANCES = {
2096
+ cash: [],
2097
+ positions: []
2098
+ };
2099
+ function AggBalanceProvider({ children }) {
2100
+ var _a;
2101
+ const client = useContext2(AggClientContext);
2102
+ const authContext = useContext2(AggAuthContext);
2103
+ const { executionMode } = useResolvedExecutionMode();
2104
+ if (!authContext) {
2105
+ throw new Error("AggBalanceProvider must be used within an <AggAuthProvider>");
2106
+ }
2107
+ const { isAuthenticated } = authContext;
2108
+ const queryExecutionMode = executionMode === "paper" ? "paper" : void 0;
2109
+ const balancesQuery = useQuery({
2110
+ queryKey: balanceQueryKeys.provider(queryExecutionMode),
2111
+ queryFn: () => __async(null, null, function* () {
2112
+ if (!client || !isAuthenticated) {
2113
+ return EMPTY_MANAGED_BALANCES;
2114
+ }
2115
+ return client.getManagedBalances(
2116
+ queryExecutionMode ? { mode: queryExecutionMode } : void 0
2117
+ );
2118
+ }),
2119
+ enabled: Boolean(client && isAuthenticated),
2120
+ staleTime: 60 * 1e3,
2121
+ // A matched fill can precede settlement and the API's next balance snapshot.
2122
+ // Keep visible clients converging even if that first invalidation reads old cash.
2123
+ refetchInterval: queryExecutionMode === "paper" ? false : 5e3,
2124
+ refetchIntervalInBackground: false,
2125
+ refetchOnWindowFocus: "always",
2126
+ refetchOnReconnect: "always"
2127
+ });
2128
+ const managedBalancesData = balancesQuery.data;
2129
+ const managedBalances = useMemo2(
2130
+ () => managedBalancesData != null ? managedBalancesData : EMPTY_MANAGED_BALANCES,
2131
+ [managedBalancesData]
2132
+ );
2133
+ const connectedVenues = useMemo2(() => {
2134
+ return Array.from(new Set(managedBalances.positions.map((position) => position.venue))).sort(
1669
2135
  (a, b) => a.localeCompare(b)
1670
2136
  );
1671
2137
  }, [managedBalances.positions]);
1672
2138
  const balancesError = managedBalancesData === void 0 ? balancesQuery.error : null;
1673
2139
  const isBalancesLoading = balancesQuery.isLoading;
1674
2140
  const refetchBalances = balancesQuery.refetch;
1675
- const totalBalance = useMemo(() => {
2141
+ const totalBalance = useMemo2(() => {
1676
2142
  const cash = managedBalances.cash;
1677
2143
  return cash.reduce((sum, token) => {
1678
2144
  if (!isUsdBasedToken(token.tokenSymbol)) return sum;
@@ -1686,7 +2152,7 @@ function AggBalanceProvider({ children }) {
1686
2152
  return sum + tokenAcrossChains;
1687
2153
  }, 0);
1688
2154
  }, [managedBalances]);
1689
- const availableBalance = useMemo(() => {
2155
+ const availableBalance = useMemo2(() => {
1690
2156
  return managedBalances.cash.reduce((sum, token) => {
1691
2157
  if (!isUsdBasedToken(token.tokenSymbol)) return sum;
1692
2158
  if (token.availableRaw != null) {
@@ -1701,7 +2167,7 @@ function AggBalanceProvider({ children }) {
1701
2167
  );
1702
2168
  }, 0);
1703
2169
  }, [managedBalances]);
1704
- const reservedBalance = useMemo(() => {
2170
+ const reservedBalance = useMemo2(() => {
1705
2171
  return managedBalances.cash.reduce((sum, token) => {
1706
2172
  if (!isUsdBasedToken(token.tokenSymbol)) return sum;
1707
2173
  if (token.reservedRaw != null) {
@@ -1716,7 +2182,7 @@ function AggBalanceProvider({ children }) {
1716
2182
  );
1717
2183
  }, 0);
1718
2184
  }, [managedBalances]);
1719
- const buildBalanceBreakdown = useCallback(
2185
+ const buildBalanceBreakdown = useCallback2(
1720
2186
  (rawForChain) => {
1721
2187
  var _a2, _b;
1722
2188
  const byChain = /* @__PURE__ */ new Map();
@@ -1744,16 +2210,16 @@ function AggBalanceProvider({ children }) {
1744
2210
  },
1745
2211
  [connectedVenues, managedBalances.cash]
1746
2212
  );
1747
- const balanceBreakdown = useMemo(() => {
2213
+ const balanceBreakdown = useMemo2(() => {
1748
2214
  return buildBalanceBreakdown((chain) => chain.balanceRaw);
1749
2215
  }, [buildBalanceBreakdown]);
1750
- const availableBalanceBreakdown = useMemo(() => {
2216
+ const availableBalanceBreakdown = useMemo2(() => {
1751
2217
  return buildBalanceBreakdown((chain) => {
1752
2218
  var _a2;
1753
2219
  return (_a2 = chain.availableRaw) != null ? _a2 : chain.balanceRaw;
1754
2220
  });
1755
2221
  }, [buildBalanceBreakdown]);
1756
- const positionsBalanceTotal = useMemo(() => {
2222
+ const positionsBalanceTotal = useMemo2(() => {
1757
2223
  const positions = managedBalances.positions;
1758
2224
  const actualPositionsBalance = positions.reduce(
1759
2225
  (sum, position) => sum + (Number.isFinite(position.balance) ? position.balance : 0),
@@ -1764,15 +2230,15 @@ function AggBalanceProvider({ children }) {
1764
2230
  const kalshiVenueCash = (_a = managedBalances.venueCash) == null ? void 0 : _a.find((item) => item.venue === "kalshi");
1765
2231
  const kalshiBalance = kalshiVenueCash ? kalshiVenueCash.balanceCents / 100 : null;
1766
2232
  const kalshiPortfolioValue = (kalshiVenueCash == null ? void 0 : kalshiVenueCash.portfolioValueCents) == null ? null : kalshiVenueCash.portfolioValueCents / 100;
1767
- const refetch = useCallback(() => {
2233
+ const refetch = useCallback2(() => {
1768
2234
  if (!isAuthenticated) return;
1769
2235
  void refetchBalances();
1770
2236
  }, [isAuthenticated, refetchBalances]);
1771
- const refetchConnectionStatus = useCallback(() => {
2237
+ const refetchConnectionStatus = useCallback2(() => {
1772
2238
  if (!client || !isAuthenticated) return;
1773
2239
  void client.getCurrentUser();
1774
2240
  }, [client, isAuthenticated]);
1775
- const value = useMemo(() => {
2241
+ const value = useMemo2(() => {
1776
2242
  if (!isAuthenticated) {
1777
2243
  return {
1778
2244
  managedBalances,
@@ -1828,24 +2294,96 @@ function AggBalanceProvider({ children }) {
1828
2294
  reservedBalance,
1829
2295
  totalBalance
1830
2296
  ]);
1831
- return /* @__PURE__ */ jsx(AggBalanceContext.Provider, { value, children });
2297
+ return /* @__PURE__ */ jsx2(AggBalanceContext.Provider, { value, children });
1832
2298
  }
1833
2299
 
1834
- // src/core/providers/event-list-state-context.tsx
1835
- import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useRef } from "react";
1836
- import { jsx as jsx2 } from "react/jsx-runtime";
1837
- var STALENESS_THRESHOLD_MS = 5 * 60 * 1e3;
1838
- var MAX_INITIAL_PAGES = 10;
2300
+ // src/core/providers/client-provider.tsx
2301
+ import { jsx as jsx3 } from "react/jsx-runtime";
2302
+ function AggClientProvider({ client, children }) {
2303
+ return /* @__PURE__ */ jsx3(AggClientContext.Provider, { value: client != null ? client : null, children });
2304
+ }
2305
+
2306
+ // src/core/providers/execution-mode-provider.tsx
2307
+ import { useMemo as useMemo3 } from "react";
2308
+
2309
+ // src/use-app-config.ts
2310
+ import { useQuery as useQuery2, useQueryClient } from "@tanstack/react-query";
2311
+ var FIVE_MINUTES = 5 * 60 * 1e3;
2312
+ var NO_APP_SCOPE = "__no-app__";
2313
+ var appConfigQueryKey = (appId) => ["agg", "app-config", appId != null ? appId : NO_APP_SCOPE];
2314
+ function useAppConfig() {
2315
+ const client = useAggClient();
2316
+ const query = useQuery2({
2317
+ queryKey: appConfigQueryKey(client.appId),
2318
+ queryFn: () => client.getAppConfig(),
2319
+ staleTime: FIVE_MINUTES,
2320
+ // Skipped entirely while the tab is unfocused — query-core only fires the
2321
+ // interval when `refetchIntervalInBackground` is set or the window is
2322
+ // focused — so a background tab costs nothing.
2323
+ refetchInterval: FIVE_MINUTES
2324
+ });
2325
+ return toAppConfigResult({
2326
+ data: query.data,
2327
+ isLoading: query.isLoading,
2328
+ error: query.error
2329
+ });
2330
+ }
2331
+ function useCachedAppConfig() {
2332
+ const queryClient = useQueryClient();
2333
+ const client = useOptionalAggClient();
2334
+ const queryKey = appConfigQueryKey(client == null ? void 0 : client.appId);
2335
+ const query = useQuery2({
2336
+ queryKey,
2337
+ enabled: false,
2338
+ initialData: () => queryClient.getQueryData(queryKey),
2339
+ staleTime: FIVE_MINUTES
2340
+ });
2341
+ return toAppConfigResult({
2342
+ data: query.data,
2343
+ isLoading: query.isLoading,
2344
+ error: query.error
2345
+ });
2346
+ }
2347
+ var toAppConfigResult = (query) => {
2348
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2349
+ return {
2350
+ disabledVenues: (_b = (_a = query.data) == null ? void 0 : _a.disabledVenues) != null ? _b : [],
2351
+ disabledCategoryPresets: (_d = (_c = query.data) == null ? void 0 : _c.disabledCategoryPresets) != null ? _d : [],
2352
+ earlyAccessEnabled: (_f = (_e = query.data) == null ? void 0 : _e.earlyAccessEnabled) != null ? _f : false,
2353
+ authOptions: (_h = (_g = query.data) == null ? void 0 : _g.authOptions) != null ? _h : [],
2354
+ tradingMode: (_i = query.data) == null ? void 0 : _i.tradingMode,
2355
+ paperStartingBalance: (_j = query.data) == null ? void 0 : _j.paperStartingBalance,
2356
+ isLoading: query.isLoading,
2357
+ error: query.error
2358
+ };
2359
+ };
2360
+
2361
+ // src/core/providers/execution-mode-provider.tsx
2362
+ import { jsx as jsx4 } from "react/jsx-runtime";
2363
+ function AggExecutionModeProvider({ children }) {
2364
+ const { tradingMode, paperStartingBalance, isLoading } = useAppConfig();
2365
+ const value = useMemo3(
2366
+ () => ({ tradingMode, paperStartingBalance, isLoading }),
2367
+ [tradingMode, paperStartingBalance, isLoading]
2368
+ );
2369
+ return /* @__PURE__ */ jsx4(AggExecutionModeContext.Provider, { value, children });
2370
+ }
2371
+
2372
+ // src/core/providers/event-list-state-context.tsx
2373
+ import { createContext as createContext2, useCallback as useCallback3, useContext as useContext3, useRef } from "react";
2374
+ import { jsx as jsx5 } from "react/jsx-runtime";
2375
+ var STALENESS_THRESHOLD_MS = 5 * 60 * 1e3;
2376
+ var MAX_INITIAL_PAGES = 10;
1839
2377
  var EventListStateContext = createContext2(null);
1840
2378
  function EventListStateProvider({ children }) {
1841
2379
  const snapshotRef = useRef(null);
1842
- const capture = useCallback2((state) => {
2380
+ const capture = useCallback3((state) => {
1843
2381
  snapshotRef.current = __spreadProps(__spreadValues({}, state), {
1844
2382
  loadedPageCount: Math.min(state.loadedPageCount, MAX_INITIAL_PAGES),
1845
2383
  capturedAt: Date.now()
1846
2384
  });
1847
2385
  }, []);
1848
- const consume = useCallback2(() => {
2386
+ const consume = useCallback3(() => {
1849
2387
  const snapshot = snapshotRef.current;
1850
2388
  snapshotRef.current = null;
1851
2389
  if (!snapshot) return null;
@@ -1860,66 +2398,27 @@ function EventListStateProvider({ children }) {
1860
2398
  capture: (...args) => value.current.capture(...args),
1861
2399
  consume: () => value.current.consume()
1862
2400
  }).current;
1863
- return /* @__PURE__ */ jsx2(EventListStateContext.Provider, { value: stableValue, children });
2401
+ return /* @__PURE__ */ jsx5(EventListStateContext.Provider, { value: stableValue, children });
1864
2402
  }
1865
2403
  function useEventListState() {
1866
- const context = useContext2(EventListStateContext);
2404
+ const context = useContext3(EventListStateContext);
1867
2405
  if (!context) {
1868
2406
  throw new Error("useEventListState must be used within an <AggProvider>");
1869
2407
  }
1870
2408
  return context;
1871
2409
  }
1872
2410
 
1873
- // src/core/providers/hooks.ts
1874
- import { useContext as useContext3 } from "react";
1875
- var useAggClient = () => {
1876
- const client = useContext3(AggClientContext);
1877
- if (!client) {
1878
- throw new Error("useAggClient must be used within an <AggProvider>");
1879
- }
1880
- return client;
1881
- };
1882
- var useOptionalAggClient = () => {
1883
- return useContext3(AggClientContext);
1884
- };
1885
- var useAggUiConfig = () => {
1886
- return useContext3(AggUiContext);
1887
- };
1888
- var useAggLabels = () => {
1889
- return useContext3(AggLabelsContext);
1890
- };
1891
- var useAggAuthContext = () => {
1892
- const context = useContext3(AggAuthContext);
1893
- if (!context) {
1894
- throw new Error("useAggAuthContext must be used within an <AggProvider>");
1895
- }
1896
- return context;
1897
- };
1898
- var useAggAuthState = useAggAuthContext;
1899
- var useAggBalanceContext = () => {
1900
- const context = useContext3(AggBalanceContext);
1901
- if (!context) {
1902
- throw new Error("useAggBalanceContext must be used within an <AggProvider>");
1903
- }
1904
- return context;
1905
- };
1906
- var useAggBalanceState = useAggBalanceContext;
1907
- var useAggBalance = useAggBalanceContext;
1908
- var useSdkUiConfig = useAggUiConfig;
1909
- var useSdkLabels = useAggLabels;
1910
- var useLabels = useAggLabels;
1911
-
1912
2411
  // src/core/providers/ws-provider.tsx
1913
2412
  import {
1914
2413
  createContext as createContext3,
1915
- useCallback as useCallback3,
1916
- useContext as useContext4,
1917
- useEffect,
1918
- useMemo as useMemo2,
2414
+ useCallback as useCallback4,
2415
+ useContext as useContext5,
2416
+ useEffect as useEffect2,
2417
+ useMemo as useMemo4,
1919
2418
  useRef as useRef2,
1920
- useState
2419
+ useState as useState2
1921
2420
  } from "react";
1922
- import { useQueryClient } from "@tanstack/react-query";
2421
+ import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
1923
2422
 
1924
2423
  // src/market-data/chart-cache.ts
1925
2424
  var MAX_CACHE_RETENTION_SECONDS = 7 * 30 * 24 * 60 * 60 + 14 * 24 * 60 * 60;
@@ -2460,8 +2959,47 @@ var marketDataKeys = {
2460
2959
  }
2461
2960
  };
2462
2961
 
2962
+ // src/core/providers/hooks.ts
2963
+ import { useContext as useContext4 } from "react";
2964
+ var useAggClient = () => {
2965
+ const client = useContext4(AggClientContext);
2966
+ if (!client) {
2967
+ throw new Error("useAggClient must be used within an <AggProvider>");
2968
+ }
2969
+ return client;
2970
+ };
2971
+ var useOptionalAggClient = () => {
2972
+ return useContext4(AggClientContext);
2973
+ };
2974
+ var useAggUiConfig = () => {
2975
+ return useContext4(AggUiContext);
2976
+ };
2977
+ var useAggLabels = () => {
2978
+ return useContext4(AggLabelsContext);
2979
+ };
2980
+ var useAggAuthContext = () => {
2981
+ const context = useContext4(AggAuthContext);
2982
+ if (!context) {
2983
+ throw new Error("useAggAuthContext must be used within an <AggProvider>");
2984
+ }
2985
+ return context;
2986
+ };
2987
+ var useAggAuthState = useAggAuthContext;
2988
+ var useAggBalanceContext = () => {
2989
+ const context = useContext4(AggBalanceContext);
2990
+ if (!context) {
2991
+ throw new Error("useAggBalanceContext must be used within an <AggProvider>");
2992
+ }
2993
+ return context;
2994
+ };
2995
+ var useAggBalanceState = useAggBalanceContext;
2996
+ var useAggBalance = useAggBalanceContext;
2997
+ var useSdkUiConfig = useAggUiConfig;
2998
+ var useSdkLabels = useAggLabels;
2999
+ var useLabels = useAggLabels;
3000
+
2463
3001
  // src/core/providers/ws-provider.tsx
2464
- import { jsx as jsx3 } from "react/jsx-runtime";
3002
+ import { jsx as jsx6 } from "react/jsx-runtime";
2465
3003
  var AggWebSocketContext = createContext3(null);
2466
3004
  var AggWebSocketConnectionContext = createContext3(false);
2467
3005
  var AggWsUserEventContext = createContext3(null);
@@ -2481,17 +3019,17 @@ var debugOrderbook = (enabled, event, payload) => {
2481
3019
  console.debug(`[AggHooks][ws-provider] ${event}`, payload);
2482
3020
  };
2483
3021
  function useAggWebSocket() {
2484
- return useContext4(AggWebSocketContext);
3022
+ return useContext5(AggWebSocketContext);
2485
3023
  }
2486
3024
  function useAggWebSocketConnectionState() {
2487
- return useContext4(AggWebSocketConnectionContext);
3025
+ return useContext5(AggWebSocketConnectionContext);
2488
3026
  }
2489
3027
  function useOnOrderSubmitted(callback) {
2490
- const listeners = useContext4(AggWsUserEventContext);
3028
+ const listeners = useContext5(AggWsUserEventContext);
2491
3029
  const callbackRef = useRef2(callback);
2492
3030
  callbackRef.current = callback;
2493
3031
  const hasCallback = callback !== null;
2494
- useEffect(() => {
3032
+ useEffect2(() => {
2495
3033
  if (!listeners || !callbackRef.current) return;
2496
3034
  const handler = (msg) => {
2497
3035
  var _a;
@@ -2501,11 +3039,11 @@ function useOnOrderSubmitted(callback) {
2501
3039
  }, [listeners, hasCallback]);
2502
3040
  }
2503
3041
  function useOnBalanceUpdate(callback) {
2504
- const listeners = useContext4(AggWsUserEventContext);
3042
+ const listeners = useContext5(AggWsUserEventContext);
2505
3043
  const callbackRef = useRef2(callback);
2506
3044
  callbackRef.current = callback;
2507
3045
  const hasCallback = callback !== null;
2508
- useEffect(() => {
3046
+ useEffect2(() => {
2509
3047
  if (!listeners || !callbackRef.current) return;
2510
3048
  const handler = (msg) => {
2511
3049
  var _a;
@@ -2515,11 +3053,11 @@ function useOnBalanceUpdate(callback) {
2515
3053
  }, [listeners, hasCallback]);
2516
3054
  }
2517
3055
  function useOnOrderEvent(callback) {
2518
- const listeners = useContext4(AggWsUserEventContext);
3056
+ const listeners = useContext5(AggWsUserEventContext);
2519
3057
  const callbackRef = useRef2(callback);
2520
3058
  callbackRef.current = callback;
2521
3059
  const hasCallback = callback !== null;
2522
- useEffect(() => {
3060
+ useEffect2(() => {
2523
3061
  if (!listeners || !callbackRef.current) return;
2524
3062
  const handler = (msg) => {
2525
3063
  var _a;
@@ -2529,11 +3067,11 @@ function useOnOrderEvent(callback) {
2529
3067
  }, [listeners, hasCallback]);
2530
3068
  }
2531
3069
  function useOnRedeemEvent(callback) {
2532
- const listeners = useContext4(AggWsUserEventContext);
3070
+ const listeners = useContext5(AggWsUserEventContext);
2533
3071
  const callbackRef = useRef2(callback);
2534
3072
  callbackRef.current = callback;
2535
3073
  const hasCallback = callback !== null;
2536
- useEffect(() => {
3074
+ useEffect2(() => {
2537
3075
  if (!listeners || !callbackRef.current) return;
2538
3076
  const handler = (msg) => {
2539
3077
  var _a;
@@ -2543,11 +3081,11 @@ function useOnRedeemEvent(callback) {
2543
3081
  }, [listeners, hasCallback]);
2544
3082
  }
2545
3083
  function useOnWithdrawalLifecycle(callback) {
2546
- const listeners = useContext4(AggWsUserEventContext);
3084
+ const listeners = useContext5(AggWsUserEventContext);
2547
3085
  const callbackRef = useRef2(callback);
2548
3086
  callbackRef.current = callback;
2549
3087
  const hasCallback = callback !== null;
2550
- useEffect(() => {
3088
+ useEffect2(() => {
2551
3089
  if (!listeners || !callbackRef.current) return;
2552
3090
  const handler = (msg) => {
2553
3091
  var _a;
@@ -2559,14 +3097,14 @@ function useOnWithdrawalLifecycle(callback) {
2559
3097
  function AggWebSocketProvider({ children }) {
2560
3098
  const client = useAggClient();
2561
3099
  const { enableWebsocketsLogs } = useAggUiConfig();
2562
- const queryClient = useQueryClient();
2563
- const [ws, setWs] = useState(null);
2564
- const [isConnected, setIsConnected] = useState(false);
2565
- const [isClientAuthenticated, setIsClientAuthenticated] = useState(client.isAuthenticated);
3100
+ const queryClient = useQueryClient2();
3101
+ const [ws, setWs] = useState2(null);
3102
+ const [isConnected, setIsConnected] = useState2(false);
3103
+ const [isClientAuthenticated, setIsClientAuthenticated] = useState2(client.isAuthenticated);
2566
3104
  const wsRef = useRef2(null);
2567
3105
  const resyncDeadlineByMarketRef = useRef2(/* @__PURE__ */ new Map());
2568
3106
  const lastBalanceInvalidationAtRef = useRef2(0);
2569
- useEffect(() => {
3107
+ useEffect2(() => {
2570
3108
  setIsClientAuthenticated(client.isAuthenticated);
2571
3109
  return client.onAuthStateChange((authenticated) => {
2572
3110
  setIsClientAuthenticated(authenticated);
@@ -2579,7 +3117,7 @@ function AggWebSocketProvider({ children }) {
2579
3117
  const withdrawalLifecycleListenersRef = useRef2(
2580
3118
  /* @__PURE__ */ new Set()
2581
3119
  );
2582
- const userEventListeners = useMemo2(
3120
+ const userEventListeners = useMemo4(
2583
3121
  () => ({
2584
3122
  addOrderSubmittedListener: (cb) => {
2585
3123
  orderSubmittedListenersRef.current.add(cb);
@@ -2614,7 +3152,7 @@ function AggWebSocketProvider({ children }) {
2614
3152
  }),
2615
3153
  []
2616
3154
  );
2617
- const syncOrderbookQueries = useCallback3(
3155
+ const syncOrderbookQueries = useCallback4(
2618
3156
  (marketId, updater) => {
2619
3157
  var _a;
2620
3158
  const queries = queryClient.getQueryCache().findAll({
@@ -2630,7 +3168,7 @@ function AggWebSocketProvider({ children }) {
2630
3168
  },
2631
3169
  [queryClient]
2632
3170
  );
2633
- const syncChartQueries = useCallback3(
3171
+ const syncChartQueries = useCallback4(
2634
3172
  (marketId, updater) => {
2635
3173
  const queries = queryClient.getQueryCache().findAll({
2636
3174
  queryKey: marketDataKeys.chartPrefix(marketId)
@@ -2644,7 +3182,7 @@ function AggWebSocketProvider({ children }) {
2644
3182
  },
2645
3183
  [queryClient]
2646
3184
  );
2647
- const syncLiveQuery = useCallback3(
3185
+ const syncLiveQuery = useCallback4(
2648
3186
  (marketId, updater) => {
2649
3187
  queryClient.setQueryData(marketDataKeys.live(marketId), (previous) => {
2650
3188
  return updater(previous);
@@ -2652,19 +3190,19 @@ function AggWebSocketProvider({ children }) {
2652
3190
  },
2653
3191
  [queryClient]
2654
3192
  );
2655
- const invalidateBalanceCaches = useCallback3(() => {
3193
+ const invalidateBalanceCaches = useCallback4(() => {
2656
3194
  const now = Date.now();
2657
3195
  if (now - lastBalanceInvalidationAtRef.current < 750) return;
2658
3196
  lastBalanceInvalidationAtRef.current = now;
2659
3197
  invalidateBalanceQueries(queryClient);
2660
3198
  }, [queryClient]);
2661
- const invalidatePositionCaches = useCallback3(() => {
3199
+ const invalidatePositionCaches = useCallback4(() => {
2662
3200
  invalidatePositionQueries(queryClient);
2663
3201
  }, [queryClient]);
2664
- const invalidateActivityCaches = useCallback3(() => {
3202
+ const invalidateActivityCaches = useCallback4(() => {
2665
3203
  invalidateUserActivityQueries(queryClient);
2666
3204
  }, [queryClient]);
2667
- const invalidateResolutionCaches = useCallback3(
3205
+ const invalidateResolutionCaches = useCallback4(
2668
3206
  (resolution) => {
2669
3207
  const { outcomeId } = resolution;
2670
3208
  syncLiveQuery(outcomeId, (previous) => {
@@ -2720,7 +3258,7 @@ function AggWebSocketProvider({ children }) {
2720
3258
  },
2721
3259
  [queryClient, syncLiveQuery]
2722
3260
  );
2723
- const callbacks = useMemo2(
3261
+ const callbacks = useMemo4(
2724
3262
  () => ({
2725
3263
  onSnapshot: (marketId, book) => {
2726
3264
  const orderbook = createMarketOrderbookDataFromState(book);
@@ -2921,7 +3459,7 @@ function AggWebSocketProvider({ children }) {
2921
3459
  syncOrderbookQueries
2922
3460
  ]
2923
3461
  );
2924
- useEffect(() => {
3462
+ useEffect2(() => {
2925
3463
  let instance = null;
2926
3464
  const resyncDeadlineByMarket = resyncDeadlineByMarketRef.current;
2927
3465
  try {
@@ -2947,16 +3485,89 @@ function AggWebSocketProvider({ children }) {
2947
3485
  setIsConnected(false);
2948
3486
  };
2949
3487
  }, [callbacks, client, enableWebsocketsLogs, isClientAuthenticated]);
2950
- return /* @__PURE__ */ jsx3(AggWebSocketConnectionContext.Provider, { value: isConnected, children: /* @__PURE__ */ jsx3(AggWsUserEventContext.Provider, { value: userEventListeners, children: /* @__PURE__ */ jsx3(AggWebSocketContext.Provider, { value: ws, children }) }) });
3488
+ return /* @__PURE__ */ jsx6(AggWebSocketConnectionContext.Provider, { value: isConnected, children: /* @__PURE__ */ jsx6(AggWsUserEventContext.Provider, { value: userEventListeners, children: /* @__PURE__ */ jsx6(AggWebSocketContext.Provider, { value: ws, children }) }) });
2951
3489
  }
2952
3490
 
3491
+ // src/core/providers/ui-provider.tsx
3492
+ import { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo6, useState as useState3 } from "react";
3493
+
2953
3494
  // src/core/ui-config/constants.ts
2954
3495
  var DEFAULT_AGG_ROOT_CLASS_NAME = "agg-root";
2955
3496
  var CHART_TIME_RANGES = ["1H", "6H", "1D", "1W", "1M", "ALL"];
2956
3497
 
3498
+ // src/core/ui-config/storage.ts
3499
+ var STORAGE_KEY = "agg_sdk_ui";
3500
+ var isBrowser = () => typeof window !== "undefined" && "localStorage" in window;
3501
+ var normalizeTheme = (value) => {
3502
+ if (value === "light" || value === "dark") {
3503
+ return value;
3504
+ }
3505
+ return void 0;
3506
+ };
3507
+ var normalizeChartTimeRange = (value) => {
3508
+ if (typeof value === "string" && CHART_TIME_RANGES.includes(value)) {
3509
+ return value;
3510
+ }
3511
+ return void 0;
3512
+ };
3513
+ var loadPersistedConfig = () => {
3514
+ var _a, _b, _c;
3515
+ if (!isBrowser()) return {};
3516
+ try {
3517
+ const raw = window.localStorage.getItem(STORAGE_KEY);
3518
+ if (!raw) return {};
3519
+ const parsed = JSON.parse(raw);
3520
+ const locale = typeof ((_a = parsed.general) == null ? void 0 : _a.locale) === "string" ? parsed.general.locale : void 0;
3521
+ const theme = normalizeTheme((_b = parsed.general) == null ? void 0 : _b.theme);
3522
+ const selectedChartTimeRange = normalizeChartTimeRange((_c = parsed.chart) == null ? void 0 : _c.selectedChartTimeRange);
3523
+ const result = {};
3524
+ if (locale || theme) {
3525
+ result.general = { locale, theme };
3526
+ }
3527
+ if (selectedChartTimeRange) {
3528
+ result.chart = { selectedChartTimeRange };
3529
+ }
3530
+ return result;
3531
+ } catch (e) {
3532
+ return {};
3533
+ }
3534
+ };
3535
+ var persistConfig = (config) => {
3536
+ if (!isBrowser()) return;
3537
+ const theme = normalizeTheme(config.theme);
3538
+ const selectedChartTimeRange = normalizeChartTimeRange(config.selectedChartTimeRange);
3539
+ const payload = __spreadValues({
3540
+ general: {
3541
+ locale: config.locale,
3542
+ theme
3543
+ }
3544
+ }, selectedChartTimeRange ? { chart: { selectedChartTimeRange } } : {});
3545
+ try {
3546
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
3547
+ } catch (e) {
3548
+ }
3549
+ };
3550
+
3551
+ // src/core/ui-config/theme-utils.ts
3552
+ var applyThemeToDocument = (theme) => {
3553
+ if (typeof document === "undefined") return;
3554
+ const isDark = theme === "dark";
3555
+ document.documentElement.dataset.aggTheme = theme;
3556
+ document.documentElement.classList.toggle("dark", isDark);
3557
+ document.documentElement.classList.toggle("agg-dark", isDark);
3558
+ document.documentElement.classList.toggle("light", !isDark);
3559
+ const aggRoots = document.querySelectorAll(".agg-root");
3560
+ aggRoots.forEach((rootElement) => {
3561
+ rootElement.dataset.aggTheme = theme;
3562
+ rootElement.classList.toggle("dark", isDark);
3563
+ rootElement.classList.toggle("agg-dark", isDark);
3564
+ rootElement.classList.toggle("light", !isDark);
3565
+ });
3566
+ };
3567
+
2957
3568
  // src/core/providers/event-trading-context.tsx
2958
- import { createContext as createContext4, useCallback as useCallback4, useContext as useContext5, useMemo as useMemo3, useReducer, useRef as useRef3 } from "react";
2959
- import { jsx as jsx4 } from "react/jsx-runtime";
3569
+ import { createContext as createContext4, useCallback as useCallback5, useContext as useContext6, useMemo as useMemo5, useReducer, useRef as useRef3 } from "react";
3570
+ import { jsx as jsx7 } from "react/jsx-runtime";
2960
3571
  var OPEN_TRADING_STATE = {
2961
3572
  kind: "open",
2962
3573
  status: "open" /* open */,
@@ -3293,7 +3904,7 @@ var initialState = {
3293
3904
  };
3294
3905
  var EventTradingContext = createContext4(void 0);
3295
3906
  var useEventTradingContext = () => {
3296
- return useContext5(EventTradingContext);
3907
+ return useContext6(EventTradingContext);
3297
3908
  };
3298
3909
  var EventTradingProvider = ({
3299
3910
  children,
@@ -3308,7 +3919,7 @@ var EventTradingProvider = ({
3308
3919
  if (pendingAtomicSelection && ((_a = state.market) == null ? void 0 : _a.id) === pendingAtomicSelection.marketId && ((_b = state.outcome) == null ? void 0 : _b.id) === pendingAtomicSelection.outcomeId) {
3309
3920
  pendingAtomicSelectionRef.current = null;
3310
3921
  }
3311
- const dispatch = useCallback4(
3922
+ const dispatch = useCallback5(
3312
3923
  (action) => {
3313
3924
  const prev = stateRef.current;
3314
3925
  rawDispatch(action);
@@ -3317,19 +3928,19 @@ var EventTradingProvider = ({
3317
3928
  },
3318
3929
  [enableLogs]
3319
3930
  );
3320
- const initializeFromEvent = useCallback4(
3931
+ const initializeFromEvent = useCallback5(
3321
3932
  (event) => dispatch({ type: "INITIALIZE_EVENT", event }),
3322
3933
  [dispatch]
3323
3934
  );
3324
- const syncEvent = useCallback4(
3935
+ const syncEvent = useCallback5(
3325
3936
  (event) => dispatch({ type: "SYNC_EVENT", event }),
3326
3937
  [dispatch]
3327
3938
  );
3328
- const selectMarket = useCallback4(
3939
+ const selectMarket = useCallback5(
3329
3940
  (marketId, market) => dispatch({ type: "SELECT_MARKET", marketId, market }),
3330
3941
  [dispatch]
3331
3942
  );
3332
- const selectOutcome = useCallback4(
3943
+ const selectOutcome = useCallback5(
3333
3944
  (outcomeId) => {
3334
3945
  var _a2, _b2;
3335
3946
  if (((_a2 = stateRef.current.outcome) == null ? void 0 : _a2.id) === outcomeId) return;
@@ -3338,7 +3949,7 @@ var EventTradingProvider = ({
3338
3949
  },
3339
3950
  [dispatch]
3340
3951
  );
3341
- const selectMarketAndOutcome = useCallback4(
3952
+ const selectMarketAndOutcome = useCallback5(
3342
3953
  (marketId, outcomeId) => {
3343
3954
  var _a2, _b2, _c, _d;
3344
3955
  if (((_a2 = stateRef.current.market) == null ? void 0 : _a2.id) === marketId && ((_b2 = stateRef.current.outcome) == null ? void 0 : _b2.id) === outcomeId) {
@@ -3352,11 +3963,11 @@ var EventTradingProvider = ({
3352
3963
  },
3353
3964
  [dispatch]
3354
3965
  );
3355
- const setTradeSide = useCallback4(
3966
+ const setTradeSide = useCallback5(
3356
3967
  (tradeSide) => dispatch({ type: "SET_TRADE_SIDE", tradeSide }),
3357
3968
  [dispatch]
3358
3969
  );
3359
- const value = useMemo3(
3970
+ const value = useMemo5(
3360
3971
  () => {
3361
3972
  var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
3362
3973
  return {
@@ -3386,101 +3997,28 @@ var EventTradingProvider = ({
3386
3997
  setTradeSide
3387
3998
  ]
3388
3999
  );
3389
- return /* @__PURE__ */ jsx4(EventTradingContext.Provider, { value, children });
4000
+ return /* @__PURE__ */ jsx7(EventTradingContext.Provider, { value, children });
3390
4001
  };
3391
4002
 
3392
4003
  // src/core/providers/ui-provider.tsx
3393
- import { useCallback as useCallback5, useEffect as useEffect2, useMemo as useMemo4, useState as useState2 } from "react";
3394
-
3395
- // src/core/ui-config/storage.ts
3396
- var STORAGE_KEY = "agg_sdk_ui";
3397
- var isBrowser = () => typeof window !== "undefined" && "localStorage" in window;
3398
- var normalizeTheme = (value) => {
3399
- if (value === "light" || value === "dark") {
3400
- return value;
3401
- }
3402
- return void 0;
3403
- };
3404
- var normalizeChartTimeRange = (value) => {
3405
- if (typeof value === "string" && CHART_TIME_RANGES.includes(value)) {
3406
- return value;
3407
- }
3408
- return void 0;
3409
- };
3410
- var loadPersistedConfig = () => {
3411
- var _a, _b, _c;
3412
- if (!isBrowser()) return {};
3413
- try {
3414
- const raw = window.localStorage.getItem(STORAGE_KEY);
3415
- if (!raw) return {};
3416
- const parsed = JSON.parse(raw);
3417
- const locale = typeof ((_a = parsed.general) == null ? void 0 : _a.locale) === "string" ? parsed.general.locale : void 0;
3418
- const theme = normalizeTheme((_b = parsed.general) == null ? void 0 : _b.theme);
3419
- const selectedChartTimeRange = normalizeChartTimeRange((_c = parsed.chart) == null ? void 0 : _c.selectedChartTimeRange);
3420
- const result = {};
3421
- if (locale || theme) {
3422
- result.general = { locale, theme };
3423
- }
3424
- if (selectedChartTimeRange) {
3425
- result.chart = { selectedChartTimeRange };
3426
- }
3427
- return result;
3428
- } catch (e) {
3429
- return {};
3430
- }
3431
- };
3432
- var persistConfig = (config) => {
3433
- if (!isBrowser()) return;
3434
- const theme = normalizeTheme(config.theme);
3435
- const selectedChartTimeRange = normalizeChartTimeRange(config.selectedChartTimeRange);
3436
- const payload = __spreadValues({
3437
- general: {
3438
- locale: config.locale,
3439
- theme
3440
- }
3441
- }, selectedChartTimeRange ? { chart: { selectedChartTimeRange } } : {});
3442
- try {
3443
- window.localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
3444
- } catch (e) {
4004
+ import { jsx as jsx8 } from "react/jsx-runtime";
4005
+ var hasWarnedMissingAggStyles = false;
4006
+ var warnIfAggStylesAreMissing = () => {
4007
+ if (hasWarnedMissingAggStyles) return;
4008
+ if (typeof window === "undefined" || typeof document === "undefined") return;
4009
+ const rootElement = document.querySelector(`.${DEFAULT_AGG_ROOT_CLASS_NAME}`);
4010
+ if (!rootElement) return;
4011
+ const computedStyle = window.getComputedStyle(rootElement);
4012
+ const hasSemanticColorToken = computedStyle.getPropertyValue("--agg-color-primary").trim().length > 0;
4013
+ const hasTailwindColorToken = computedStyle.getPropertyValue("--color-agg-primary").trim().length > 0;
4014
+ const hasTailwindRadiusToken = computedStyle.getPropertyValue("--radius-agg-md").trim().length > 0;
4015
+ if (hasSemanticColorToken && hasTailwindColorToken && hasTailwindRadiusToken) {
4016
+ return;
3445
4017
  }
3446
- };
3447
-
3448
- // src/core/ui-config/theme-utils.ts
3449
- var applyThemeToDocument = (theme) => {
3450
- if (typeof document === "undefined") return;
3451
- const isDark = theme === "dark";
3452
- document.documentElement.dataset.aggTheme = theme;
3453
- document.documentElement.classList.toggle("dark", isDark);
3454
- document.documentElement.classList.toggle("agg-dark", isDark);
3455
- document.documentElement.classList.toggle("light", !isDark);
3456
- const aggRoots = document.querySelectorAll(".agg-root");
3457
- aggRoots.forEach((rootElement) => {
3458
- rootElement.dataset.aggTheme = theme;
3459
- rootElement.classList.toggle("dark", isDark);
3460
- rootElement.classList.toggle("agg-dark", isDark);
3461
- rootElement.classList.toggle("light", !isDark);
3462
- });
3463
- };
3464
-
3465
- // src/core/providers/ui-provider.tsx
3466
- import { jsx as jsx5 } from "react/jsx-runtime";
3467
- var hasWarnedMissingAggStyles = false;
3468
- var warnIfAggStylesAreMissing = () => {
3469
- if (hasWarnedMissingAggStyles) return;
3470
- if (typeof window === "undefined" || typeof document === "undefined") return;
3471
- const rootElement = document.querySelector(`.${DEFAULT_AGG_ROOT_CLASS_NAME}`);
3472
- if (!rootElement) return;
3473
- const computedStyle = window.getComputedStyle(rootElement);
3474
- const hasSemanticColorToken = computedStyle.getPropertyValue("--agg-color-primary").trim().length > 0;
3475
- const hasTailwindColorToken = computedStyle.getPropertyValue("--color-agg-primary").trim().length > 0;
3476
- const hasTailwindRadiusToken = computedStyle.getPropertyValue("--radius-agg-md").trim().length > 0;
3477
- if (hasSemanticColorToken && hasTailwindColorToken && hasTailwindRadiusToken) {
3478
- return;
3479
- }
3480
- hasWarnedMissingAggStyles = true;
3481
- console.warn(
3482
- '[agg] Missing AGG UI styles. Import "@agg-build/ui/styles.css" once at your app entrypoint so agg token utilities resolve correctly.'
3483
- );
4018
+ hasWarnedMissingAggStyles = true;
4019
+ console.warn(
4020
+ '[agg] Missing AGG UI styles. Import "@agg-build/ui/styles.css" once at your app entrypoint so agg token utilities resolve correctly.'
4021
+ );
3484
4022
  };
3485
4023
  function logConfig(config, enableLogs) {
3486
4024
  if (!enableLogs) return;
@@ -3494,545 +4032,130 @@ var getSearchStateAfterSelect = (selectedEvent) => {
3494
4032
  result: selectedEvent,
3495
4033
  isShowingAllResults: false
3496
4034
  };
3497
- };
3498
- var AggUiProvider = ({ config, children }) => {
3499
- const persisted = useMemo4(() => loadPersistedConfig(), []);
3500
- const mergedConfig = useMemo4(() => mergeAggUiConfig(persisted, config), [persisted, config]);
3501
- const [selectedChartTimeRange, setSelectedChartTimeRange] = useState2(
3502
- mergedConfig.chart.selectedChartTimeRange
3503
- );
3504
- const handleSetSelectedChartTimeRange = useCallback5((range) => {
3505
- setSelectedChartTimeRange(range);
3506
- }, []);
3507
- const [searchValue, setSearchValue] = useState2(mergedConfig.search.value);
3508
- const [searchResult, setSearchResult] = useState2(mergedConfig.search.result);
3509
- const [isShowingAllResults, setIsShowingAllResults] = useState2(
3510
- mergedConfig.search.isShowingAllResults
3511
- );
3512
- useEffect2(() => {
3513
- setSearchValue(mergedConfig.search.value);
3514
- }, [mergedConfig.search.value]);
3515
- useEffect2(() => {
3516
- setSearchResult(mergedConfig.search.result);
3517
- }, [mergedConfig.search.result]);
3518
- useEffect2(() => {
3519
- setIsShowingAllResults(mergedConfig.search.isShowingAllResults);
3520
- }, [mergedConfig.search.isShowingAllResults]);
3521
- const handleSearchChange = useCallback5(
3522
- (value) => {
3523
- var _a, _b;
3524
- setSearchValue(value);
3525
- setSearchResult(null);
3526
- setIsShowingAllResults(false);
3527
- (_b = (_a = mergedConfig.search).onChange) == null ? void 0 : _b.call(_a, value);
3528
- },
3529
- [mergedConfig.search]
3530
- );
3531
- const handleSearchSelect = useCallback5(
3532
- (value) => {
3533
- var _a, _b;
3534
- const nextSearchState = getSearchStateAfterSelect(value);
3535
- setSearchValue(nextSearchState.value);
3536
- setSearchResult(nextSearchState.result);
3537
- setIsShowingAllResults(nextSearchState.isShowingAllResults);
3538
- (_b = (_a = mergedConfig.search).onSelect) == null ? void 0 : _b.call(_a, value);
3539
- },
3540
- [mergedConfig.search]
3541
- );
3542
- const handleOpenResults = useCallback5(() => {
3543
- var _a, _b;
3544
- setIsShowingAllResults(true);
3545
- (_b = (_a = mergedConfig.search).openResults) == null ? void 0 : _b.call(_a);
3546
- }, [mergedConfig.search]);
3547
- const handleCloseResults = useCallback5(() => {
3548
- var _a, _b;
3549
- setIsShowingAllResults(false);
3550
- (_b = (_a = mergedConfig.search).closeResults) == null ? void 0 : _b.call(_a);
3551
- }, [mergedConfig.search]);
3552
- const resolvedConfig = useMemo4(() => {
3553
- return __spreadProps(__spreadValues({}, mergedConfig), {
3554
- chart: __spreadProps(__spreadValues({}, mergedConfig.chart), {
3555
- selectedChartTimeRange,
3556
- setSelectedChartTimeRange: handleSetSelectedChartTimeRange
3557
- }),
3558
- search: __spreadProps(__spreadValues({}, mergedConfig.search), {
3559
- value: searchValue,
3560
- onChange: handleSearchChange,
3561
- onSelect: handleSearchSelect,
3562
- openResults: handleOpenResults,
3563
- closeResults: handleCloseResults,
3564
- result: searchResult,
3565
- isShowingAllResults
3566
- })
3567
- });
3568
- }, [
3569
- handleCloseResults,
3570
- handleOpenResults,
3571
- handleSearchChange,
3572
- handleSearchSelect,
3573
- handleSetSelectedChartTimeRange,
3574
- isShowingAllResults,
3575
- mergedConfig,
3576
- searchResult,
3577
- searchValue,
3578
- selectedChartTimeRange
3579
- ]);
3580
- useEffect2(() => {
3581
- persistConfig({
3582
- locale: resolvedConfig.general.locale,
3583
- theme: resolvedConfig.general.theme,
3584
- selectedChartTimeRange: resolvedConfig.chart.selectedChartTimeRange
3585
- });
3586
- }, [
3587
- resolvedConfig.general.locale,
3588
- resolvedConfig.general.theme,
3589
- resolvedConfig.chart.selectedChartTimeRange
3590
- ]);
3591
- useEffect2(() => {
3592
- applyThemeToDocument(resolvedConfig.general.theme);
3593
- }, [resolvedConfig.general.theme]);
3594
- useEffect2(() => {
3595
- warnIfAggStylesAreMissing();
3596
- }, []);
3597
- const resolvedRootClassName = [
3598
- DEFAULT_AGG_ROOT_CLASS_NAME,
3599
- resolvedConfig.general.theme === "dark" ? "dark" : null,
3600
- resolvedConfig.general.rootClassName
3601
- ].filter(Boolean).join(" ");
3602
- logConfig(resolvedConfig, resolvedConfig.enableLogs);
3603
- return /* @__PURE__ */ jsx5(AggLabelsContext.Provider, { value: resolvedConfig.general.labels, children: /* @__PURE__ */ jsx5(AggUiContext.Provider, { value: resolvedConfig, children: /* @__PURE__ */ jsx5(EventTradingProvider, { enableLogs: resolvedConfig.enableLogs, children: /* @__PURE__ */ jsx5(
3604
- "div",
3605
- {
3606
- className: resolvedRootClassName,
3607
- "data-agg-animations": resolvedConfig.features.enableAnimations ? "true" : "false",
3608
- "data-agg-gradients": resolvedConfig.features.enableGradients ? "true" : "false",
3609
- "data-agg-theme": resolvedConfig.general.theme,
3610
- children
3611
- }
3612
- ) }) }) });
3613
- };
3614
-
3615
- // src/core/providers/agg-provider.tsx
3616
- import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
3617
-
3618
- // src/core/providers/auth-provider.tsx
3619
- import { QueryClient, QueryClientContext } from "@tanstack/react-query";
3620
- import { useCallback as useCallback6, useContext as useContext6, useEffect as useEffect3, useMemo as useMemo5, useState as useState3 } from "react";
3621
-
3622
- // src/current-user-query.ts
3623
- var CURRENT_USER_QUERY_KEY = ["current-user"];
3624
- var CURRENT_USER_STALE_TIME_MS = 6e4;
3625
- var fetchCurrentUserProfile = (queryClient, client, queryKey = CURRENT_USER_QUERY_KEY) => {
3626
- return queryClient.fetchQuery({
3627
- queryKey,
3628
- queryFn: () => client.getCurrentUser(),
3629
- staleTime: CURRENT_USER_STALE_TIME_MS
3630
- });
3631
- };
3632
-
3633
- // src/core/providers/auth-utils.ts
3634
- import { TurnstileChallengeError } from "@agg-build/sdk";
3635
- var createPlaceholderUserProfile = (input) => {
3636
- return {
3637
- id: input.id,
3638
- username: null,
3639
- avatarUrl: null,
3640
- externalId: null,
3641
- isLocationBlocked: false,
3642
- venueAccounts: null,
3643
- accounts: [],
3644
- wallets: []
3645
- };
3646
- };
3647
- var createWalletSessionUser = (input) => {
3648
- return __spreadProps(__spreadValues({}, createPlaceholderUserProfile({ id: input.id })), {
3649
- accounts: [
3650
- {
3651
- type: "siwe" /* siwe */,
3652
- provider: "wallet" /* wallet */,
3653
- providerAccountId: input.address
3654
- }
3655
- ]
3656
- });
3657
- };
3658
- var getBrowserAuthLocation = () => {
3659
- if (typeof window === "undefined") {
3660
- return {
3661
- domain: "localhost",
3662
- uri: "http://localhost"
3663
- };
3664
- }
3665
- return {
3666
- domain: window.location.host,
3667
- uri: window.location.origin
3668
- };
3669
- };
3670
- var resolveAuthCallbackUrl = (callbackUrl) => {
3671
- return callbackUrl instanceof URL ? callbackUrl : typeof callbackUrl === "string" ? new URL(
3672
- callbackUrl,
3673
- typeof window === "undefined" ? "http://localhost" : window.location.origin
3674
- ) : typeof window === "undefined" ? null : new URL(window.location.href);
3675
- };
3676
- var parseAuthCallbackCode = (callbackUrl) => {
3677
- var _a;
3678
- const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
3679
- return (_a = resolvedUrl == null ? void 0 : resolvedUrl.searchParams.get("code")) != null ? _a : null;
3680
- };
3681
- var parseLinkConfirmToken = (callbackUrl) => {
3682
- var _a;
3683
- const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
3684
- return (_a = resolvedUrl == null ? void 0 : resolvedUrl.searchParams.get("link_confirm_token")) != null ? _a : null;
3685
- };
3686
- var getAuthCallbackCleanupPath = (callbackUrl) => {
3687
- const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
3688
- if (!resolvedUrl) return null;
3689
- const params = new URLSearchParams(resolvedUrl.search);
3690
- params.delete("code");
3691
- params.delete("link_confirm_token");
3692
- const search = params.toString();
3693
- return `${resolvedUrl.pathname}${search ? `?${search}` : ""}`;
3694
- };
3695
- var exchangeAuthCallbackCode = (client, callbackUrl) => __async(null, null, function* () {
3696
- const code = parseAuthCallbackCode(callbackUrl);
3697
- if (!code) return null;
3698
- const result = yield client.exchangeAuthCode(code);
3699
- return {
3700
- cleanupPath: getAuthCallbackCleanupPath(callbackUrl),
3701
- user: result.user
3702
- };
3703
- });
3704
- var confirmLinkAccountCallback = (client, callbackUrl) => __async(null, null, function* () {
3705
- const token = parseLinkConfirmToken(callbackUrl);
3706
- if (!token) return null;
3707
- yield client.linkAccountConfirm(token);
3708
- return { cleanupPath: getAuthCallbackCleanupPath(callbackUrl) };
3709
- });
3710
- var parseAuthCallbackTokens = (callbackUrl) => {
3711
- var _a, _b;
3712
- const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
3713
- if (!resolvedUrl) return null;
3714
- const hash = resolvedUrl.hash.startsWith("#") ? resolvedUrl.hash.slice(1) : resolvedUrl.hash;
3715
- if (!hash) return null;
3716
- const params = new URLSearchParams(hash);
3717
- const accessToken = params.get("access_token");
3718
- const refreshToken = params.get("refresh_token");
3719
- if (!accessToken || !refreshToken) return null;
3720
- const userId = (_a = params.get("user_id")) != null ? _a : void 0;
3721
- const tokenType = (_b = params.get("token_type")) != null ? _b : void 0;
3722
- return {
3723
- accessToken,
3724
- refreshToken,
3725
- tokenType,
3726
- userId
3727
- };
3728
- };
3729
- var createAuthCallbackSession = (tokens) => {
3730
- return {
3731
- accessToken: tokens.accessToken,
3732
- refreshToken: tokens.refreshToken,
3733
- user: tokens.userId ? createPlaceholderUserProfile({ id: tokens.userId }) : void 0
3734
- };
3735
- };
3736
- var executeWalletAuthFlow = (input) => __async(null, null, function* () {
3737
- var _a, _b, _c, _d;
3738
- const address = input.options.address.trim();
3739
- const chain = (_a = input.options.chain) != null ? _a : "ethereum";
3740
- const provider = chain === "solana" ? "siws" : "siwe";
3741
- const location = (_b = input.location) != null ? _b : getBrowserAuthLocation();
3742
- const startResult = yield input.client.authStart(__spreadValues({
3743
- provider
3744
- }, input.options.turnstileToken ? { turnstileToken: input.options.turnstileToken } : {}));
3745
- if (startResult.type === "challenge_required") {
3746
- if (!startResult.siteKey) {
3747
- throw new Error("Server returned challenge_required but no siteKey was provided.");
3748
- }
3749
- throw new TurnstileChallengeError(startResult.siteKey);
3750
- }
3751
- if (startResult.type !== "nonce") {
3752
- throw new Error(`AGG auth start returned an unexpected "${startResult.type}" response`);
3753
- }
3754
- const message = chain === "solana" ? input.client.buildSiwsMessage({
3755
- domain: location.domain,
3756
- address,
3757
- uri: location.uri,
3758
- nonce: startResult.nonce,
3759
- chainId: typeof input.options.chainId === "string" ? input.options.chainId : "mainnet",
3760
- statement: (_c = startResult.statement) != null ? _c : input.options.statement
3761
- }) : input.client.buildSiweMessage({
3762
- domain: location.domain,
3763
- // Any casing: `buildSiweMessage` applies the EIP-55 checksum itself.
3764
- address,
3765
- uri: location.uri,
3766
- nonce: startResult.nonce,
3767
- chainId: typeof input.options.chainId === "number" ? input.options.chainId : void 0,
3768
- statement: (_d = startResult.statement) != null ? _d : input.options.statement
3769
- });
3770
- const signature = yield input.options.signMessage(message);
3771
- const result = yield input.client.verify({ message, signature });
3772
- return {
3773
- accessToken: result.accessToken,
3774
- refreshToken: result.refreshToken,
3775
- user: createWalletSessionUser({
3776
- id: result.user.id,
3777
- address
3778
- })
3779
- };
3780
- });
3781
-
3782
- // src/core/providers/auth-provider.tsx
3783
- import { jsx as jsx6 } from "react/jsx-runtime";
3784
- var getClientAuthSnapshot = (client) => {
3785
- var _a;
3786
- return {
3787
- isAuthenticated: (_a = client == null ? void 0 : client.isAuthenticated) != null ? _a : false,
3788
- user: client == null ? void 0 : client.user
3789
- };
3790
- };
3791
- var toError = (value) => {
3792
- return value instanceof Error ? value : new Error(String(value));
3793
- };
3794
- var replaceAuthCallbackUrl = (cleanupPath) => {
3795
- if (!cleanupPath || typeof window === "undefined") return;
3796
- window.history.replaceState(null, "", cleanupPath);
3797
- };
3798
- function AggAuthProvider({ children }) {
3799
- const client = useContext6(AggClientContext);
3800
- const queryClientFromContext = useContext6(QueryClientContext);
3801
- const fallbackQueryClient = useMemo5(() => new QueryClient(), []);
3802
- const queryClient = queryClientFromContext && "fetchQuery" in queryClientFromContext ? queryClientFromContext : fallbackQueryClient;
3803
- const snapshot = getClientAuthSnapshot(client);
3804
- const [isAuthenticated, setIsAuthenticated] = useState3(snapshot.isAuthenticated);
3805
- const [user, setUser] = useState3(snapshot.user);
3806
- const [isLoading, setIsLoading] = useState3(false);
3807
- const [error, setError] = useState3(null);
3808
- const isWeb3User = useMemo5(() => {
3809
- const accounts = user == null ? void 0 : user.accounts;
3810
- if (!Array.isArray(accounts)) return true;
3811
- return accounts.some((account) => {
3812
- var _a;
3813
- const provider = String((_a = account.provider) != null ? _a : "").toLowerCase();
3814
- return provider === "wallet" || provider === "solana_wallet";
3815
- });
3816
- }, [user]);
3817
- const refreshCurrentUser = useCallback6(
3818
- (targetClient) => __async(null, null, function* () {
3819
- const fullUser = yield fetchCurrentUserProfile(queryClient, targetClient);
3820
- setIsAuthenticated(true);
3821
- setUser(fullUser);
3822
- return fullUser;
3823
- }),
3824
- [queryClient]
3825
- );
3826
- useEffect3(() => {
3827
- const state = getClientAuthSnapshot(client);
3828
- setIsAuthenticated(state.isAuthenticated);
3829
- setUser(state.user);
3830
- setIsLoading(false);
3831
- setError(null);
3832
- if (!client) return;
3833
- if (state.isAuthenticated) {
3834
- refreshCurrentUser(client).catch(() => {
3835
- client.clearAccessToken();
3836
- });
3837
- } else if (client.authStatus === "unknown") {
3838
- client.refreshAccessToken().then(() => refreshCurrentUser(client)).catch(() => {
3839
- client.clearAccessToken();
3840
- });
3841
- }
3842
- }, [client, refreshCurrentUser]);
3843
- useEffect3(() => {
3844
- if (!client) return;
3845
- return client.onAuthStateChange((authenticated) => {
3846
- setIsAuthenticated(authenticated);
3847
- setUser(client.user);
3848
- if (!authenticated) {
3849
- setIsLoading(false);
3850
- setError(null);
3851
- }
3852
- });
3853
- }, [client]);
3854
- const signIn = useCallback6(
3855
- (options) => __async(null, null, function* () {
3856
- if (!client) {
3857
- const missingClientError = new Error("Agg client is not configured in <AggProvider>");
3858
- setError(missingClientError);
3859
- throw missingClientError;
3860
- }
3861
- const address = options.address.trim();
3862
- if (!address) {
3863
- const missingAddressError = new Error("Wallet address is required");
3864
- setError(missingAddressError);
3865
- throw missingAddressError;
3866
- }
3867
- setIsLoading(true);
3868
- setError(null);
3869
- try {
3870
- const result = yield executeWalletAuthFlow({
3871
- client,
3872
- options: __spreadProps(__spreadValues({}, options), {
3873
- address
3874
- })
3875
- });
3876
- client.setSession(result);
3877
- setIsAuthenticated(true);
3878
- setUser(result.user);
3879
- yield refreshCurrentUser(client);
3880
- } catch (signInError) {
3881
- const resolvedError = toError(signInError);
3882
- setError(resolvedError);
3883
- throw resolvedError;
3884
- } finally {
3885
- setIsLoading(false);
3886
- }
3887
- }),
3888
- [client, refreshCurrentUser]
4035
+ };
4036
+ var AggUiProvider = ({ config, children }) => {
4037
+ const persisted = useMemo6(() => loadPersistedConfig(), []);
4038
+ const mergedConfig = useMemo6(() => mergeAggUiConfig(persisted, config), [persisted, config]);
4039
+ const [selectedChartTimeRange, setSelectedChartTimeRange] = useState3(
4040
+ mergedConfig.chart.selectedChartTimeRange
3889
4041
  );
3890
- const startAuth = useCallback6(
3891
- (options) => __async(null, null, function* () {
3892
- if (!client) {
3893
- const missingClientError = new Error("Agg client is not configured in <AggProvider>");
3894
- setError(missingClientError);
3895
- throw missingClientError;
3896
- }
3897
- setIsLoading(true);
3898
- setError(null);
3899
- try {
3900
- return yield client.authStart(options);
3901
- } catch (startAuthError) {
3902
- const resolvedError = toError(startAuthError);
3903
- setError(resolvedError);
3904
- throw resolvedError;
3905
- } finally {
3906
- setIsLoading(false);
3907
- }
3908
- }),
3909
- [client]
4042
+ const handleSetSelectedChartTimeRange = useCallback6((range) => {
4043
+ setSelectedChartTimeRange(range);
4044
+ }, []);
4045
+ const [searchValue, setSearchValue] = useState3(mergedConfig.search.value);
4046
+ const [searchResult, setSearchResult] = useState3(mergedConfig.search.result);
4047
+ const [isShowingAllResults, setIsShowingAllResults] = useState3(
4048
+ mergedConfig.search.isShowingAllResults
3910
4049
  );
3911
- const setSession = useCallback6(
3912
- (session) => __async(null, null, function* () {
3913
- if (!client) {
3914
- const missingClientError = new Error("Agg client is not configured in <AggProvider>");
3915
- setError(missingClientError);
3916
- throw missingClientError;
3917
- }
3918
- setIsLoading(true);
3919
- setError(null);
3920
- try {
3921
- client.setSession(session);
3922
- const resolvedUser = yield refreshCurrentUser(client);
3923
- setIsAuthenticated(true);
3924
- setUser(resolvedUser);
3925
- return resolvedUser;
3926
- } catch (sessionError) {
3927
- client.clearAccessToken();
3928
- setIsAuthenticated(false);
3929
- setUser(void 0);
3930
- const resolvedError = toError(sessionError);
3931
- setError(resolvedError);
3932
- throw resolvedError;
3933
- } finally {
3934
- setIsLoading(false);
3935
- }
3936
- }),
3937
- [client, refreshCurrentUser]
4050
+ useEffect3(() => {
4051
+ setSearchValue(mergedConfig.search.value);
4052
+ }, [mergedConfig.search.value]);
4053
+ useEffect3(() => {
4054
+ setSearchResult(mergedConfig.search.result);
4055
+ }, [mergedConfig.search.result]);
4056
+ useEffect3(() => {
4057
+ setIsShowingAllResults(mergedConfig.search.isShowingAllResults);
4058
+ }, [mergedConfig.search.isShowingAllResults]);
4059
+ const handleSearchChange = useCallback6(
4060
+ (value) => {
4061
+ var _a, _b;
4062
+ setSearchValue(value);
4063
+ setSearchResult(null);
4064
+ setIsShowingAllResults(false);
4065
+ (_b = (_a = mergedConfig.search).onChange) == null ? void 0 : _b.call(_a, value);
4066
+ },
4067
+ [mergedConfig.search]
3938
4068
  );
3939
- const handleAuthCallback = useCallback6(
3940
- (callbackUrl) => __async(null, null, function* () {
3941
- if (!client) {
3942
- const missingClientError = new Error("Agg client is not configured in <AggProvider>");
3943
- setError(missingClientError);
3944
- throw missingClientError;
3945
- }
3946
- setIsLoading(true);
3947
- setError(null);
3948
- try {
3949
- const exchangedSession = yield exchangeAuthCallbackCode(client, callbackUrl);
3950
- if (exchangedSession) {
3951
- const resolvedUser2 = yield refreshCurrentUser(client);
3952
- if (callbackUrl === void 0) {
3953
- replaceAuthCallbackUrl(exchangedSession.cleanupPath);
3954
- }
3955
- return resolvedUser2;
3956
- }
3957
- const confirmedLink = yield confirmLinkAccountCallback(client, callbackUrl);
3958
- if (confirmedLink) {
3959
- const resolvedUser2 = yield refreshCurrentUser(client);
3960
- if (callbackUrl === void 0) {
3961
- replaceAuthCallbackUrl(confirmedLink.cleanupPath);
3962
- }
3963
- return resolvedUser2;
3964
- }
3965
- const tokens = parseAuthCallbackTokens(callbackUrl);
3966
- if (!tokens) return null;
3967
- client.setSession(createAuthCallbackSession(tokens));
3968
- setIsAuthenticated(client.isAuthenticated);
3969
- setUser(client.user);
3970
- const resolvedUser = yield refreshCurrentUser(client);
3971
- if (callbackUrl === void 0) {
3972
- replaceAuthCallbackUrl(getAuthCallbackCleanupPath(callbackUrl));
3973
- }
3974
- return resolvedUser;
3975
- } catch (callbackError) {
3976
- const resolvedError = toError(callbackError);
3977
- setError(resolvedError);
3978
- throw resolvedError;
3979
- } finally {
3980
- setIsLoading(false);
3981
- }
3982
- }),
3983
- [client, refreshCurrentUser]
4069
+ const handleSearchSelect = useCallback6(
4070
+ (value) => {
4071
+ var _a, _b;
4072
+ const nextSearchState = getSearchStateAfterSelect(value);
4073
+ setSearchValue(nextSearchState.value);
4074
+ setSearchResult(nextSearchState.result);
4075
+ setIsShowingAllResults(nextSearchState.isShowingAllResults);
4076
+ (_b = (_a = mergedConfig.search).onSelect) == null ? void 0 : _b.call(_a, value);
4077
+ },
4078
+ [mergedConfig.search]
3984
4079
  );
3985
- const signOut = useCallback6(() => __async(null, null, function* () {
3986
- yield client == null ? void 0 : client.signOut();
3987
- setIsAuthenticated(false);
3988
- setUser(void 0);
3989
- setError(null);
3990
- }), [client]);
3991
- const clearError = useCallback6(() => {
3992
- setError(null);
3993
- }, []);
3994
- const value = useMemo5(() => {
3995
- return {
3996
- isAuthenticated,
3997
- isWeb3User,
3998
- user,
3999
- isLoading,
4000
- error,
4001
- signIn,
4002
- startAuth,
4003
- setSession,
4004
- handleAuthCallback,
4005
- signOut,
4006
- clearError
4007
- };
4080
+ const handleOpenResults = useCallback6(() => {
4081
+ var _a, _b;
4082
+ setIsShowingAllResults(true);
4083
+ (_b = (_a = mergedConfig.search).openResults) == null ? void 0 : _b.call(_a);
4084
+ }, [mergedConfig.search]);
4085
+ const handleCloseResults = useCallback6(() => {
4086
+ var _a, _b;
4087
+ setIsShowingAllResults(false);
4088
+ (_b = (_a = mergedConfig.search).closeResults) == null ? void 0 : _b.call(_a);
4089
+ }, [mergedConfig.search]);
4090
+ const resolvedConfig = useMemo6(() => {
4091
+ return __spreadProps(__spreadValues({}, mergedConfig), {
4092
+ chart: __spreadProps(__spreadValues({}, mergedConfig.chart), {
4093
+ selectedChartTimeRange,
4094
+ setSelectedChartTimeRange: handleSetSelectedChartTimeRange
4095
+ }),
4096
+ search: __spreadProps(__spreadValues({}, mergedConfig.search), {
4097
+ value: searchValue,
4098
+ onChange: handleSearchChange,
4099
+ onSelect: handleSearchSelect,
4100
+ openResults: handleOpenResults,
4101
+ closeResults: handleCloseResults,
4102
+ result: searchResult,
4103
+ isShowingAllResults
4104
+ })
4105
+ });
4008
4106
  }, [
4009
- clearError,
4010
- error,
4011
- handleAuthCallback,
4012
- isAuthenticated,
4013
- isWeb3User,
4014
- isLoading,
4015
- setSession,
4016
- signIn,
4017
- signOut,
4018
- startAuth,
4019
- user
4107
+ handleCloseResults,
4108
+ handleOpenResults,
4109
+ handleSearchChange,
4110
+ handleSearchSelect,
4111
+ handleSetSelectedChartTimeRange,
4112
+ isShowingAllResults,
4113
+ mergedConfig,
4114
+ searchResult,
4115
+ searchValue,
4116
+ selectedChartTimeRange
4020
4117
  ]);
4021
- return /* @__PURE__ */ jsx6(AggAuthContext.Provider, { value, children });
4022
- }
4023
-
4024
- // src/core/providers/client-provider.tsx
4025
- import { jsx as jsx7 } from "react/jsx-runtime";
4026
- function AggClientProvider({ client, children }) {
4027
- return /* @__PURE__ */ jsx7(AggClientContext.Provider, { value: client != null ? client : null, children });
4028
- }
4118
+ useEffect3(() => {
4119
+ persistConfig({
4120
+ locale: resolvedConfig.general.locale,
4121
+ theme: resolvedConfig.general.theme,
4122
+ selectedChartTimeRange: resolvedConfig.chart.selectedChartTimeRange
4123
+ });
4124
+ }, [
4125
+ resolvedConfig.general.locale,
4126
+ resolvedConfig.general.theme,
4127
+ resolvedConfig.chart.selectedChartTimeRange
4128
+ ]);
4129
+ useEffect3(() => {
4130
+ applyThemeToDocument(resolvedConfig.general.theme);
4131
+ }, [resolvedConfig.general.theme]);
4132
+ useEffect3(() => {
4133
+ warnIfAggStylesAreMissing();
4134
+ }, []);
4135
+ const resolvedRootClassName = [
4136
+ DEFAULT_AGG_ROOT_CLASS_NAME,
4137
+ resolvedConfig.general.theme === "dark" ? "dark" : null,
4138
+ resolvedConfig.general.rootClassName
4139
+ ].filter(Boolean).join(" ");
4140
+ logConfig(resolvedConfig, resolvedConfig.enableLogs);
4141
+ return /* @__PURE__ */ jsx8(AggLabelsContext.Provider, { value: resolvedConfig.general.labels, children: /* @__PURE__ */ jsx8(AggUiContext.Provider, { value: resolvedConfig, children: /* @__PURE__ */ jsx8(EventTradingProvider, { enableLogs: resolvedConfig.enableLogs, children: /* @__PURE__ */ jsx8(
4142
+ "div",
4143
+ {
4144
+ className: resolvedRootClassName,
4145
+ "data-agg-animations": resolvedConfig.features.enableAnimations ? "true" : "false",
4146
+ "data-agg-gradients": resolvedConfig.features.enableGradients ? "true" : "false",
4147
+ "data-agg-theme": resolvedConfig.general.theme,
4148
+ children
4149
+ }
4150
+ ) }) }) });
4151
+ };
4029
4152
 
4030
4153
  // src/core/providers/agg-provider.tsx
4031
- import { jsx as jsx8 } from "react/jsx-runtime";
4154
+ import { jsx as jsx9 } from "react/jsx-runtime";
4032
4155
  var hasWarnedMissingQueryClient = false;
4033
4156
  function useQueryClientCheck() {
4034
4157
  try {
4035
- useQueryClient2();
4158
+ useQueryClient3();
4036
4159
  } catch (e) {
4037
4160
  if (!hasWarnedMissingQueryClient) {
4038
4161
  hasWarnedMissingQueryClient = true;
@@ -4049,14 +4172,32 @@ var AggProvider = ({ client, config, children }) => {
4049
4172
  "AggProvider requires a valid AggClient instance. Create one with createAggClient() and pass it via the 'client' prop."
4050
4173
  );
4051
4174
  }
4052
- return /* @__PURE__ */ jsx8(AggClientProvider, { client, children: /* @__PURE__ */ jsx8(AggUiProvider, { config, children: /* @__PURE__ */ jsx8(EventListStateProvider, { children: /* @__PURE__ */ jsx8(AggWebSocketProvider, { children: /* @__PURE__ */ jsx8(AggAuthProvider, { children: /* @__PURE__ */ jsx8(AggBalanceProvider, { children }) }) }) }) }) });
4175
+ return /* @__PURE__ */ jsx9(AggClientProvider, { client, children: /* @__PURE__ */ jsx9(AggUiProvider, { config, children: /* @__PURE__ */ jsx9(AggExecutionModeProvider, { children: /* @__PURE__ */ jsx9(EventListStateProvider, { children: /* @__PURE__ */ jsx9(AggWebSocketProvider, { children: /* @__PURE__ */ jsx9(AggAuthProvider, { children: /* @__PURE__ */ jsx9(AggBalanceProvider, { children }) }) }) }) }) }) });
4053
4176
  };
4054
4177
 
4178
+ // src/use-resolved-execution-mode.ts
4179
+ function useResolvedExecutionMode(override) {
4180
+ var _a;
4181
+ const serverConfig = useContext7(AggExecutionModeContext);
4182
+ const tradingMode = serverConfig == null ? void 0 : serverConfig.tradingMode;
4183
+ const isLoading = (_a = serverConfig == null ? void 0 : serverConfig.isLoading) != null ? _a : false;
4184
+ const {
4185
+ trading: { executionMode: configuredExecutionMode }
4186
+ } = useAggUiConfig();
4187
+ const localMode = override != null ? override : configuredExecutionMode;
4188
+ const executionMode = tradingMode != null ? tradingMode : localMode === "paper" ? "paper" : "live";
4189
+ return {
4190
+ executionMode,
4191
+ isPaperMode: executionMode === "paper",
4192
+ isResolving: tradingMode === void 0 && isLoading
4193
+ };
4194
+ }
4195
+
4055
4196
  // src/execution/use-execute-managed.ts
4056
- import { useMutation, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
4197
+ import { useMutation, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
4057
4198
  function useExecuteManaged(options) {
4058
4199
  const client = useAggClient();
4059
- const queryClient = useQueryClient3();
4200
+ const queryClient = useQueryClient4();
4060
4201
  return useMutation({
4061
4202
  mutationFn: (params) => client.executeManaged(params),
4062
4203
  onSuccess: (data) => {
@@ -4071,10 +4212,10 @@ function useExecuteManaged(options) {
4071
4212
  }
4072
4213
 
4073
4214
  // src/execution/use-place-limit-order.ts
4074
- import { useMutation as useMutation2, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
4215
+ import { useMutation as useMutation2, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
4075
4216
  function usePlaceLimitOrder(options) {
4076
4217
  const client = useAggClient();
4077
- const queryClient = useQueryClient4();
4218
+ const queryClient = useQueryClient5();
4078
4219
  return useMutation2({
4079
4220
  mutationFn: (params) => client.placeLimitOrder(params),
4080
4221
  onSuccess: (data) => {
@@ -4090,10 +4231,10 @@ function usePlaceLimitOrder(options) {
4090
4231
  }
4091
4232
 
4092
4233
  // src/execution/use-cancel-managed-order.ts
4093
- import { useMutation as useMutation3, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
4234
+ import { useMutation as useMutation3, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
4094
4235
  function useCancelManagedOrder(options) {
4095
4236
  const client = useAggClient();
4096
- const queryClient = useQueryClient5();
4237
+ const queryClient = useQueryClient6();
4097
4238
  return useMutation3({
4098
4239
  mutationFn: (orderId) => client.cancelManagedOrder(orderId),
4099
4240
  onSuccess: (data, orderId) => {
@@ -4113,10 +4254,10 @@ function useCancelManagedOrder(options) {
4113
4254
  }
4114
4255
 
4115
4256
  // src/execution/use-withdraw-managed.ts
4116
- import { useMutation as useMutation4, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
4257
+ import { useMutation as useMutation4, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
4117
4258
  function useWithdrawManaged(options) {
4118
4259
  const client = useAggClient();
4119
- const queryClient = useQueryClient6();
4260
+ const queryClient = useQueryClient7();
4120
4261
  return useMutation4({
4121
4262
  mutationFn: (params) => client.withdrawManaged(params),
4122
4263
  onSuccess: (data) => {
@@ -4129,15 +4270,19 @@ function useWithdrawManaged(options) {
4129
4270
  }
4130
4271
 
4131
4272
  // src/execution/use-managed-balances.ts
4132
- import { useQuery as useQuery2 } from "@tanstack/react-query";
4273
+ import { useQuery as useQuery3 } from "@tanstack/react-query";
4133
4274
  function useManagedBalances(options) {
4134
4275
  const client = useAggClient();
4135
4276
  const { enabled = true, mode } = options != null ? options : {};
4136
- const query = useQuery2({
4277
+ const query = useQuery3({
4137
4278
  queryKey: executionKeys.balances(mode),
4138
4279
  queryFn: () => client.getManagedBalances(mode ? { mode } : void 0),
4139
4280
  enabled,
4140
4281
  staleTime: 1e4,
4282
+ // A matched fill can precede settlement and the API's next balance snapshot.
4283
+ // Keep visible clients converging even if that first invalidation reads old cash.
4284
+ refetchInterval: mode === "paper" ? false : 5e3,
4285
+ refetchIntervalInBackground: false,
4141
4286
  gcTime: 5 * 6e4,
4142
4287
  retry: 1
4143
4288
  });
@@ -4147,12 +4292,12 @@ function useManagedBalances(options) {
4147
4292
  }
4148
4293
 
4149
4294
  // src/execution/use-positions.ts
4150
- import { useQuery as useQuery3 } from "@tanstack/react-query";
4295
+ import { useQuery as useQuery4 } from "@tanstack/react-query";
4151
4296
  function usePositions(options) {
4152
4297
  var _a, _b, _c, _d;
4153
4298
  const client = useAggClient();
4154
4299
  const { enabled = true, cursor, limit, status, mode } = options != null ? options : {};
4155
- const query = useQuery3({
4300
+ const query = useQuery4({
4156
4301
  queryKey: executionKeys.positions(cursor, limit, status, mode),
4157
4302
  queryFn: () => client.getPositions(__spreadValues({ cursor, limit, status }, mode ? { mode } : {})),
4158
4303
  enabled,
@@ -4168,8 +4313,8 @@ function usePositions(options) {
4168
4313
  }
4169
4314
 
4170
4315
  // src/execution/use-deposit-addresses.ts
4171
- import { useEffect as useEffect4, useMemo as useMemo6, useRef as useRef4, useState as useState4 } from "react";
4172
- import { useQuery as useQuery4 } from "@tanstack/react-query";
4316
+ import { useEffect as useEffect4, useMemo as useMemo7, useRef as useRef4, useState as useState4 } from "react";
4317
+ import { useQuery as useQuery5 } from "@tanstack/react-query";
4173
4318
  var SVM_CHAIN_IDS = /* @__PURE__ */ new Set([792703809]);
4174
4319
  function getDepositAddress(chainId, data) {
4175
4320
  return chainId !== void 0 && SVM_CHAIN_IDS.has(chainId) ? data.svmAddress : data.evmAddress;
@@ -4193,7 +4338,7 @@ function useDepositAddresses(options) {
4193
4338
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4194
4339
  };
4195
4340
  }, [enabled, poll, timeoutMs]);
4196
- const query = useQuery4({
4341
+ const query = useQuery5({
4197
4342
  queryKey: executionKeys.depositAddresses(),
4198
4343
  queryFn: () => client.getDepositAddresses(),
4199
4344
  enabled,
@@ -4209,9 +4354,9 @@ function useDepositAddresses(options) {
4209
4354
  });
4210
4355
  const isReady = ((_a = query.data) == null ? void 0 : _a.ready) === true;
4211
4356
  const readyData = isReady ? query.data : void 0;
4212
- const evmAddress = useMemo6(() => readyData == null ? void 0 : readyData.evmAddress, [readyData]);
4213
- const svmAddress = useMemo6(() => readyData == null ? void 0 : readyData.svmAddress, [readyData]);
4214
- const supportedChains = useMemo6(() => readyData == null ? void 0 : readyData.supportedChains, [readyData]);
4357
+ const evmAddress = useMemo7(() => readyData == null ? void 0 : readyData.evmAddress, [readyData]);
4358
+ const svmAddress = useMemo7(() => readyData == null ? void 0 : readyData.svmAddress, [readyData]);
4359
+ const supportedChains = useMemo7(() => readyData == null ? void 0 : readyData.supportedChains, [readyData]);
4215
4360
  return __spreadProps(__spreadValues({}, query), {
4216
4361
  isReady,
4217
4362
  isTimedOut,
@@ -4225,10 +4370,10 @@ function useDepositAddresses(options) {
4225
4370
  }
4226
4371
 
4227
4372
  // src/execution/use-sync-balances.ts
4228
- import { useMutation as useMutation5, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
4373
+ import { useMutation as useMutation5, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
4229
4374
  function useSyncBalances(options) {
4230
4375
  const client = useAggClient();
4231
- const queryClient = useQueryClient7();
4376
+ const queryClient = useQueryClient8();
4232
4377
  return useMutation5({
4233
4378
  mutationFn: () => client.syncManagedBalances(),
4234
4379
  onSuccess: () => {
@@ -4957,13 +5102,13 @@ function useExecutionProgress({
4957
5102
  }
4958
5103
 
4959
5104
  // src/execution/use-balance-refill-policies.ts
4960
- import { useMutation as useMutation6, useQuery as useQuery5, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
5105
+ import { useMutation as useMutation6, useQuery as useQuery6, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
4961
5106
  function useBalanceRefillPolicies(options) {
4962
5107
  var _a, _b;
4963
5108
  const client = useAggClient();
4964
- const queryClient = useQueryClient8();
5109
+ const queryClient = useQueryClient9();
4965
5110
  const queryKey = executionKeys.balanceRefillPolicies();
4966
- const query = useQuery5({
5111
+ const query = useQuery6({
4967
5112
  queryKey,
4968
5113
  queryFn: () => client.getBalanceRefillPolicies(),
4969
5114
  enabled: (_a = options == null ? void 0 : options.enabled) != null ? _a : true,
@@ -5042,7 +5187,7 @@ var computeClosedPositionTotals = (group) => {
5042
5187
  };
5043
5188
 
5044
5189
  // src/execution/use-redeem.ts
5045
- import { useMutation as useMutation7, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
5190
+ import { useMutation as useMutation7, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
5046
5191
  var RedeemRejectedError = class extends Error {
5047
5192
  constructor(message, response) {
5048
5193
  super(message);
@@ -5053,10 +5198,11 @@ var RedeemRejectedError = class extends Error {
5053
5198
  var isLegRejected = (status) => status === "ineligible" || status === "rejected";
5054
5199
  var useRedeem = () => {
5055
5200
  const client = useAggClient();
5056
- const queryClient = useQueryClient9();
5201
+ const queryClient = useQueryClient10();
5202
+ const { executionMode } = useResolvedExecutionMode();
5057
5203
  return useMutation7({
5058
5204
  mutationFn: (body) => __async(null, null, function* () {
5059
- const response = yield client.redeem(body);
5205
+ const response = yield client.redeem(__spreadValues({ mode: executionMode }, body));
5060
5206
  if (response.results.length > 0 && response.results.every((r) => isLegRejected(r.status))) {
5061
5207
  const reasons = response.results.map((r) => r.reason).filter((r) => Boolean(r));
5062
5208
  const message = reasons.length > 0 ? reasons.join("; ") : "Redeem rejected";
@@ -5076,7 +5222,7 @@ var useOnRedeemEvent2 = (listener) => {
5076
5222
  };
5077
5223
 
5078
5224
  // src/execution/use-redeem-eligible-count.ts
5079
- import { useQuery as useQuery6 } from "@tanstack/react-query";
5225
+ import { useQuery as useQuery7 } from "@tanstack/react-query";
5080
5226
  var CLAIMABLE_COUNT_PAGE_LIMIT = 100;
5081
5227
  var getClaimablePositionsCount = (client) => __async(null, null, function* () {
5082
5228
  var _a;
@@ -5101,7 +5247,7 @@ var useRedeemEligibleCount = () => {
5101
5247
  var _a;
5102
5248
  const client = useAggClient();
5103
5249
  const { isAuthenticated } = useAggAuthState();
5104
- const query = useQuery6({
5250
+ const query = useQuery7({
5105
5251
  queryKey: executionKeys.claimablePositionsCount(),
5106
5252
  queryFn: () => getClaimablePositionsCount(client),
5107
5253
  enabled: isAuthenticated,
@@ -5113,7 +5259,7 @@ var useRedeemEligibleCount = () => {
5113
5259
  };
5114
5260
 
5115
5261
  // src/execution/use-redeem-lifecycles.ts
5116
- import { useEffect as useEffect6, useMemo as useMemo7, useState as useState6 } from "react";
5262
+ import { useEffect as useEffect6, useMemo as useMemo8, useState as useState6 } from "react";
5117
5263
  var computeDerivedState = (legs, expectedCount) => {
5118
5264
  const legCount = Object.keys(legs).length;
5119
5265
  let allTerminal = legCount === expectedCount;
@@ -5164,7 +5310,7 @@ var seedState = (input) => {
5164
5310
  };
5165
5311
  };
5166
5312
  function useRedeemLifecycles(inputs) {
5167
- const inputsByRedeemId = useMemo7(() => {
5313
+ const inputsByRedeemId = useMemo8(() => {
5168
5314
  const map = {};
5169
5315
  for (const input of inputs) {
5170
5316
  map[input.redeemId] = input;
@@ -5196,7 +5342,7 @@ function useRedeemLifecycles(inputs) {
5196
5342
  });
5197
5343
  }, [inputsByRedeemId]);
5198
5344
  useOnRedeemEvent(
5199
- useMemo7(() => {
5345
+ useMemo8(() => {
5200
5346
  if (Object.keys(inputsByRedeemId).length === 0) return null;
5201
5347
  return (event) => {
5202
5348
  const input = inputsByRedeemId[event.redeemId];
@@ -5231,7 +5377,7 @@ function useRedeemLifecycles(inputs) {
5231
5377
  }
5232
5378
 
5233
5379
  // src/execution/use-redeem-lifecycle.ts
5234
- import { useMemo as useMemo8 } from "react";
5380
+ import { useMemo as useMemo9 } from "react";
5235
5381
  var INITIAL_STATE = {
5236
5382
  pending: true,
5237
5383
  terminal: false,
@@ -5242,7 +5388,7 @@ var INITIAL_STATE = {
5242
5388
  };
5243
5389
  function useRedeemLifecycle(input) {
5244
5390
  var _a;
5245
- const inputs = useMemo8(() => input ? [input] : [], [input]);
5391
+ const inputs = useMemo9(() => input ? [input] : [], [input]);
5246
5392
  const map = useRedeemLifecycles(inputs);
5247
5393
  if (!input) return INITIAL_STATE;
5248
5394
  return (_a = map[input.redeemId]) != null ? _a : INITIAL_STATE;
@@ -5276,7 +5422,11 @@ export {
5276
5422
  invalidateUserActivityQueries,
5277
5423
  invalidateUserMoneyState,
5278
5424
  invalidateUserClaimState,
5425
+ useResolvedExecutionMode,
5279
5426
  AggBalanceProvider,
5427
+ appConfigQueryKey,
5428
+ useAppConfig,
5429
+ useCachedAppConfig,
5280
5430
  EventListStateProvider,
5281
5431
  useEventListState,
5282
5432
  getIntervalSeconds,