@agg-build/hooks 1.0.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.
@@ -0,0 +1,3601 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __pow = Math.pow;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+ var __async = (__this, __arguments, generator) => {
34
+ return new Promise((resolve, reject) => {
35
+ var fulfilled = (value) => {
36
+ try {
37
+ step(generator.next(value));
38
+ } catch (e) {
39
+ reject(e);
40
+ }
41
+ };
42
+ var rejected = (value) => {
43
+ try {
44
+ step(generator.throw(value));
45
+ } catch (e) {
46
+ reject(e);
47
+ }
48
+ };
49
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
50
+ step((generator = generator.apply(__this, __arguments)).next());
51
+ });
52
+ };
53
+
54
+ // ../common/src/enums/venue.ts
55
+ var Venue = /* @__PURE__ */ ((Venue2) => {
56
+ Venue2["kalshi"] = "kalshi";
57
+ Venue2["polymarket"] = "polymarket";
58
+ Venue2["limitless"] = "limitless";
59
+ Venue2["opinion"] = "opinion";
60
+ Venue2["predict"] = "predict";
61
+ Venue2["probable"] = "probable";
62
+ Venue2["myriad"] = "myriad";
63
+ Venue2["hyperliquid"] = "hyperliquid";
64
+ return Venue2;
65
+ })(Venue || {});
66
+
67
+ // ../common/src/enums/market-status.ts
68
+ var MatchStatus = /* @__PURE__ */ ((MatchStatus2) => {
69
+ MatchStatus2["pending"] = "pending";
70
+ MatchStatus2["unmatched"] = "unmatched";
71
+ MatchStatus2["review"] = "review";
72
+ MatchStatus2["matched"] = "matched";
73
+ MatchStatus2["verified"] = "verified";
74
+ MatchStatus2["rejected"] = "rejected";
75
+ return MatchStatus2;
76
+ })(MatchStatus || {});
77
+ var MatchType = /* @__PURE__ */ ((MatchType2) => {
78
+ MatchType2["manual"] = "manual";
79
+ MatchType2["llm"] = "llm";
80
+ return MatchType2;
81
+ })(MatchType || {});
82
+ var CONFIRMED_MATCH_STATUSES = ["matched" /* matched */, "verified" /* verified */];
83
+ var MarketStatus = /* @__PURE__ */ ((MarketStatus2) => {
84
+ MarketStatus2["open"] = "open";
85
+ MarketStatus2["closed"] = "closed";
86
+ MarketStatus2["resolved"] = "resolved";
87
+ MarketStatus2["unopened"] = "unopened";
88
+ MarketStatus2["paused"] = "paused";
89
+ return MarketStatus2;
90
+ })(MarketStatus || {});
91
+
92
+ // ../common/src/utils/auth.ts
93
+ function getWalletAddressFromUserProfile(user) {
94
+ var _a, _b, _c, _d, _e;
95
+ const oauthWallet = (_b = (_a = user == null ? void 0 : user.accounts) == null ? void 0 : _a.find(
96
+ (a) => a.type === "oauth" /* oauth */ && String(a.provider).toLowerCase() === "wallet"
97
+ )) != null ? _b : null;
98
+ if (oauthWallet == null ? void 0 : oauthWallet.providerAccountId) return oauthWallet.providerAccountId;
99
+ const siweAccount = (_d = (_c = user == null ? void 0 : user.accounts) == null ? void 0 : _c.find((a) => a.type === "siwe" /* siwe */)) != null ? _d : null;
100
+ return (_e = siweAccount == null ? void 0 : siweAccount.providerAccountId) != null ? _e : void 0;
101
+ }
102
+
103
+ // ../common/src/utils/validate.ts
104
+ var EMAIL_MSG = "Enter a valid email address.";
105
+ var EMAIL_MAX_LEN = 254;
106
+ function isEmail(v) {
107
+ const n = v.length;
108
+ if (n === 0 || n > EMAIL_MAX_LEN) return false;
109
+ let atIdx = -1;
110
+ for (let i = 0; i < n; i++) {
111
+ const c = v.charCodeAt(i);
112
+ if (c === 32 || c >= 9 && c <= 13) return false;
113
+ if (c === 64) {
114
+ if (atIdx !== -1) return false;
115
+ atIdx = i;
116
+ }
117
+ }
118
+ if (atIdx <= 0 || atIdx === n - 1) return false;
119
+ for (let i = atIdx + 2; i < n - 1; i++) {
120
+ if (v.charCodeAt(i) === 46) return true;
121
+ }
122
+ return false;
123
+ }
124
+ function parseEmail(raw) {
125
+ const email = raw.trim();
126
+ if (!isEmail(email)) {
127
+ return { success: false, error: { issues: [{ message: EMAIL_MSG }] } };
128
+ }
129
+ return { success: true, data: { email } };
130
+ }
131
+ function parseEmailStrict(raw) {
132
+ var _a;
133
+ const result = parseEmail(raw);
134
+ if (!result.success) {
135
+ const err = new Error(EMAIL_MSG);
136
+ err.issues = (_a = result.error) == null ? void 0 : _a.issues;
137
+ throw err;
138
+ }
139
+ return result.data;
140
+ }
141
+
142
+ // ../common/src/utils/image-url.ts
143
+ function pickVariant(px) {
144
+ if (px <= 44 /* sm */) return 44 /* sm */;
145
+ if (px <= 48 /* md */) return 48 /* md */;
146
+ if (px <= 60 /* lg */) return 60 /* lg */;
147
+ return 0 /* original */;
148
+ }
149
+ var VARIANT_RE = /\/(original|raw|\d+)\.webp$/;
150
+ function optimizedImageUrl(url, maxPx) {
151
+ if (!url) return void 0;
152
+ if (!VARIANT_RE.test(url)) return url;
153
+ const variant = pickVariant(maxPx);
154
+ const filename = variant === 0 /* original */ ? "original.webp" : `${variant}.webp`;
155
+ return url.replace(VARIANT_RE, `/${filename}`);
156
+ }
157
+
158
+ // ../common/src/utils/sort-venues.ts
159
+ var VENUE_SORT_ORDER = [
160
+ "polymarket" /* polymarket */,
161
+ "kalshi" /* kalshi */,
162
+ "opinion" /* opinion */,
163
+ "limitless" /* limitless */,
164
+ "predict" /* predict */,
165
+ "myriad" /* myriad */,
166
+ "hyperliquid" /* hyperliquid */
167
+ ];
168
+ var venueOrderIndex = new Map(VENUE_SORT_ORDER.map((v, i) => [v, i]));
169
+ var getVenueOrder = (venue) => {
170
+ var _a;
171
+ return (_a = venueOrderIndex.get(venue)) != null ? _a : VENUE_SORT_ORDER.length;
172
+ };
173
+ var sortVenues = (venues) => [...venues].sort((a, b) => getVenueOrder(a) - getVenueOrder(b));
174
+
175
+ // src/candle-store.ts
176
+ import { CandleBuilder } from "@agg-build/sdk";
177
+ var MAX_BUILDERS = 60;
178
+ var builders = /* @__PURE__ */ new Map();
179
+ function getOrCreateBuilder(marketId) {
180
+ const existing = builders.get(marketId);
181
+ if (existing) {
182
+ builders.delete(marketId);
183
+ builders.set(marketId, existing);
184
+ return existing;
185
+ }
186
+ evict();
187
+ const builder = new CandleBuilder();
188
+ builders.set(marketId, builder);
189
+ return builder;
190
+ }
191
+ function getBuilder(marketId) {
192
+ return builders.get(marketId);
193
+ }
194
+ function resetAllBuilders() {
195
+ for (const builder of builders.values()) {
196
+ builder.reset();
197
+ }
198
+ }
199
+ function evict() {
200
+ var _a;
201
+ if (builders.size < MAX_BUILDERS) return;
202
+ const oldest = builders.keys().next().value;
203
+ if (oldest) {
204
+ (_a = builders.get(oldest)) == null ? void 0 : _a.dispose();
205
+ builders.delete(oldest);
206
+ }
207
+ }
208
+
209
+ // src/core/ui-config/labels.ts
210
+ var enUsLabels = {
211
+ common: {
212
+ close: "Close",
213
+ loading: "Loading",
214
+ retry: "Retry",
215
+ errorPrefix: "Error",
216
+ tabsAria: "Tabs",
217
+ hiddenTabsAria: "Hidden tabs",
218
+ selectAria: "Select",
219
+ lineChartAria: "Line chart",
220
+ candlestickChartAria: "Candlestick chart",
221
+ lineChartSeriesSwitchAria: "Chart series switch",
222
+ lineChartSeriesOptionAria: (seriesLabel) => `Show ${seriesLabel} series`,
223
+ chartTypeSwitchAria: "Chart type switch",
224
+ lineChartType: "Line",
225
+ candlestickChartType: "Candlestick"
226
+ },
227
+ venues: {
228
+ polymarket: "Polymarket",
229
+ kalshi: "Kalshi",
230
+ opinion: "Opinion",
231
+ predict: "Predict",
232
+ limitless: "Limitless",
233
+ probable: "Probable",
234
+ myriad: "Myriad",
235
+ hyperliquid: "Hyperliquid"
236
+ },
237
+ auth: {
238
+ connect: (connectorName) => connectorName ? `Sign in with ${connectorName}` : "Sign in",
239
+ signIn: "Sign in",
240
+ signingIn: "Signing in...",
241
+ signInStatement: "Sign in to AGG",
242
+ emailAddress: "Email address",
243
+ continue: "Continue",
244
+ emailUnavailable: "Email sign-in is currently unavailable.",
245
+ signInWithMethod: (methodLabel) => `Sign in with ${methodLabel}`,
246
+ socialWalletNotice: "A wallet will automatically be created for you when signing up with a social account.",
247
+ learnMore: "Learn more",
248
+ dividerOr: "OR",
249
+ connectWallet: "Connect wallet",
250
+ terms: "Terms",
251
+ privacyPolicy: "Privacy Policy",
252
+ legalNoticePrefix: "By signing in, you agree to our",
253
+ legalNoticeSeparator: "&",
254
+ deposit: "Deposit",
255
+ depositGeoBlocked: "Deposits are not available in your region.",
256
+ balances: "Balances",
257
+ viewAll: "View All",
258
+ loadingBalances: "Loading balances...",
259
+ myProfile: "My Profile",
260
+ withdraw: "Withdraw",
261
+ disconnect: "Disconnect",
262
+ claimWinnings: "Claim Now",
263
+ claimableWinningsBadge: (count) => `${count} claimable winning${count === 1 ? "" : "s"}`,
264
+ claimableWinningsTooltip: (count) => `${count} position${count === 1 ? "" : "s"} ready to claim`,
265
+ walletMenuFor: (profileLabel) => `Profile menu for ${profileLabel}`
266
+ },
267
+ deposit: {
268
+ title: "Deposit",
269
+ back: "Go back",
270
+ balancePrefix: "Balance:",
271
+ balanceLabel: "Balance",
272
+ done: "Done",
273
+ methods: {
274
+ walletTitle: (walletLabel) => `Use your wallet (${walletLabel})`,
275
+ walletDescription: "Deposit instantly from your connected wallet",
276
+ cryptoTitle: "Send crypto",
277
+ cryptoDescription: "Transfer from any wallet or exchange",
278
+ cardTitle: "Deposit with card",
279
+ cardDescription: "Buy crypto instantly with your card"
280
+ },
281
+ walletFlow: {
282
+ title: "Use your wallet",
283
+ tokenLabel: "Token",
284
+ networkLabel: "Network",
285
+ amountLabel: "Amount",
286
+ max: "Max",
287
+ feePrefix: "Fee ~",
288
+ confirm: "Confirm Deposit"
289
+ },
290
+ sendCrypto: {
291
+ title: "Send crypto",
292
+ tokenLabel: "Supported token",
293
+ networkLabel: "Supported network",
294
+ depositAddressLabel: "Your deposit address",
295
+ copy: "Copy",
296
+ copied: "Copied!",
297
+ minDepositPrefix: "Min deposit",
298
+ warning: "Send only the selected token on the selected network. Wrong token or network may results in permanently lost funds.",
299
+ qrPlaceholder: "QR code placeholder",
300
+ addressLoadingTitle: "Preparing your deposit address...",
301
+ addressLoadingDescription: "We're generating your address, this usually takes a few seconds."
302
+ },
303
+ cardFlow: {
304
+ title: "Buy crypto",
305
+ amountLabel: "Amount",
306
+ currencyLabel: "Currency",
307
+ tokenLabel: "Token",
308
+ networkLabel: "Network",
309
+ destinationWalletLabel: "Destination wallet",
310
+ getQuotes: "Get Quotes",
311
+ minRequired: (amount) => `Min required: ${amount}`,
312
+ minAmountError: (amount) => `Enter at least ${amount} to continue`,
313
+ selectProviderTitle: "Select provider",
314
+ feeLabel: "Fee",
315
+ providerBadges: {
316
+ best: "BEST",
317
+ lowKyc: "LOW KYC"
318
+ },
319
+ successTitle: "Purchase complete",
320
+ successDescription: "Your USDC has been successfully added to your balance.",
321
+ pendingTitle: (provider) => `Complete your payment on ${provider}`,
322
+ pendingDescription: "Once your transaction is finished, your balance may take a few minutes to update. The deposit will appear in your activity once it's successful.",
323
+ viewActivity: "View Activity",
324
+ chooseAnotherProvider: "Choose another provider",
325
+ summary: {
326
+ provider: "Provider",
327
+ fees: "Fees"
328
+ },
329
+ loadingQuotes: "Finding the best rates...",
330
+ errorLoadingQuotesTitle: "Failed to load quotes",
331
+ errorLoadingQuotesDescription: "Please try again.",
332
+ retry: "Retry",
333
+ noQuotes: "No quotes available for this configuration.",
334
+ widgetTitle: "Complete Purchase"
335
+ },
336
+ processingTitle: "Processing deposit",
337
+ processingSteps: {
338
+ submitting: "Waiting for wallet confirmation",
339
+ submitted: "Wallet confirmed",
340
+ confirming: "Processing transaction\u2026",
341
+ updatingBalance: "Updating balance",
342
+ fundsAvailable: "Funds available"
343
+ },
344
+ successTitle: "Deposit complete",
345
+ successDescription: "Your USDC has been successfully added to your balance.",
346
+ summary: {
347
+ amountReceived: "Amount received",
348
+ network: "Network",
349
+ fromWallet: "From wallet",
350
+ gasFee: "Gas fee"
351
+ }
352
+ },
353
+ withdraw: {
354
+ title: "Withdraw",
355
+ back: "Go back",
356
+ done: "Done",
357
+ balancePrefix: "Balance:",
358
+ methods: {
359
+ cardTitle: "Withdraw with card",
360
+ cardDescription: "Withdraw funds to your card"
361
+ },
362
+ cardFlow: {
363
+ title: "Sell crypto",
364
+ amountLabel: "Amount",
365
+ currencyLabel: "Currency",
366
+ tokenLabel: "Token",
367
+ networkLabel: "Network",
368
+ destinationWalletLabel: "Destination wallet",
369
+ getQuotes: "Get Quotes",
370
+ selectProviderTitle: "Select provider",
371
+ feeLabel: "Fee",
372
+ providerBadges: {
373
+ best: "BEST",
374
+ lowKyc: "LOW KYC"
375
+ },
376
+ successTitle: "Withdrawal complete",
377
+ successDescription: "Your USDC has been successfully sent to your wallet.",
378
+ summary: {
379
+ provider: "Provider",
380
+ toWallet: "To wallet",
381
+ fees: "Fees"
382
+ }
383
+ },
384
+ summary: {
385
+ amountReceived: "Amount received",
386
+ network: "Network"
387
+ }
388
+ },
389
+ markets: {
390
+ emptyNoOpen: "No open markets available.",
391
+ emptyResolved: "This event has been resolved."
392
+ },
393
+ home: {
394
+ trending: "Trending",
395
+ topMarkets: "Top Markets",
396
+ newMarkets: "New Markets",
397
+ categoryTabsAria: "Home page category tabs"
398
+ },
399
+ userProfile: {
400
+ activity: {
401
+ depositType: "Deposit",
402
+ withdrawalType: "Withdraw",
403
+ depositTitles: {
404
+ connectedWallet: "Deposit from connected wallet",
405
+ externalWallet: "Deposit from external wallet",
406
+ card: "Deposit with card"
407
+ },
408
+ withdrawalTitle: (tokenSymbol) => `Withdraw ${tokenSymbol}`
409
+ },
410
+ positions: {
411
+ totalTradedHeader: "Total traded",
412
+ amountWonHeader: "Amount won",
413
+ claimHeader: "Claim",
414
+ claim: "Claim",
415
+ claimed: "Claimed",
416
+ pending: "Pending",
417
+ won: "Won",
418
+ lost: "Lost",
419
+ resolved: "Resolved",
420
+ marketClosed: "Market closed",
421
+ closed: "Closed"
422
+ }
423
+ },
424
+ eventList: {
425
+ matchedTab: "Matched",
426
+ loading: (title) => `Loading ${title}`,
427
+ tabsAria: (title) => `${title} tabs`,
428
+ emptyAria: "No events found",
429
+ emptyTitle: "No Events Found",
430
+ emptyDescription: "We couldn't find any events matching your filters.\nTry adjusting them or check back later.",
431
+ empty: "No events found for this tab.",
432
+ errorTitle: "Something went wrong",
433
+ errorDescription: "We're having trouble loading data right now.\nTry refreshing or check back later.",
434
+ viewResolved: "View resolved",
435
+ hideResolved: "Hide resolved"
436
+ },
437
+ search: {
438
+ placeholder: "Search...",
439
+ inputAria: "Search markets",
440
+ resultsAria: "Search results",
441
+ resultAria: (title) => `View ${title}`,
442
+ resultsSummary: (countLabel, query) => `${countLabel} search results for "${query}"`,
443
+ seeAllResults: "See all results",
444
+ loadingResults: "Loading search results",
445
+ noResultsTitle: "No markets found",
446
+ noResultsDescription: "Check your spelling or try a broader search term."
447
+ },
448
+ eventItem: {
449
+ loading: "Loading market tile",
450
+ unavailableAria: "Market tile unavailable",
451
+ unavailableTitle: "Market unavailable",
452
+ unavailableDescription: "We could not load this market right now.",
453
+ arbitrage: "Arbitrage",
454
+ priceGap: "Price Gap",
455
+ volumeSuffix: "Vol.",
456
+ marketSingular: "Market",
457
+ marketPlural: "Markets",
458
+ venueSingular: "Venue",
459
+ venuePlural: "Venues"
460
+ },
461
+ eventItemDetails: {
462
+ loading: "Loading market details",
463
+ unavailableAria: "Market details unavailable",
464
+ unavailableTitle: "Market details unavailable",
465
+ unavailableDescription: "We could not load this market right now.",
466
+ notFoundAria: "Event not found",
467
+ notFoundTitle: "Event Not Found",
468
+ notFoundDescription: "We couldn't find this event or it may no longer exist.",
469
+ chartUnavailableAria: "Chart unavailable",
470
+ chartUnavailableTitle: "Chart Unavailable",
471
+ chartUnavailableDescription: "We couldn't load live chart data for this event.",
472
+ historicalLineChartAria: (title) => `${title} historical line chart`,
473
+ outcomeSelectorAria: "Outcome selector",
474
+ yes: "Yes",
475
+ no: "No",
476
+ allTimeRange: "All",
477
+ volumeSuffix: "Vol.",
478
+ marketSelectPlaceholder: "Select market",
479
+ marketSelectSearchPlaceholder: "Search markets...",
480
+ marketSelectEmpty: "No markets found"
481
+ },
482
+ settlementSummary: {
483
+ title: "Settlement",
484
+ readFullDetails: "Read full details",
485
+ showLess: "Show less"
486
+ },
487
+ marketDetails: {
488
+ loading: "Loading market details",
489
+ unavailableAria: "Market details unavailable",
490
+ unavailableTitle: "Market details unavailable",
491
+ unavailableDescription: "We could not load this market right now.",
492
+ notFoundAria: "Market not found",
493
+ notFoundTitle: "Market Not Found",
494
+ notFoundDescription: "We couldn't find this market or it may no longer exist.",
495
+ chartUnavailableAria: "Chart unavailable",
496
+ chartUnavailableTitle: "Chart Unavailable",
497
+ chartUnavailableDescription: "We couldn't load live chart data for this market.",
498
+ orderBookEmptyAria: "No orders yet",
499
+ orderBookEmptyTitle: "No orders yet",
500
+ orderBookEmptyDescription: "Be the first to set the price on this market.",
501
+ orderBookResolvedAria: "Market resolved",
502
+ orderBookResolvedTitle: "Market Resolved",
503
+ orderBookResolvedDescription: "This market has been resolved and is no longer trading.",
504
+ orderBookUnavailableAria: "Orderbook unavailable",
505
+ orderBookUnavailableTitle: "Orderbook Unavailable",
506
+ orderBookUnavailableDescription: "We couldn't load live order data for this market.",
507
+ marketOutcomesAria: "Market outcomes",
508
+ tabsAria: "Market details tabs",
509
+ toggleOpenDetailsAria: (title) => `Open details for ${title}`,
510
+ toggleCloseDetailsAria: (title) => `Close details for ${title}`,
511
+ loadingOrderbookAria: "Loading orderbook",
512
+ loadingOrderbookLabel: "Loading orderbook...",
513
+ asks: "Asks",
514
+ bids: "Bids",
515
+ spread: "Spread",
516
+ midPrice: "Mid",
517
+ tradePrefix: "Trade",
518
+ priceColumn: "Price",
519
+ sharesColumn: "Shares",
520
+ totalColumn: "Total",
521
+ lastPrice: "Last",
522
+ graphAria: (title) => `${title} price history`,
523
+ outcomeSelectorAria: "Outcome selector",
524
+ showOutcomeAria: (label) => `Show ${label} outcome`,
525
+ viewResolved: "View resolved",
526
+ hideResolved: "Hide resolved",
527
+ volumeUnavailable: "Volume unavailable",
528
+ tabs: {
529
+ orderBook: "Order Book",
530
+ graph: "Graph",
531
+ other: "Other"
532
+ },
533
+ meta: {
534
+ status: "Status",
535
+ created: "Created",
536
+ opens: "Opens",
537
+ closes: "Closes",
538
+ markets: "Markets",
539
+ unknown: "Unknown",
540
+ venueSingular: "Venue",
541
+ venuePlural: "Venues",
542
+ volumeSuffix: "Vol."
543
+ }
544
+ },
545
+ trading: {
546
+ settlementSection: "Settlement",
547
+ settlementDifferencesTitle: "Key differences across venues",
548
+ settlementLoading: "Loading settlement",
549
+ settlementDetailsAria: (venueLabel) => `${venueLabel} settlement details`,
550
+ settlementShowMoreAria: (ctaLabel, venueLabel) => `${ctaLabel} for ${venueLabel}`,
551
+ settlementDescriptionLabel: "Description",
552
+ settlementRulesPrimaryLabel: "Resolution rules",
553
+ settlementRulesSecondaryLabel: "Additional rules",
554
+ disclaimer: "By trading, you agree to the Terms of Use of each exchange.",
555
+ geoBlockTermsLink: "Terms of Use",
556
+ geoBlockGenericMessage: "Trading is not available in your region. See ",
557
+ geoBlockVenueMessage: (venueLabel) => `Trading on ${venueLabel} is not available in your region. See `,
558
+ geoBlockMessageSuffix: " for more information.",
559
+ geoBlockModalAriaLabel: "Geo-restricted location",
560
+ geoBlockModalTitle: "Trading is not available in your current location",
561
+ geoBlockModalDescription: "You appear to be located in a restricted jurisdiction. You can still browse markets in view-only mode or return when you're in a supported region.",
562
+ geoBlockModalConfirm: "Confirm",
563
+ averagePrice: (value) => `${(value * 100).toLocaleString("en-US", {
564
+ minimumFractionDigits: 0,
565
+ maximumFractionDigits: 2
566
+ })}\xA2 avg. price`,
567
+ balance: (value) => `Balance ${value}`,
568
+ shares: (value) => `${value.toLocaleString("en-US", {
569
+ minimumFractionDigits: Number.isInteger(value) ? 0 : 2,
570
+ maximumFractionDigits: 6
571
+ })} shares`,
572
+ slippage: (value) => `Slippage: ${value}%`,
573
+ editSlippage: (value) => `Edit ${value}`,
574
+ collapseSlippage: (value) => `Collapse ${value}`,
575
+ resetSlippage: "Auto",
576
+ slippageWarning: (value) => `Slippage below ${value}% may prevent your order from executing.`,
577
+ slippageLow: (value) => `Slippage below ${value}% may prevent your order from executing.`,
578
+ slippageHigh: (value) => `Slippage above ${value}% increases the chance of an unfavorable trade.`,
579
+ showAdditionalVenues: (count) => `Show ${count} more venue${count === 1 ? "" : "s"}`,
580
+ hideAdditionalVenues: "Hide additional venues",
581
+ quoteExpired: "Quote expired. Please refresh.",
582
+ orderSubmitted: "Order submitted",
583
+ orderPending: "Your order is being processed...",
584
+ orderFailed: "Order failed. Please try again.",
585
+ orderDisabledEventResolved: "This event has been resolved.",
586
+ orderDisabledEventClosed: "This event is no longer accepting orders.",
587
+ orderDisabledEventPaused: "Trading is temporarily paused for this event.",
588
+ orderDisabledEventUnopened: "Trading has not opened yet for this event.",
589
+ orderDisabledEventUnavailable: "Trading is currently unavailable.",
590
+ orderDisabledMarketResolved: "This market has been resolved.",
591
+ orderDisabledMarketClosed: "This market is no longer accepting orders.",
592
+ orderDisabledMarketPaused: "Trading is temporarily paused for this market.",
593
+ orderDisabledMarketUnopened: "Trading has not opened yet for this market.",
594
+ orderDisabledMarketUnavailable: "Trading is currently unavailable for this market.",
595
+ orderDisabledNoMarket: "Select a market to place an order.",
596
+ orderDisabledNoOutcome: "Select an outcome to place an order.",
597
+ orderDisabledNoEvent: "No event selected.",
598
+ insufficientBalance: "Insufficient balance",
599
+ refreshQuote: "Refresh Quote",
600
+ confirmOrder: "Confirm Order",
601
+ withdrawSubmitted: "Withdrawal submitted",
602
+ withdrawProcessing: "Your withdrawal is being processed...",
603
+ estimatedCost: (value) => `Est. cost ${value}`,
604
+ partialFill: (filledSize, requestedSize) => `Only ${filledSize} of ${requestedSize} shares available at this price.`,
605
+ insufficientLiquidity: "Not enough liquidity available for this order size.",
606
+ noMarketSelected: "Select a market to place an order.",
607
+ noOrderbooks: "No live orderbooks are available for this market right now.",
608
+ quoteUnavailable: "Quote temporarily unavailable. Please try again.",
609
+ selectedVenueUnavailable: "The venue you selected is no longer available on this route. Review the updated options and try again.",
610
+ engineUnavailable: "The routing engine is temporarily unavailable. Please try again in a moment.",
611
+ insufficientInputAmount: "Trade amount is too small to cover bridging and execution costs. Increase your spend or deposit funds on the destination chain.",
612
+ minOrderSizeViolated: "Order size is below the venue minimum. Increase your spend.",
613
+ minimumOrderAmount: (amount) => `Minimum order is $${amount}`,
614
+ insufficientPosition: (totalShares) => `You only have ${totalShares} shares available to sell.`,
615
+ insufficientPositionGeneric: "You don't have enough shares to sell.",
616
+ insufficientSellDepth: "Not enough bid liquidity on the matched venues for this sell amount.",
617
+ noBidsAboveMinPrice: "No venue bids above the minimum price.",
618
+ signInRequired: "Sign in to get a routed quote",
619
+ kycRequired: "Verify to trade Kalshi",
620
+ kycNotVerifiedTooltip: "You have not been verified yet",
621
+ kycVerifyModalTitle: "Verify Your Identity",
622
+ kycVerifyModalDescription: "To start trading on Kalshi, you'll need to complete identity verification through dFlow. It only takes a few minutes and helps us stay compliant with regulations.",
623
+ kycStartVerification: "Start Verification",
624
+ kycDoItLater: "Do It Later",
625
+ kycSuccessTitle: "Verification successful",
626
+ kycSuccessDescription: "Your identity has been confirmed and you now have full access to trade on Kalshi markets.",
627
+ kycSuccessDone: "Done",
628
+ outcome: (label) => `Outcome: ${label}`,
629
+ smartRouting: "Smart Routing",
630
+ orderSplitting: "Order Splitting",
631
+ splitOrderDescription: "We split your order for the best price:",
632
+ viewAllRoutes: (count) => `View all (${count})`,
633
+ hideRoutes: "Hide routes",
634
+ venueUnavailableInRegion: "Unavailable in your region",
635
+ toWin: (tab) => tab === "buy" ? "To win" : "Payout",
636
+ buyingOutcome: (label) => `Buying ${label}`,
637
+ sellingOutcome: (label) => `Selling ${label}`,
638
+ findingBestRoute: "Finding the best route...",
639
+ submittingOrderProgress: "Submitting order...",
640
+ orderSubmittedProgress: (orderId) => `Order #${orderId.replace(/^#/, "")} submitted`,
641
+ executingOnVenue: (venueLabel) => `Executing on ${venueLabel}...`,
642
+ confirmTransactionInWallet: "Confirm the transaction in your wallet",
643
+ executionConfirmed: "Execution confirmed",
644
+ orderSuccessTitle: "Order placed",
645
+ orderSuccessDescription: "Your order has been submitted successfully.",
646
+ orderFailureTitle: "Order failed",
647
+ orderFailureDescription: (message) => message || "Something went wrong. Please try again.",
648
+ orderDone: "Done",
649
+ orderNewTrade: "New Trade",
650
+ orderShare: "Share",
651
+ orderRetry: "Try again",
652
+ orderContinue: "Continue",
653
+ orderDismiss: "Dismiss",
654
+ orderRetryVenue: (venueLabel) => `Retry ${venueLabel}`,
655
+ orderPartialFillStatus: (venueLabel) => `${venueLabel} order partially filled`,
656
+ orderVenueUnavailableStatus: (venueLabel) => `${venueLabel} unavailable, your funds have not been charged.`,
657
+ orderMarketResolvedStatus: (venueLabel) => `Market resolved on ${venueLabel} and is no longer accepting orders.`,
658
+ orderSummaryShares: "Shares",
659
+ orderSummaryAvgPrice: "Avg. price",
660
+ orderSummaryEstCost: "Est. cost",
661
+ orderSummaryVenue: "Venue",
662
+ orderComplete: "Order complete",
663
+ orderFilledAtPrice: (venueLabel, priceLabel) => `${venueLabel} order filled at ${priceLabel}`,
664
+ orderFilledAtPriceWithAmount: (venueLabel, priceLabel, amountLabel) => `${venueLabel} order filled at ${priceLabel} (${amountLabel})`,
665
+ orderPartiallyFilledAtPriceWithAmount: (venueLabel, priceLabel, amountLabel) => `${venueLabel} order partially filled at ${priceLabel} (${amountLabel})`,
666
+ orderSkip: "Skip",
667
+ orderRetryRemaining: "Retry remaining",
668
+ resolvedEarningsTitle: "Your Earnings",
669
+ resolvedSharesLabel: "Shares",
670
+ resolvedTotalPayoutLabel: "Total payout",
671
+ claimWinnings: "Claim Winnings",
672
+ boughtOutcomeAtPrice: (label, priceLabel) => `Bought ${label} at ${priceLabel}`,
673
+ soldOutcomeAtPrice: (label, priceLabel) => `Sold ${label} at ${priceLabel}`,
674
+ potentialReturnBonus: (value) => `+${value} Better Payout`,
675
+ withSmartRouting: "with Smart Routing",
676
+ buy: "Buy",
677
+ sell: "Sell",
678
+ amount: (side) => `${side === "buy" ? "Amount" : "Shares"}`
679
+ },
680
+ onboarding: {
681
+ modal: {
682
+ title: "Onboarding",
683
+ stepHowItWorks: "How it works",
684
+ stepProfileSetup: "Set up your profile",
685
+ stepConnectAccounts: "Connect accounts"
686
+ },
687
+ howItWorks: {
688
+ title: "How it works",
689
+ continue: "Continue",
690
+ features: {
691
+ createAccount: {
692
+ title: "Create Your Account",
693
+ description: "Add a few basic details to set up your account and personalize your experience on the platform."
694
+ },
695
+ linkAccounts: {
696
+ title: "Link Trading Accounts",
697
+ description: "Connect supported exchanges to unlock additional markets and liquidity. Trade across decentralized markets in one interface."
698
+ },
699
+ bestPrices: {
700
+ title: "Best Prices Always",
701
+ description: "Our real-time aggregated orderbook lets you shop lines across exchanges and automatically splits predictions to optimize trades."
702
+ },
703
+ stayInControl: {
704
+ title: "You Stay in Control",
705
+ description: "All trades are executed on the original platform. We never custody funds or move money on your behalf."
706
+ }
707
+ }
708
+ },
709
+ profileSetup: {
710
+ title: "Set up your profile",
711
+ uploadProfilePictureAria: "Upload profile picture",
712
+ profilePreviewAlt: "Profile preview",
713
+ usernameLabel: "Username",
714
+ usernamePlaceholder: "e.g. CryptoJohn",
715
+ continue: "Continue"
716
+ },
717
+ connectAccounts: {
718
+ title: "Connect Accounts",
719
+ connect: "Connect",
720
+ connectAccount: "Connect Account",
721
+ continue: "Continue",
722
+ onchainTitle: "Onchain exchanges",
723
+ onchainMobileTitle: (additionalVenueCount) => `Polymarket +${additionalVenueCount} venues`,
724
+ onchainDescription: "Trade multiple venues with one signature.",
725
+ onchainMobileDescription: "Trade multiple exchanges with one signature",
726
+ kalshiTitle: "US regulated exchanges",
727
+ kalshiMobileTitle: "Kalshi",
728
+ kalshiDescription: "Trade on regulated markets via Kalshi.",
729
+ kalshiMobileDescription: "Connect your Kalshi account"
730
+ },
731
+ connectOnchainModal: {
732
+ ariaLabel: "Connect Onchain Exchanges",
733
+ title: "Connect Onchain Exchanges",
734
+ description: "Sign in with your wallet to trade across supported\nonchain prediction markets.",
735
+ supportedVenuesLabel: "Supported venues:",
736
+ connect: "Sign In with Wallet",
737
+ cancel: "Cancel",
738
+ fallbackError: "Signature declined. Please try again."
739
+ },
740
+ connectKalshiModal: {
741
+ ariaLabel: "Connect Kalshi Account",
742
+ title: "Connect Kalshi Account",
743
+ description: "You'll generate an API key in Kalshi profile and add it to connect your account. These keys are used only to execute trades on your behalf.",
744
+ stepOne: {
745
+ label: "Step 1",
746
+ title: "Generate a Read/Write API Key in Kalshi",
747
+ instructions: {
748
+ signIn: "1. Sign in to your Kalshi account.",
749
+ goToProfilePrefix: "2. Go to your",
750
+ profileText: "Profile",
751
+ goToProfileSeparator: ":",
752
+ profileUrl: "https://kalshi.com/account/profile",
753
+ clickCreateKeyPrefix: "3. Click",
754
+ createKeyText: "Create Key",
755
+ clickCreateKeySuffix: ".",
756
+ selectPermissionsPrefix: "4. Select",
757
+ readWriteText: "Read/Write",
758
+ selectPermissionsSuffix: " permissions.",
759
+ createKey: "5. Create the key."
760
+ },
761
+ footerLineOne: "Kalshi will display your API Key ID and Private Key.",
762
+ footerLineTwo: "You'll need both for the next step."
763
+ },
764
+ stepTwo: {
765
+ label: "Step 2",
766
+ title: "Paste Your Kalshi API Credentials",
767
+ description: "These credentials are encrypted and used only to execute trades on your behalf. We can't access your funds directly.",
768
+ apiKeyIdLabel: "API Key ID",
769
+ apiKeyIdPlaceholder: "a3f9c1b2-7d4e-4c91-9f2a-8b6e1d3c5a77",
770
+ privateKeyLabel: "Private Key",
771
+ privateKeyPlaceholder: "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASC..."
772
+ },
773
+ help: {
774
+ label: "Having trouble?",
775
+ docsLinkLabel: "View Kalshi docs",
776
+ tutorialLinkLabel: "Watch tutorial video"
777
+ },
778
+ actions: {
779
+ cancel: "Cancel",
780
+ verifyConnection: "Verify Connection"
781
+ },
782
+ fallbackError: "Verification failed. Please check your credentials and try again."
783
+ }
784
+ },
785
+ eventMarketPage: {
786
+ unavailableAria: "Event market page unavailable",
787
+ unavailableTitle: "Something went wrong",
788
+ unavailableDescription: "We're having trouble loading this event right now.\nTry refreshing or check back later.",
789
+ loadingSettlementQuestion: "Loading settlement",
790
+ loadingSettlementDifferencesTitle: "Loading settlement",
791
+ loadingSettlementPlaceholder: "Loading",
792
+ tradingResolvedBadge: "Resolved",
793
+ tradingResolvedTitle: "Market resolved",
794
+ tradingResolvedDescription: "Trading has ended for this event. You can review the final result.",
795
+ tradingClosedBadge: "Closed",
796
+ tradingClosedTitle: "Trading closed",
797
+ tradingClosedDescription: "This event is no longer accepting new orders.",
798
+ tradingPausedBadge: "Paused",
799
+ tradingPausedTitle: "Trading paused",
800
+ tradingPausedDescription: "Trading is temporarily unavailable for this event.",
801
+ tradingUnopenedBadge: "Upcoming",
802
+ tradingUnopenedTitle: "Trading not open yet",
803
+ tradingUnopenedDescription: "This event is listed, but trading has not opened yet.",
804
+ tradingUnavailableBadge: "Unavailable",
805
+ tradingUnavailableTitle: "Trading unavailable",
806
+ tradingUnavailableDescription: "Trading is currently unavailable for this event.",
807
+ resolvedAt: (dateLabel) => `Resolved ${dateLabel}`,
808
+ closedAt: (dateLabel) => `Closed ${dateLabel}`,
809
+ opensAt: (dateLabel) => `Opens ${dateLabel}`,
810
+ winningOutcome: (label) => `Winning outcome: ${label}`,
811
+ resolvedOutcome: (label) => `Resolved: ${label}`,
812
+ marketDetailsAriaByDate: (dateLabel) => `Market details for ${dateLabel}`,
813
+ marketDetailsAriaByQuestion: (question) => `Market details for ${question}`
814
+ },
815
+ header: {
816
+ bannerAria: "Site header",
817
+ logoAria: "Home"
818
+ }
819
+ };
820
+ var defaultAggUiLabelsByLocale = {
821
+ "en-US": enUsLabels,
822
+ en: enUsLabels
823
+ };
824
+ var isObjectValue = (value) => {
825
+ return typeof value === "object" && value !== null && !Array.isArray(value);
826
+ };
827
+ var mergeObjectValues = (baseValue, overrideValue) => {
828
+ const mergedEntries = Object.entries(baseValue).map(([key, value]) => {
829
+ const nextOverrideValue = overrideValue[key];
830
+ if (typeof nextOverrideValue === "undefined") {
831
+ return [key, value];
832
+ }
833
+ if (isObjectValue(value) && isObjectValue(nextOverrideValue)) {
834
+ return [key, mergeObjectValues(value, nextOverrideValue)];
835
+ }
836
+ return [key, nextOverrideValue];
837
+ });
838
+ return Object.fromEntries(mergedEntries);
839
+ };
840
+ var resolveAggUiLabels = (locale) => {
841
+ var _a;
842
+ if (defaultAggUiLabelsByLocale[locale]) {
843
+ return defaultAggUiLabelsByLocale[locale];
844
+ }
845
+ const baseLocale = locale.split("-")[0];
846
+ return (_a = defaultAggUiLabelsByLocale[baseLocale]) != null ? _a : enUsLabels;
847
+ };
848
+ var mergeAggUiLabels = (baseLabels, overrides) => {
849
+ if (!overrides) return baseLabels;
850
+ return mergeObjectValues(baseLabels, overrides);
851
+ };
852
+
853
+ // src/core/ui-config/utils.ts
854
+ var DEFAULT_LOCALE = "en-US";
855
+ var createFormatters = (locale) => {
856
+ const number = new Intl.NumberFormat(locale, {
857
+ maximumFractionDigits: 2
858
+ });
859
+ const percent = new Intl.NumberFormat(locale, {
860
+ style: "percent",
861
+ minimumFractionDigits: 0,
862
+ maximumFractionDigits: 0
863
+ });
864
+ const currency = new Intl.NumberFormat(locale, {
865
+ style: "currency",
866
+ currency: "USD",
867
+ maximumFractionDigits: 2
868
+ });
869
+ const compactCurrency = new Intl.NumberFormat(locale, {
870
+ style: "currency",
871
+ currency: "USD",
872
+ notation: "compact",
873
+ maximumFractionDigits: 0
874
+ });
875
+ const date = new Intl.DateTimeFormat(locale, {
876
+ month: "long",
877
+ day: "numeric",
878
+ year: "numeric"
879
+ });
880
+ return {
881
+ formatNumber: (value) => number.format(value),
882
+ formatPercent: (value) => percent.format(value),
883
+ formatCurrency: (value) => currency.format(value),
884
+ formatCompactCurrency: (value) => compactCurrency.format(value),
885
+ formatDate: (value) => date.format(value)
886
+ };
887
+ };
888
+ var defaultFormatters = createFormatters(DEFAULT_LOCALE);
889
+ var defaultAggUiSearchConfig = {
890
+ value: "",
891
+ result: null,
892
+ isShowingAllResults: false
893
+ };
894
+ var defaultAggUiConfig = {
895
+ enableLogs: false,
896
+ enableWebsocketsLogs: false,
897
+ general: {
898
+ locale: DEFAULT_LOCALE,
899
+ theme: "light",
900
+ rootClassName: "",
901
+ labels: resolveAggUiLabels(DEFAULT_LOCALE)
902
+ },
903
+ features: {
904
+ enableAnimations: true,
905
+ enableLiveUpdates: true,
906
+ enableGradients: false
907
+ },
908
+ market: {
909
+ arbitrageThreshold: 0
910
+ },
911
+ chart: {
912
+ defaultChartTimeRange: "1D",
913
+ selectedChartTimeRange: "1D",
914
+ setSelectedChartTimeRange: () => {
915
+ }
916
+ },
917
+ formatting: defaultFormatters,
918
+ search: defaultAggUiSearchConfig
919
+ };
920
+ var mergeAggUiSearchConfig = (config) => {
921
+ var _a, _b, _c;
922
+ return {
923
+ value: (_a = config == null ? void 0 : config.value) != null ? _a : defaultAggUiSearchConfig.value,
924
+ onChange: config == null ? void 0 : config.onChange,
925
+ onSelect: config == null ? void 0 : config.onSelect,
926
+ openResults: config == null ? void 0 : config.openResults,
927
+ closeResults: config == null ? void 0 : config.closeResults,
928
+ result: (_b = config == null ? void 0 : config.result) != null ? _b : null,
929
+ isShowingAllResults: (_c = config == null ? void 0 : config.isShowingAllResults) != null ? _c : defaultAggUiSearchConfig.isShowingAllResults
930
+ };
931
+ };
932
+ var mergeAggUiConfig = (persisted, config) => {
933
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K;
934
+ const locale = (_d = (_c = (_a = config == null ? void 0 : config.general) == null ? void 0 : _a.locale) != null ? _c : (_b = persisted.general) == null ? void 0 : _b.locale) != null ? _d : DEFAULT_LOCALE;
935
+ const theme = (_h = (_g = (_e = config == null ? void 0 : config.general) == null ? void 0 : _e.theme) != null ? _g : (_f = persisted.general) == null ? void 0 : _f.theme) != null ? _h : defaultAggUiConfig.general.theme;
936
+ const formatters = createFormatters(locale);
937
+ const defaultLabels = resolveAggUiLabels(locale);
938
+ return {
939
+ enableLogs: (_i = config == null ? void 0 : config.enableLogs) != null ? _i : defaultAggUiConfig.enableLogs,
940
+ enableWebsocketsLogs: (_j = config == null ? void 0 : config.enableWebsocketsLogs) != null ? _j : defaultAggUiConfig.enableWebsocketsLogs,
941
+ general: {
942
+ locale,
943
+ theme,
944
+ rootClassName: (_l = (_k = config == null ? void 0 : config.general) == null ? void 0 : _k.rootClassName) != null ? _l : defaultAggUiConfig.general.rootClassName,
945
+ labels: mergeAggUiLabels(defaultLabels, (_m = config == null ? void 0 : config.general) == null ? void 0 : _m.labels)
946
+ },
947
+ features: {
948
+ enableAnimations: (_o = (_n = config == null ? void 0 : config.features) == null ? void 0 : _n.enableAnimations) != null ? _o : defaultAggUiConfig.features.enableAnimations,
949
+ enableLiveUpdates: (_q = (_p = config == null ? void 0 : config.features) == null ? void 0 : _p.enableLiveUpdates) != null ? _q : defaultAggUiConfig.features.enableLiveUpdates,
950
+ enableGradients: (_s = (_r = config == null ? void 0 : config.features) == null ? void 0 : _r.enableGradients) != null ? _s : defaultAggUiConfig.features.enableGradients
951
+ },
952
+ market: {
953
+ arbitrageThreshold: (_u = (_t = config == null ? void 0 : config.market) == null ? void 0 : _t.arbitrageThreshold) != null ? _u : defaultAggUiConfig.market.arbitrageThreshold
954
+ },
955
+ chart: {
956
+ defaultChartTimeRange: (_w = (_v = config == null ? void 0 : config.chart) == null ? void 0 : _v.defaultChartTimeRange) != null ? _w : defaultAggUiConfig.chart.defaultChartTimeRange,
957
+ selectedChartTimeRange: (_A = (_z = (_x = persisted.chart) == null ? void 0 : _x.selectedChartTimeRange) != null ? _z : (_y = config == null ? void 0 : config.chart) == null ? void 0 : _y.defaultChartTimeRange) != null ? _A : defaultAggUiConfig.chart.defaultChartTimeRange,
958
+ setSelectedChartTimeRange: defaultAggUiConfig.chart.setSelectedChartTimeRange
959
+ },
960
+ formatting: {
961
+ formatNumber: (_C = (_B = config == null ? void 0 : config.formatting) == null ? void 0 : _B.formatNumber) != null ? _C : formatters.formatNumber,
962
+ formatPercent: (_E = (_D = config == null ? void 0 : config.formatting) == null ? void 0 : _D.formatPercent) != null ? _E : formatters.formatPercent,
963
+ formatCurrency: (_G = (_F = config == null ? void 0 : config.formatting) == null ? void 0 : _F.formatCurrency) != null ? _G : formatters.formatCurrency,
964
+ formatCompactCurrency: (_I = (_H = config == null ? void 0 : config.formatting) == null ? void 0 : _H.formatCompactCurrency) != null ? _I : formatters.formatCompactCurrency,
965
+ formatDate: (_K = (_J = config == null ? void 0 : config.formatting) == null ? void 0 : _J.formatDate) != null ? _K : formatters.formatDate
966
+ },
967
+ search: mergeAggUiSearchConfig(config == null ? void 0 : config.search),
968
+ walletActions: config == null ? void 0 : config.walletActions,
969
+ solanaRpcUrl: config == null ? void 0 : config.solanaRpcUrl
970
+ };
971
+ };
972
+
973
+ // src/execution/query-keys.ts
974
+ var executionKeys = {
975
+ all: () => ["execution"],
976
+ balances: () => ["execution", "balances"],
977
+ positions: (cursor, limit, status) => ["execution", "positions", cursor != null ? cursor : null, limit != null ? limit : null, status != null ? status : null],
978
+ positionsPrefix: () => ["execution", "positions"],
979
+ claimableClosedPositionsCount: () => ["execution", "positions", "claimable-count"],
980
+ orders: (status, cursor, limit) => ["execution", "orders", status != null ? status : null, cursor != null ? cursor : null, limit != null ? limit : null],
981
+ ordersPrefix: () => ["execution", "orders"],
982
+ depositAddresses: () => ["execution", "deposit-addresses"]
983
+ };
984
+
985
+ // src/execution/balance-invalidation.ts
986
+ var balanceQueryKeys = {
987
+ execution: () => executionKeys.balances(),
988
+ // Kept as an alias for backward compatibility with existing callers.
989
+ // The balance provider now uses the same canonical execution balances key.
990
+ provider: () => executionKeys.balances(),
991
+ venue: (venuesKey) => ["venue-balances", venuesKey],
992
+ venuePrefix: () => ["venue-balances"]
993
+ };
994
+ var BALANCE_REFRESHING_ORDER_EVENTS = /* @__PURE__ */ new Set(["filled", "partial_fill"]);
995
+ var invalidateBalanceQueries = (queryClient, options) => {
996
+ var _a;
997
+ const refetchType = (_a = options == null ? void 0 : options.refetchType) != null ? _a : "active";
998
+ const executionKey = balanceQueryKeys.execution();
999
+ const providerKey = balanceQueryKeys.provider();
1000
+ queryClient.invalidateQueries({
1001
+ queryKey: executionKey,
1002
+ refetchType
1003
+ });
1004
+ const isProviderKeyDistinct = providerKey.length !== executionKey.length || providerKey.some((segment, index) => segment !== executionKey[index]);
1005
+ if (isProviderKeyDistinct) {
1006
+ queryClient.invalidateQueries({
1007
+ queryKey: providerKey,
1008
+ refetchType
1009
+ });
1010
+ }
1011
+ queryClient.invalidateQueries({
1012
+ queryKey: balanceQueryKeys.venuePrefix(),
1013
+ refetchType
1014
+ });
1015
+ };
1016
+ var invalidatePositionQueries = (queryClient, options) => {
1017
+ var _a;
1018
+ queryClient.invalidateQueries({
1019
+ queryKey: executionKeys.positionsPrefix(),
1020
+ refetchType: (_a = options == null ? void 0 : options.refetchType) != null ? _a : "active"
1021
+ });
1022
+ };
1023
+ var shouldInvalidateBalancesForOrderEvent = (event, currentUserId) => {
1024
+ if (!BALANCE_REFRESHING_ORDER_EVENTS.has(event.event)) return false;
1025
+ if (!currentUserId) return true;
1026
+ return event.userId === currentUserId;
1027
+ };
1028
+
1029
+ // src/core/providers/balance-provider.tsx
1030
+ import { useQuery } from "@tanstack/react-query";
1031
+ import { useCallback, useContext, useMemo } from "react";
1032
+
1033
+ // src/core/providers/contexts.ts
1034
+ import { createContext } from "react";
1035
+ var AggClientContext = createContext(null);
1036
+ var AggUiContext = createContext(defaultAggUiConfig);
1037
+ var AggLabelsContext = createContext(defaultAggUiConfig.general.labels);
1038
+ var AggAuthContext = createContext(null);
1039
+ var AggBalanceContext = createContext(null);
1040
+
1041
+ // src/core/providers/balance-provider.tsx
1042
+ import { jsx } from "react/jsx-runtime";
1043
+ var CHAIN_LABELS = {
1044
+ 1: "Ethereum",
1045
+ 10: "Optimism",
1046
+ 56: "BNB",
1047
+ 137: "Polygon",
1048
+ 8453: "Base",
1049
+ 42161: "Arbitrum",
1050
+ 43114: "Avalanche",
1051
+ 11155111: "Sepolia",
1052
+ 792703809: "Solana"
1053
+ };
1054
+ var chainLabelFromId = (chainId) => {
1055
+ var _a;
1056
+ return (_a = CHAIN_LABELS[chainId]) != null ? _a : `Chain ${chainId}`;
1057
+ };
1058
+ var toTokenUnits = (raw, decimals) => {
1059
+ const numeric = Number(raw);
1060
+ if (!Number.isFinite(numeric)) return 0;
1061
+ return numeric / __pow(10, decimals);
1062
+ };
1063
+ var isUsdBasedToken = (tokenSymbol) => {
1064
+ var _a;
1065
+ return (_a = tokenSymbol == null ? void 0 : tokenSymbol.toUpperCase()) == null ? void 0 : _a.includes("USD");
1066
+ };
1067
+ var EMPTY_MANAGED_BALANCES = {
1068
+ cash: [],
1069
+ positions: []
1070
+ };
1071
+ function AggBalanceProvider({ children }) {
1072
+ const client = useContext(AggClientContext);
1073
+ const authContext = useContext(AggAuthContext);
1074
+ if (!authContext) {
1075
+ throw new Error("AggBalanceProvider must be used within an <AggAuthProvider>");
1076
+ }
1077
+ const { isAuthenticated } = authContext;
1078
+ const balancesQuery = useQuery({
1079
+ queryKey: balanceQueryKeys.provider(),
1080
+ queryFn: () => __async(null, null, function* () {
1081
+ if (!client || !isAuthenticated) {
1082
+ return EMPTY_MANAGED_BALANCES;
1083
+ }
1084
+ return client.getManagedBalances();
1085
+ }),
1086
+ enabled: Boolean(client && isAuthenticated),
1087
+ staleTime: 1e4
1088
+ });
1089
+ const managedBalancesData = balancesQuery.data;
1090
+ const managedBalances = useMemo(
1091
+ () => managedBalancesData != null ? managedBalancesData : EMPTY_MANAGED_BALANCES,
1092
+ [managedBalancesData]
1093
+ );
1094
+ const connectedVenues = useMemo(() => {
1095
+ return Array.from(new Set(managedBalances.positions.map((position) => position.venue))).sort(
1096
+ (a, b) => a.localeCompare(b)
1097
+ );
1098
+ }, [managedBalances.positions]);
1099
+ const balancesError = balancesQuery.error;
1100
+ const isBalancesLoading = balancesQuery.isLoading;
1101
+ const refetchBalances = balancesQuery.refetch;
1102
+ const totalBalance = useMemo(() => {
1103
+ const cash = managedBalances.cash;
1104
+ return cash.reduce((sum, token) => {
1105
+ if (!isUsdBasedToken(token.tokenSymbol)) return sum;
1106
+ const tokenAcrossChains = token.chains.reduce(
1107
+ (chainSum, chain) => {
1108
+ var _a;
1109
+ return chainSum + toTokenUnits(chain.balanceRaw, (_a = chain.decimals) != null ? _a : token.decimals);
1110
+ },
1111
+ 0
1112
+ );
1113
+ return sum + tokenAcrossChains;
1114
+ }, 0);
1115
+ }, [managedBalances]);
1116
+ const balanceBreakdown = useMemo(() => {
1117
+ var _a, _b;
1118
+ const byChain = /* @__PURE__ */ new Map();
1119
+ const cash = managedBalances.cash;
1120
+ for (const token of cash) {
1121
+ if (!isUsdBasedToken(token.tokenSymbol)) continue;
1122
+ for (const chain of token.chains) {
1123
+ const current = (_a = byChain.get(chain.chainId)) != null ? _a : {
1124
+ label: chainLabelFromId(chain.chainId),
1125
+ balance: 0,
1126
+ accountCount: 0
1127
+ };
1128
+ current.balance += toTokenUnits(chain.balanceRaw, (_b = chain.decimals) != null ? _b : token.decimals);
1129
+ current.accountCount += 1;
1130
+ byChain.set(chain.chainId, current);
1131
+ }
1132
+ }
1133
+ return Array.from(byChain.entries()).sort((a, b) => a[1].label.localeCompare(b[1].label)).map(([chainId, value2]) => ({
1134
+ key: String(chainId),
1135
+ label: value2.label,
1136
+ balance: value2.balance,
1137
+ accountCount: value2.accountCount,
1138
+ venues: connectedVenues.length > 0 ? connectedVenues : void 0
1139
+ }));
1140
+ }, [connectedVenues, managedBalances]);
1141
+ const positionsBalanceTotal = useMemo(() => {
1142
+ const positions = managedBalances.positions;
1143
+ return positions.reduce(
1144
+ (sum, position) => sum + (Number.isFinite(position.balance) ? position.balance : 0),
1145
+ 0
1146
+ );
1147
+ }, [managedBalances]);
1148
+ const refetch = useCallback(() => {
1149
+ if (!isAuthenticated) return;
1150
+ void refetchBalances();
1151
+ }, [isAuthenticated, refetchBalances]);
1152
+ const refetchConnectionStatus = useCallback(() => {
1153
+ if (!client || !isAuthenticated) return;
1154
+ void client.getCurrentUser();
1155
+ }, [client, isAuthenticated]);
1156
+ const value = useMemo(() => {
1157
+ if (!isAuthenticated) {
1158
+ return {
1159
+ managedBalances,
1160
+ totalBalance: 0,
1161
+ positionsBalanceTotal: 0,
1162
+ balanceBreakdown: [],
1163
+ connectedVenues: [],
1164
+ isLoading: false,
1165
+ error: null,
1166
+ refetch,
1167
+ refetchConnectionStatus
1168
+ };
1169
+ }
1170
+ const error = balancesError instanceof Error ? balancesError : balancesError ? new Error(String(balancesError)) : null;
1171
+ return {
1172
+ managedBalances,
1173
+ totalBalance,
1174
+ positionsBalanceTotal,
1175
+ balanceBreakdown,
1176
+ connectedVenues,
1177
+ isLoading: isBalancesLoading,
1178
+ error,
1179
+ refetch,
1180
+ refetchConnectionStatus
1181
+ };
1182
+ }, [
1183
+ balanceBreakdown,
1184
+ balancesError,
1185
+ connectedVenues,
1186
+ isBalancesLoading,
1187
+ isAuthenticated,
1188
+ managedBalances,
1189
+ positionsBalanceTotal,
1190
+ refetch,
1191
+ refetchConnectionStatus,
1192
+ totalBalance
1193
+ ]);
1194
+ return /* @__PURE__ */ jsx(AggBalanceContext.Provider, { value, children });
1195
+ }
1196
+
1197
+ // src/core/providers/event-list-state-context.tsx
1198
+ import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useRef } from "react";
1199
+ import { jsx as jsx2 } from "react/jsx-runtime";
1200
+ var STALENESS_THRESHOLD_MS = 5 * 60 * 1e3;
1201
+ var MAX_INITIAL_PAGES = 10;
1202
+ var EventListStateContext = createContext2(null);
1203
+ function EventListStateProvider({ children }) {
1204
+ const snapshotRef = useRef(null);
1205
+ const capture = useCallback2((state) => {
1206
+ snapshotRef.current = __spreadProps(__spreadValues({}, state), {
1207
+ loadedPageCount: Math.min(state.loadedPageCount, MAX_INITIAL_PAGES),
1208
+ capturedAt: Date.now()
1209
+ });
1210
+ }, []);
1211
+ const consume = useCallback2(() => {
1212
+ const snapshot = snapshotRef.current;
1213
+ snapshotRef.current = null;
1214
+ if (!snapshot) return null;
1215
+ const age = Date.now() - snapshot.capturedAt;
1216
+ if (age > STALENESS_THRESHOLD_MS) return null;
1217
+ return snapshot;
1218
+ }, []);
1219
+ const value = useRef({ capture, consume });
1220
+ value.current.capture = capture;
1221
+ value.current.consume = consume;
1222
+ const stableValue = useRef({
1223
+ capture: (...args) => value.current.capture(...args),
1224
+ consume: () => value.current.consume()
1225
+ }).current;
1226
+ return /* @__PURE__ */ jsx2(EventListStateContext.Provider, { value: stableValue, children });
1227
+ }
1228
+ function useEventListState() {
1229
+ const context = useContext2(EventListStateContext);
1230
+ if (!context) {
1231
+ throw new Error("useEventListState must be used within an <AggProvider>");
1232
+ }
1233
+ return context;
1234
+ }
1235
+
1236
+ // src/core/providers/hooks.ts
1237
+ import { useContext as useContext3 } from "react";
1238
+ var useAggClient = () => {
1239
+ const client = useContext3(AggClientContext);
1240
+ if (!client) {
1241
+ throw new Error("useAggClient must be used within an <AggProvider>");
1242
+ }
1243
+ return client;
1244
+ };
1245
+ var useAggUiConfig = () => {
1246
+ return useContext3(AggUiContext);
1247
+ };
1248
+ var useAggLabels = () => {
1249
+ return useContext3(AggLabelsContext);
1250
+ };
1251
+ var useAggAuthContext = () => {
1252
+ const context = useContext3(AggAuthContext);
1253
+ if (!context) {
1254
+ throw new Error("useAggAuthContext must be used within an <AggProvider>");
1255
+ }
1256
+ return context;
1257
+ };
1258
+ var useAggAuthState = useAggAuthContext;
1259
+ var useAggBalanceContext = () => {
1260
+ const context = useContext3(AggBalanceContext);
1261
+ if (!context) {
1262
+ throw new Error("useAggBalanceContext must be used within an <AggProvider>");
1263
+ }
1264
+ return context;
1265
+ };
1266
+ var useAggBalanceState = useAggBalanceContext;
1267
+ var useAggBalance = useAggBalanceContext;
1268
+ var useSdkUiConfig = useAggUiConfig;
1269
+ var useSdkLabels = useAggLabels;
1270
+ var useLabels = useAggLabels;
1271
+
1272
+ // src/core/providers/ws-provider.tsx
1273
+ import {
1274
+ createContext as createContext3,
1275
+ useCallback as useCallback3,
1276
+ useContext as useContext4,
1277
+ useEffect,
1278
+ useMemo as useMemo2,
1279
+ useRef as useRef2,
1280
+ useState
1281
+ } from "react";
1282
+ import { useQueryClient } from "@tanstack/react-query";
1283
+
1284
+ // src/market-data/chart-cache.ts
1285
+ var getIntervalSeconds = (interval) => {
1286
+ switch (interval) {
1287
+ case "1m":
1288
+ return 60;
1289
+ case "5m":
1290
+ return 5 * 60;
1291
+ case "1h":
1292
+ return 60 * 60;
1293
+ case "1d":
1294
+ return 24 * 60 * 60;
1295
+ }
1296
+ };
1297
+ var createVenueData = (venue, outcomeIds = []) => ({
1298
+ venue,
1299
+ outcomeIds,
1300
+ candles: [],
1301
+ liveCandle: null,
1302
+ lineValue: void 0,
1303
+ lastTrade: null
1304
+ });
1305
+ var sortCandles = (candles) => {
1306
+ return [...candles].sort((left, right) => left.time - right.time);
1307
+ };
1308
+ var createMarketChartData = (params) => {
1309
+ const candles = sortCandles(
1310
+ params.response.data.map((candle) => ({
1311
+ time: Math.floor(candle.t / 1e3),
1312
+ open: candle.o,
1313
+ high: candle.h,
1314
+ low: candle.l,
1315
+ close: candle.c,
1316
+ volume: candle.v,
1317
+ source: "rest"
1318
+ }))
1319
+ );
1320
+ const lastCandle = candles[candles.length - 1];
1321
+ const venues = {
1322
+ [params.response.venue]: {
1323
+ venue: params.response.venue,
1324
+ outcomeIds: [params.response.venueMarketOutcomeId],
1325
+ candles,
1326
+ liveCandle: null,
1327
+ lineValue: lastCandle == null ? void 0 : lastCandle.close,
1328
+ lastTrade: null
1329
+ }
1330
+ };
1331
+ return {
1332
+ marketId: params.marketId,
1333
+ outcomeIds: [params.response.venueMarketOutcomeId],
1334
+ primaryVenue: params.response.venue,
1335
+ interval: params.interval,
1336
+ startTs: params.startTs,
1337
+ endTs: params.endTs,
1338
+ venues
1339
+ };
1340
+ };
1341
+ var mergeMarketChartData = (params) => {
1342
+ var _a, _b;
1343
+ if (params.datasets.length === 0) {
1344
+ return null;
1345
+ }
1346
+ const primaryVenue = (_b = (_a = params.datasets[0]) == null ? void 0 : _a.primaryVenue) != null ? _b : "aggregate";
1347
+ const outcomeIds = Array.from(
1348
+ new Set(
1349
+ params.datasets.flatMap((dataset) => {
1350
+ return dataset.outcomeIds.length > 0 ? dataset.outcomeIds : [dataset.marketId];
1351
+ })
1352
+ )
1353
+ );
1354
+ const venues = params.datasets.reduce((acc, dataset) => {
1355
+ for (const [venue, venueData] of Object.entries(dataset.venues)) {
1356
+ const existingVenueData = acc[venue];
1357
+ acc[venue] = existingVenueData ? __spreadProps(__spreadValues({}, venueData), {
1358
+ outcomeIds: Array.from(
1359
+ /* @__PURE__ */ new Set([...existingVenueData.outcomeIds, ...venueData.outcomeIds])
1360
+ )
1361
+ }) : venueData;
1362
+ }
1363
+ return acc;
1364
+ }, {});
1365
+ return {
1366
+ marketId: params.marketId,
1367
+ outcomeIds,
1368
+ primaryVenue,
1369
+ interval: params.interval,
1370
+ startTs: params.startTs,
1371
+ endTs: params.endTs,
1372
+ venues
1373
+ };
1374
+ };
1375
+ var applyTradeToMarketChart = (data, trade) => {
1376
+ var _a, _b, _c;
1377
+ if (!data || data.marketId !== trade.outcomeId) {
1378
+ return data;
1379
+ }
1380
+ const currentVenue = (_a = data.venues[trade.venue]) != null ? _a : createVenueData(trade.venue);
1381
+ const intervalSeconds = getIntervalSeconds(data.interval);
1382
+ const expectedCandleTime = trade.timestamp - trade.timestamp % intervalSeconds;
1383
+ let liveCandle = currentVenue.liveCandle;
1384
+ if (liveCandle && liveCandle.time === expectedCandleTime) {
1385
+ liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
1386
+ close: trade.price,
1387
+ high: Math.max(liveCandle.high, trade.price),
1388
+ low: Math.min(liveCandle.low, trade.price),
1389
+ volume: ((_b = liveCandle.volume) != null ? _b : 0) + trade.size,
1390
+ source: "trade"
1391
+ });
1392
+ } else if (!liveCandle || liveCandle.time !== expectedCandleTime) {
1393
+ liveCandle = {
1394
+ time: expectedCandleTime,
1395
+ open: trade.price,
1396
+ high: trade.price,
1397
+ low: trade.price,
1398
+ close: trade.price,
1399
+ volume: trade.size,
1400
+ source: "trade"
1401
+ };
1402
+ }
1403
+ return __spreadProps(__spreadValues({}, data), {
1404
+ venues: __spreadProps(__spreadValues({}, data.venues), {
1405
+ [trade.venue]: __spreadProps(__spreadValues({}, currentVenue), {
1406
+ outcomeIds: currentVenue.outcomeIds.includes(trade.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, trade.outcomeId],
1407
+ liveCandle,
1408
+ lineValue: (_c = liveCandle == null ? void 0 : liveCandle.close) != null ? _c : trade.price,
1409
+ lastTrade: trade
1410
+ })
1411
+ })
1412
+ });
1413
+ };
1414
+
1415
+ // src/market-data/live-cache.ts
1416
+ var MAX_TRADES = 50;
1417
+ var createMarketLiveState = (marketId, overrides) => __spreadValues({
1418
+ marketId,
1419
+ orderbook: null,
1420
+ orderbookSnapshotVersion: 0,
1421
+ orderbookError: null,
1422
+ trades: [],
1423
+ isConnected: false,
1424
+ integrity: "ok"
1425
+ }, overrides);
1426
+ var withLiveConnectionState = (data, isConnected) => {
1427
+ if (!data) return data;
1428
+ if (data.isConnected === isConnected) return data;
1429
+ return __spreadProps(__spreadValues({}, data), {
1430
+ isConnected
1431
+ });
1432
+ };
1433
+ var withLiveOrderbook = (data, orderbook, source) => {
1434
+ const current = data != null ? data : createMarketLiveState(orderbook.marketId);
1435
+ return __spreadProps(__spreadValues({}, current), {
1436
+ orderbook,
1437
+ orderbookSnapshotVersion: source === "snapshot" ? current.orderbookSnapshotVersion + 1 : current.orderbookSnapshotVersion,
1438
+ orderbookError: null,
1439
+ integrity: "ok"
1440
+ });
1441
+ };
1442
+ var withLiveOrderbookError = (data, marketId, orderbookError) => {
1443
+ const current = data != null ? data : createMarketLiveState(marketId);
1444
+ if (current.orderbookError === orderbookError && current.marketId === marketId) {
1445
+ return current;
1446
+ }
1447
+ return __spreadProps(__spreadValues({}, current), {
1448
+ marketId,
1449
+ orderbookError
1450
+ });
1451
+ };
1452
+ var withLiveIntegrity = (data, integrity) => {
1453
+ if (!data) return data;
1454
+ if (data.integrity === integrity) return data;
1455
+ return __spreadProps(__spreadValues({}, data), {
1456
+ integrity
1457
+ });
1458
+ };
1459
+ var withLiveTrade = (data, trade) => {
1460
+ const current = data != null ? data : createMarketLiveState(trade.outcomeId);
1461
+ const trades = [trade, ...current.trades].slice(0, MAX_TRADES);
1462
+ return __spreadProps(__spreadValues({}, current), {
1463
+ trades
1464
+ });
1465
+ };
1466
+
1467
+ // src/market-data/orderbook-cache.ts
1468
+ var truncateLevels = (levels, depth) => {
1469
+ if (depth == null) return levels;
1470
+ return levels.slice(0, Math.max(0, depth));
1471
+ };
1472
+ var truncateVenueOrderbooks = (venueOrderbooks, depth) => {
1473
+ if (depth == null) return venueOrderbooks;
1474
+ return Object.fromEntries(
1475
+ Object.entries(venueOrderbooks).map(([venue, book]) => [
1476
+ venue,
1477
+ {
1478
+ bids: truncateLevels(book.bids, depth),
1479
+ asks: truncateLevels(book.asks, depth)
1480
+ }
1481
+ ])
1482
+ );
1483
+ };
1484
+ var aggregateVenueLevels = (venueOrderbooks, side) => {
1485
+ var _a;
1486
+ const levelsByPrice = /* @__PURE__ */ new Map();
1487
+ for (const [venue, orderbook] of Object.entries(venueOrderbooks)) {
1488
+ for (const level of orderbook[side]) {
1489
+ const currentLevel = levelsByPrice.get(level.price);
1490
+ if (currentLevel) {
1491
+ currentLevel.size += level.size;
1492
+ currentLevel.venues[venue] = ((_a = currentLevel.venues[venue]) != null ? _a : 0) + level.size;
1493
+ continue;
1494
+ }
1495
+ levelsByPrice.set(level.price, {
1496
+ price: level.price,
1497
+ size: level.size,
1498
+ venues: {
1499
+ [venue]: level.size
1500
+ }
1501
+ });
1502
+ }
1503
+ }
1504
+ return [...levelsByPrice.values()].sort(
1505
+ (left, right) => side === "bids" ? right.price - left.price : left.price - right.price
1506
+ );
1507
+ };
1508
+ var createMarketOrderbookDataFromVenueOrderbooks = ({
1509
+ marketId,
1510
+ venueOrderbooks,
1511
+ timestamp = Math.floor(Date.now() / 1e3)
1512
+ }) => {
1513
+ var _a, _b, _c, _d;
1514
+ const bids = aggregateVenueLevels(venueOrderbooks, "bids");
1515
+ const asks = aggregateVenueLevels(venueOrderbooks, "asks");
1516
+ const bestBid = (_b = (_a = bids[0]) == null ? void 0 : _a.price) != null ? _b : null;
1517
+ const bestAsk = (_d = (_c = asks[0]) == null ? void 0 : _c.price) != null ? _d : null;
1518
+ return {
1519
+ marketId,
1520
+ orderbook: {
1521
+ bids,
1522
+ asks
1523
+ },
1524
+ venueOrderbooks,
1525
+ venues: Object.fromEntries(
1526
+ Object.entries(venueOrderbooks).map(([venue, orderbook]) => {
1527
+ var _a2, _b2, _c2, _d2;
1528
+ return [
1529
+ venue,
1530
+ {
1531
+ bestBid: (_b2 = (_a2 = orderbook.bids[0]) == null ? void 0 : _a2.price) != null ? _b2 : null,
1532
+ bestAsk: (_d2 = (_c2 = orderbook.asks[0]) == null ? void 0 : _c2.price) != null ? _d2 : null
1533
+ }
1534
+ ];
1535
+ })
1536
+ ),
1537
+ midpoint: bestBid != null && bestAsk != null ? (bestBid + bestAsk) / 2 : null,
1538
+ spread: bestBid != null && bestAsk != null ? bestAsk - bestBid : null,
1539
+ timestamp,
1540
+ snapshotVersion: 0,
1541
+ integrity: "ok"
1542
+ };
1543
+ };
1544
+ var createMarketOrderbookDataFromState = (state, options) => {
1545
+ var _a;
1546
+ return {
1547
+ marketId: state.marketId,
1548
+ orderbook: {
1549
+ bids: state.bids,
1550
+ asks: state.asks
1551
+ },
1552
+ venueOrderbooks: state.venueOrderbooks,
1553
+ venues: state.venues,
1554
+ midpoint: state.midpoint,
1555
+ spread: state.spread,
1556
+ timestamp: state.timestamp,
1557
+ snapshotVersion: (_a = options == null ? void 0 : options.snapshotVersion) != null ? _a : 0,
1558
+ seq: state.seq,
1559
+ checksum: state.checksum,
1560
+ integrity: "ok"
1561
+ };
1562
+ };
1563
+ var marketOrderbookDataToResponse = (data) => {
1564
+ return {
1565
+ venueMarketId: data.marketId,
1566
+ orderbook: data.orderbook,
1567
+ venueOrderbooks: data.venueOrderbooks,
1568
+ venues: data.venues,
1569
+ midpoint: data.midpoint,
1570
+ spread: data.spread,
1571
+ timestamp: data.timestamp,
1572
+ seq: data.seq,
1573
+ checksum: data.checksum,
1574
+ matchedMarkets: data.matchedMarkets
1575
+ };
1576
+ };
1577
+ var withOrderbookIntegrity = (data, integrity) => {
1578
+ if (!data) return data;
1579
+ if (data.integrity === integrity) return data;
1580
+ return __spreadProps(__spreadValues({}, data), {
1581
+ integrity
1582
+ });
1583
+ };
1584
+ var applyOrderbookDepth = (data, depth) => {
1585
+ if (depth == null) return data;
1586
+ return __spreadProps(__spreadValues({}, data), {
1587
+ orderbook: {
1588
+ bids: truncateLevels(data.orderbook.bids, depth),
1589
+ asks: truncateLevels(data.orderbook.asks, depth)
1590
+ },
1591
+ venueOrderbooks: truncateVenueOrderbooks(data.venueOrderbooks, depth)
1592
+ });
1593
+ };
1594
+
1595
+ // src/market-data/query-keys.ts
1596
+ var marketDataKeys = {
1597
+ all: () => ["market-data"],
1598
+ live: (marketId) => ["market-data", "live", marketId],
1599
+ livePrefix: () => ["market-data", "live"],
1600
+ orderbook: (marketId, selectionKey, depth) => ["market-data", "orderbook", marketId, selectionKey != null ? selectionKey : null, depth != null ? depth : null],
1601
+ orderbookPrefix: (marketId) => marketId == null ? ["market-data", "orderbook"] : ["market-data", "orderbook", marketId],
1602
+ orderbookQuote: (marketId, side, size) => ["market-data", "orderbook-quote", marketId, side, size],
1603
+ chart: (marketId, interval, startTs, endTs, countBack) => ["market-data", "chart", marketId, interval, startTs, endTs, countBack != null ? countBack : null],
1604
+ chartPrefix: (marketId, interval) => {
1605
+ if (!marketId) return ["market-data", "chart"];
1606
+ if (!interval) return ["market-data", "chart", marketId];
1607
+ return ["market-data", "chart", marketId, interval];
1608
+ }
1609
+ };
1610
+
1611
+ // src/core/providers/ws-provider.tsx
1612
+ import { jsx as jsx3 } from "react/jsx-runtime";
1613
+ var AggWebSocketContext = createContext3(null);
1614
+ var AggWebSocketConnectionContext = createContext3(false);
1615
+ var AggWsUserEventContext = createContext3(null);
1616
+ var snapshotUnavailableOutcomeIdPattern = /snapshot unavailable for\s+([^\s]+)/i;
1617
+ var ORDERBOOK_DEBUG_TOP_LEVELS = 5;
1618
+ var resolveSnapshotUnavailableOutcomeId = (errorMessage) => {
1619
+ var _a;
1620
+ const matchedOutcomeId = (_a = snapshotUnavailableOutcomeIdPattern.exec(errorMessage)) == null ? void 0 : _a[1];
1621
+ if (!matchedOutcomeId) return null;
1622
+ return matchedOutcomeId.replace(/[.,;:!?]+$/, "");
1623
+ };
1624
+ var summarizeTopLevels = (levels) => {
1625
+ return levels.slice(0, ORDERBOOK_DEBUG_TOP_LEVELS).map((level) => ({ price: level.price, size: level.size }));
1626
+ };
1627
+ var debugOrderbook = (enabled, event, payload) => {
1628
+ if (!enabled) return;
1629
+ console.debug(`[AggHooks][ws-provider] ${event}`, payload);
1630
+ };
1631
+ function useAggWebSocket() {
1632
+ return useContext4(AggWebSocketContext);
1633
+ }
1634
+ function useAggWebSocketConnectionState() {
1635
+ return useContext4(AggWebSocketConnectionContext);
1636
+ }
1637
+ function useOnOrderSubmitted(callback) {
1638
+ const listeners = useContext4(AggWsUserEventContext);
1639
+ const callbackRef = useRef2(callback);
1640
+ callbackRef.current = callback;
1641
+ const hasCallback = callback !== null;
1642
+ useEffect(() => {
1643
+ if (!listeners || !callbackRef.current) return;
1644
+ const handler = (msg) => {
1645
+ var _a;
1646
+ (_a = callbackRef.current) == null ? void 0 : _a.call(callbackRef, msg);
1647
+ };
1648
+ return listeners.addOrderSubmittedListener(handler);
1649
+ }, [listeners, hasCallback]);
1650
+ }
1651
+ function useOnBalanceUpdate(callback) {
1652
+ const listeners = useContext4(AggWsUserEventContext);
1653
+ const callbackRef = useRef2(callback);
1654
+ callbackRef.current = callback;
1655
+ const hasCallback = callback !== null;
1656
+ useEffect(() => {
1657
+ if (!listeners || !callbackRef.current) return;
1658
+ const handler = (msg) => {
1659
+ var _a;
1660
+ (_a = callbackRef.current) == null ? void 0 : _a.call(callbackRef, msg);
1661
+ };
1662
+ return listeners.addBalanceUpdateListener(handler);
1663
+ }, [listeners, hasCallback]);
1664
+ }
1665
+ function useOnOrderEvent(callback) {
1666
+ const listeners = useContext4(AggWsUserEventContext);
1667
+ const callbackRef = useRef2(callback);
1668
+ callbackRef.current = callback;
1669
+ const hasCallback = callback !== null;
1670
+ useEffect(() => {
1671
+ if (!listeners || !callbackRef.current) return;
1672
+ const handler = (msg) => {
1673
+ var _a;
1674
+ (_a = callbackRef.current) == null ? void 0 : _a.call(callbackRef, msg);
1675
+ };
1676
+ return listeners.addOrderEventListener(handler);
1677
+ }, [listeners, hasCallback]);
1678
+ }
1679
+ function useOnRedeemEvent(callback) {
1680
+ const listeners = useContext4(AggWsUserEventContext);
1681
+ const callbackRef = useRef2(callback);
1682
+ callbackRef.current = callback;
1683
+ const hasCallback = callback !== null;
1684
+ useEffect(() => {
1685
+ if (!listeners || !callbackRef.current) return;
1686
+ const handler = (msg) => {
1687
+ var _a;
1688
+ (_a = callbackRef.current) == null ? void 0 : _a.call(callbackRef, msg);
1689
+ };
1690
+ return listeners.addRedeemEventListener(handler);
1691
+ }, [listeners, hasCallback]);
1692
+ }
1693
+ function AggWebSocketProvider({ children }) {
1694
+ const client = useAggClient();
1695
+ const { enableWebsocketsLogs } = useAggUiConfig();
1696
+ const queryClient = useQueryClient();
1697
+ const [ws, setWs] = useState(null);
1698
+ const [isConnected, setIsConnected] = useState(false);
1699
+ const [isClientAuthenticated, setIsClientAuthenticated] = useState(client.isAuthenticated);
1700
+ const wsRef = useRef2(null);
1701
+ const resyncDeadlineByMarketRef = useRef2(/* @__PURE__ */ new Map());
1702
+ const lastBalanceInvalidationAtRef = useRef2(0);
1703
+ useEffect(() => {
1704
+ setIsClientAuthenticated(client.isAuthenticated);
1705
+ return client.onAuthStateChange((authenticated) => {
1706
+ setIsClientAuthenticated(authenticated);
1707
+ });
1708
+ }, [client]);
1709
+ const orderSubmittedListenersRef = useRef2(/* @__PURE__ */ new Set());
1710
+ const balanceUpdateListenersRef = useRef2(/* @__PURE__ */ new Set());
1711
+ const orderEventListenersRef = useRef2(/* @__PURE__ */ new Set());
1712
+ const redeemEventListenersRef = useRef2(/* @__PURE__ */ new Set());
1713
+ const userEventListeners = useMemo2(
1714
+ () => ({
1715
+ addOrderSubmittedListener: (cb) => {
1716
+ orderSubmittedListenersRef.current.add(cb);
1717
+ return () => {
1718
+ orderSubmittedListenersRef.current.delete(cb);
1719
+ };
1720
+ },
1721
+ addBalanceUpdateListener: (cb) => {
1722
+ balanceUpdateListenersRef.current.add(cb);
1723
+ return () => {
1724
+ balanceUpdateListenersRef.current.delete(cb);
1725
+ };
1726
+ },
1727
+ addOrderEventListener: (cb) => {
1728
+ orderEventListenersRef.current.add(cb);
1729
+ return () => {
1730
+ orderEventListenersRef.current.delete(cb);
1731
+ };
1732
+ },
1733
+ addRedeemEventListener: (cb) => {
1734
+ redeemEventListenersRef.current.add(cb);
1735
+ return () => {
1736
+ redeemEventListenersRef.current.delete(cb);
1737
+ };
1738
+ }
1739
+ }),
1740
+ []
1741
+ );
1742
+ const syncOrderbookQueries = useCallback3(
1743
+ (marketId, updater) => {
1744
+ var _a;
1745
+ const queries = queryClient.getQueryCache().findAll({
1746
+ queryKey: marketDataKeys.orderbookPrefix(marketId)
1747
+ });
1748
+ for (const query of queries) {
1749
+ const depth = (_a = query.queryKey[4]) != null ? _a : null;
1750
+ queryClient.setQueryData(
1751
+ query.queryKey,
1752
+ (previous) => updater(query.queryKey, depth, previous)
1753
+ );
1754
+ }
1755
+ },
1756
+ [queryClient]
1757
+ );
1758
+ const syncChartQueries = useCallback3(
1759
+ (marketId, updater) => {
1760
+ const queries = queryClient.getQueryCache().findAll({
1761
+ queryKey: marketDataKeys.chartPrefix(marketId)
1762
+ });
1763
+ for (const query of queries) {
1764
+ queryClient.setQueryData(
1765
+ query.queryKey,
1766
+ (previous) => updater(query.queryKey, previous)
1767
+ );
1768
+ }
1769
+ },
1770
+ [queryClient]
1771
+ );
1772
+ const syncLiveQuery = useCallback3(
1773
+ (marketId, updater) => {
1774
+ queryClient.setQueryData(marketDataKeys.live(marketId), (previous) => {
1775
+ return updater(previous);
1776
+ });
1777
+ },
1778
+ [queryClient]
1779
+ );
1780
+ const invalidateBalanceCaches = useCallback3(() => {
1781
+ const now = Date.now();
1782
+ if (now - lastBalanceInvalidationAtRef.current < 750) return;
1783
+ lastBalanceInvalidationAtRef.current = now;
1784
+ invalidateBalanceQueries(queryClient);
1785
+ }, [queryClient]);
1786
+ const invalidatePositionCaches = useCallback3(() => {
1787
+ invalidatePositionQueries(queryClient);
1788
+ }, [queryClient]);
1789
+ const callbacks = useMemo2(
1790
+ () => ({
1791
+ onSnapshot: (marketId, book) => {
1792
+ const orderbook = createMarketOrderbookDataFromState(book);
1793
+ resyncDeadlineByMarketRef.current.delete(marketId);
1794
+ syncOrderbookQueries(marketId, (_queryKey, depth, previous) => {
1795
+ var _a;
1796
+ const previousSnapshotVersion = (_a = previous == null ? void 0 : previous.snapshotVersion) != null ? _a : 0;
1797
+ return applyOrderbookDepth(
1798
+ __spreadProps(__spreadValues({}, orderbook), {
1799
+ snapshotVersion: previousSnapshotVersion + 1
1800
+ }),
1801
+ depth
1802
+ );
1803
+ });
1804
+ syncLiveQuery(marketId, (previous) => withLiveOrderbook(previous, book, "snapshot"));
1805
+ if (book.midpoint != null) {
1806
+ getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
1807
+ }
1808
+ },
1809
+ onDelta: (marketId, book) => {
1810
+ var _a, _b;
1811
+ const previousLiveState = queryClient.getQueryData(marketDataKeys.live(marketId));
1812
+ debugOrderbook(enableWebsocketsLogs, "delta_received", {
1813
+ outcomeId: marketId,
1814
+ seq: book.seq,
1815
+ checksum: book.checksum,
1816
+ hasTargetOrderbook: Boolean(previousLiveState == null ? void 0 : previousLiveState.orderbook),
1817
+ beforeTop: (previousLiveState == null ? void 0 : previousLiveState.orderbook) ? {
1818
+ bids: summarizeTopLevels(previousLiveState.orderbook.bids),
1819
+ asks: summarizeTopLevels(previousLiveState.orderbook.asks)
1820
+ } : null,
1821
+ afterTop: {
1822
+ bids: summarizeTopLevels(book.bids),
1823
+ asks: summarizeTopLevels(book.asks)
1824
+ }
1825
+ });
1826
+ const orderbook = createMarketOrderbookDataFromState(book);
1827
+ resyncDeadlineByMarketRef.current.delete(marketId);
1828
+ syncOrderbookQueries(marketId, (_queryKey, depth, previous) => {
1829
+ var _a2;
1830
+ const previousSnapshotVersion = (_a2 = previous == null ? void 0 : previous.snapshotVersion) != null ? _a2 : 0;
1831
+ return applyOrderbookDepth(
1832
+ __spreadProps(__spreadValues({}, orderbook), {
1833
+ snapshotVersion: previousSnapshotVersion
1834
+ }),
1835
+ depth
1836
+ );
1837
+ });
1838
+ syncLiveQuery(marketId, (previous) => withLiveOrderbook(previous, book, "delta"));
1839
+ const nextLiveState = queryClient.getQueryData(
1840
+ marketDataKeys.live(marketId)
1841
+ );
1842
+ debugOrderbook(enableWebsocketsLogs, "delta_cached", {
1843
+ outcomeId: marketId,
1844
+ seq: (_b = (_a = nextLiveState == null ? void 0 : nextLiveState.orderbook) == null ? void 0 : _a.seq) != null ? _b : null,
1845
+ selectorTop: (nextLiveState == null ? void 0 : nextLiveState.orderbook) ? {
1846
+ bids: summarizeTopLevels(nextLiveState.orderbook.bids),
1847
+ asks: summarizeTopLevels(nextLiveState.orderbook.asks)
1848
+ } : null
1849
+ });
1850
+ if (book.midpoint != null) {
1851
+ getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
1852
+ }
1853
+ },
1854
+ onTrade: (trade) => {
1855
+ syncChartQueries(trade.outcomeId, (_queryKey, previous) => {
1856
+ return applyTradeToMarketChart(previous, trade);
1857
+ });
1858
+ syncLiveQuery(trade.outcomeId, (previous) => withLiveTrade(previous, trade));
1859
+ getOrCreateBuilder(trade.outcomeId).addTrade(trade.price, trade.size, trade.timestamp);
1860
+ },
1861
+ onHeartbeat: () => {
1862
+ const now = Date.now();
1863
+ resyncDeadlineByMarketRef.current.forEach((deadline, marketId) => {
1864
+ var _a;
1865
+ if (deadline > now) return;
1866
+ (_a = wsRef.current) == null ? void 0 : _a.resnapshot(marketId);
1867
+ resyncDeadlineByMarketRef.current.set(marketId, now + 35e3);
1868
+ });
1869
+ },
1870
+ onDiagnostics: (event) => {
1871
+ var _a;
1872
+ if (event.type !== "seq_gap" && event.type !== "checksum_mismatch") return;
1873
+ const id = (_a = event.outcomeId) != null ? _a : event.marketId;
1874
+ resyncDeadlineByMarketRef.current.set(id, Date.now() + 35e3);
1875
+ syncOrderbookQueries(
1876
+ id,
1877
+ (_queryKey, _depth, previous) => withOrderbookIntegrity(previous, "resyncing")
1878
+ );
1879
+ syncLiveQuery(id, (previous) => withLiveIntegrity(previous, "resyncing"));
1880
+ },
1881
+ onOrderSubmitted: (msg) => {
1882
+ for (const listener of orderSubmittedListenersRef.current) {
1883
+ listener(msg);
1884
+ }
1885
+ },
1886
+ onBalanceUpdate: (msg) => {
1887
+ if (isClientAuthenticated) {
1888
+ invalidateBalanceCaches();
1889
+ }
1890
+ for (const listener of balanceUpdateListenersRef.current) {
1891
+ listener(msg);
1892
+ }
1893
+ },
1894
+ onOrderEvent: (msg) => {
1895
+ var _a, _b;
1896
+ if (isClientAuthenticated) {
1897
+ const currentUserId = (_b = (_a = client.user) == null ? void 0 : _a.id) != null ? _b : null;
1898
+ if (shouldInvalidateBalancesForOrderEvent(msg, currentUserId)) {
1899
+ invalidateBalanceCaches();
1900
+ invalidatePositionCaches();
1901
+ }
1902
+ }
1903
+ for (const listener of orderEventListenersRef.current) {
1904
+ listener(msg);
1905
+ }
1906
+ },
1907
+ onRedeemEvent: (msg) => {
1908
+ for (const listener of redeemEventListenersRef.current) {
1909
+ listener(msg);
1910
+ }
1911
+ },
1912
+ onError: (msg) => {
1913
+ const outcomeId = resolveSnapshotUnavailableOutcomeId(msg.message);
1914
+ if (!outcomeId) return;
1915
+ syncLiveQuery(
1916
+ outcomeId,
1917
+ (previous) => withLiveOrderbookError(previous, outcomeId, msg.message)
1918
+ );
1919
+ },
1920
+ onConnectionStateChange: (connected) => {
1921
+ setIsConnected(connected);
1922
+ if (connected) {
1923
+ queryClient.invalidateQueries({
1924
+ queryKey: marketDataKeys.chartPrefix(),
1925
+ refetchType: "active"
1926
+ });
1927
+ } else {
1928
+ resetAllBuilders();
1929
+ }
1930
+ const liveQueries = queryClient.getQueryCache().findAll({
1931
+ queryKey: marketDataKeys.livePrefix()
1932
+ });
1933
+ for (const query of liveQueries) {
1934
+ queryClient.setQueryData(query.queryKey, (previous) => {
1935
+ return withLiveConnectionState(
1936
+ previous,
1937
+ connected
1938
+ );
1939
+ });
1940
+ }
1941
+ }
1942
+ }),
1943
+ [
1944
+ client,
1945
+ enableWebsocketsLogs,
1946
+ invalidateBalanceCaches,
1947
+ invalidatePositionCaches,
1948
+ isClientAuthenticated,
1949
+ queryClient,
1950
+ syncChartQueries,
1951
+ syncLiveQuery,
1952
+ syncOrderbookQueries
1953
+ ]
1954
+ );
1955
+ useEffect(() => {
1956
+ let instance = null;
1957
+ const resyncDeadlineByMarket = resyncDeadlineByMarketRef.current;
1958
+ try {
1959
+ instance = client.createWebSocket(callbacks, { enableLogs: enableWebsocketsLogs });
1960
+ } catch (e) {
1961
+ console.warn(
1962
+ "[AggUI] WebSocket connection could not be established. Ensure wsUrl is configured in createAggClient(). Real-time features (live prices, order updates) are disabled."
1963
+ );
1964
+ setWs(null);
1965
+ wsRef.current = null;
1966
+ setIsConnected(false);
1967
+ return;
1968
+ }
1969
+ setWs(instance);
1970
+ wsRef.current = instance;
1971
+ return () => {
1972
+ instance == null ? void 0 : instance.destroy();
1973
+ if (wsRef.current === instance) {
1974
+ wsRef.current = null;
1975
+ }
1976
+ resyncDeadlineByMarket.clear();
1977
+ setWs(null);
1978
+ setIsConnected(false);
1979
+ };
1980
+ }, [callbacks, client, enableWebsocketsLogs, isClientAuthenticated]);
1981
+ return /* @__PURE__ */ jsx3(AggWebSocketConnectionContext.Provider, { value: isConnected, children: /* @__PURE__ */ jsx3(AggWsUserEventContext.Provider, { value: userEventListeners, children: /* @__PURE__ */ jsx3(AggWebSocketContext.Provider, { value: ws, children }) }) });
1982
+ }
1983
+
1984
+ // src/core/ui-config/constants.ts
1985
+ var DEFAULT_AGG_ROOT_CLASS_NAME = "agg-root";
1986
+ var CHART_TIME_RANGES = ["1H", "6H", "1D", "1W", "1M", "ALL"];
1987
+
1988
+ // src/core/providers/event-trading-context.tsx
1989
+ import { createContext as createContext4, useCallback as useCallback4, useContext as useContext5, useMemo as useMemo3, useReducer, useRef as useRef3 } from "react";
1990
+ import { jsx as jsx4 } from "react/jsx-runtime";
1991
+ var OPEN_TRADING_STATE = {
1992
+ kind: "open",
1993
+ status: "open" /* open */,
1994
+ isOpen: true,
1995
+ isTradingDisabled: false,
1996
+ startsAt: null,
1997
+ endsAt: null,
1998
+ resolvesAt: null,
1999
+ winningOutcome: null
2000
+ };
2001
+ var resolveTradingStateKind = (status) => {
2002
+ if (!status || status === "open" /* open */) return "open";
2003
+ if (status === "resolved" /* resolved */) return "resolved";
2004
+ if (status === "paused" /* paused */) return "paused";
2005
+ if (status === "unopened" /* unopened */) return "unopened";
2006
+ return "closed";
2007
+ };
2008
+ var resolveMarketWinningOutcome = (market) => {
2009
+ var _a;
2010
+ if (!market) return null;
2011
+ return (_a = market.venueMarketOutcomes.find((outcome) => outcome.winner === true)) != null ? _a : null;
2012
+ };
2013
+ var AFFIRMATIVE_WINNER_LABELS = /* @__PURE__ */ new Set(["yes", "up", "buy", "long", "true"]);
2014
+ var isAffirmativeWinnerLabel = (label) => {
2015
+ if (!label) return false;
2016
+ return AFFIRMATIVE_WINNER_LABELS.has(label.trim().toLowerCase());
2017
+ };
2018
+ var resolvePreferredWinningMarket = (marketStates) => {
2019
+ var _a, _b;
2020
+ const marketWithAffirmativeWinner = marketStates.find(
2021
+ (item) => {
2022
+ var _a2;
2023
+ return isAffirmativeWinnerLabel((_a2 = item.state.winningOutcome) == null ? void 0 : _a2.label);
2024
+ }
2025
+ );
2026
+ if (marketWithAffirmativeWinner) {
2027
+ return marketWithAffirmativeWinner.market;
2028
+ }
2029
+ return (_b = (_a = marketStates.find((item) => item.state.winningOutcome)) == null ? void 0 : _a.market) != null ? _b : null;
2030
+ };
2031
+ var resolveMarketTradingState = (market) => {
2032
+ var _a, _b, _c, _d;
2033
+ if (!market) {
2034
+ return __spreadProps(__spreadValues({}, OPEN_TRADING_STATE), {
2035
+ kind: "unavailable",
2036
+ status: null,
2037
+ isOpen: false,
2038
+ isTradingDisabled: true,
2039
+ market: null
2040
+ });
2041
+ }
2042
+ const kind = resolveTradingStateKind(market.status);
2043
+ return {
2044
+ kind,
2045
+ status: (_a = market.status) != null ? _a : kind === "open" ? "open" /* open */ : null,
2046
+ isOpen: kind === "open",
2047
+ isTradingDisabled: kind !== "open",
2048
+ startsAt: (_b = market.startDate) != null ? _b : null,
2049
+ endsAt: (_c = market.endDate) != null ? _c : null,
2050
+ resolvesAt: (_d = market.resolutionDate) != null ? _d : null,
2051
+ market,
2052
+ winningOutcome: resolveMarketWinningOutcome(market)
2053
+ };
2054
+ };
2055
+ var deriveEventTradingStateKind = (marketStates) => {
2056
+ if (marketStates.length === 0) return "unavailable";
2057
+ if (marketStates.some((marketState) => marketState.kind === "open")) return "open";
2058
+ if (marketStates.every((marketState) => marketState.kind === "resolved")) return "resolved";
2059
+ if (marketStates.every((marketState) => marketState.kind === "paused")) return "paused";
2060
+ if (marketStates.every((marketState) => marketState.kind === "unopened")) return "unopened";
2061
+ return "closed";
2062
+ };
2063
+ var resolveEventStateStatus = (event, kind) => {
2064
+ if (event.status) return event.status;
2065
+ if (kind === "unavailable") return null;
2066
+ if (kind === "open") return "open" /* open */;
2067
+ if (kind === "resolved") return "resolved" /* resolved */;
2068
+ if (kind === "paused") return "paused" /* paused */;
2069
+ if (kind === "unopened") return "unopened" /* unopened */;
2070
+ return "closed" /* closed */;
2071
+ };
2072
+ var resolveEventWinningOutcome = (marketStates, preferredMarket) => {
2073
+ var _a, _b, _c, _d;
2074
+ if (preferredMarket) {
2075
+ return (_b = (_a = marketStates.find((item) => item.market.id === preferredMarket.id)) == null ? void 0 : _a.state.winningOutcome) != null ? _b : null;
2076
+ }
2077
+ return (_d = (_c = marketStates.find((item) => item.state.winningOutcome)) == null ? void 0 : _c.state.winningOutcome) != null ? _d : null;
2078
+ };
2079
+ var resolveEventTradingState = (event) => {
2080
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
2081
+ if (!(event == null ? void 0 : event.venueMarkets.length)) {
2082
+ return __spreadProps(__spreadValues({}, OPEN_TRADING_STATE), {
2083
+ kind: "unavailable",
2084
+ status: (_a = event == null ? void 0 : event.status) != null ? _a : null,
2085
+ isOpen: false,
2086
+ isTradingDisabled: true,
2087
+ startsAt: (_b = event == null ? void 0 : event.startDate) != null ? _b : null,
2088
+ endsAt: (_c = event == null ? void 0 : event.endDate) != null ? _c : null,
2089
+ displayMarkets: [],
2090
+ tradableMarkets: [],
2091
+ marketStates: [],
2092
+ primaryMarket: null
2093
+ });
2094
+ }
2095
+ const marketStates = event.venueMarkets.map((market) => ({
2096
+ market,
2097
+ state: resolveMarketTradingState(market)
2098
+ }));
2099
+ const derivedKind = deriveEventTradingStateKind(marketStates.map((item) => item.state));
2100
+ const explicitKind = event.status ? resolveTradingStateKind(event.status) : null;
2101
+ const kind = explicitKind && (explicitKind !== "open" || derivedKind === "open") ? explicitKind : derivedKind;
2102
+ const preferredWinningMarket = resolvePreferredWinningMarket(marketStates);
2103
+ const tradableMarkets = marketStates.filter((item) => item.state.isOpen).map((item) => item.market);
2104
+ const displayMarkets = kind === "open" ? tradableMarkets : event.venueMarkets;
2105
+ const primaryMarket = (_g = (_f = (_e = (_d = kind !== "open" ? preferredWinningMarket : null) != null ? _d : displayMarkets[0]) != null ? _e : tradableMarkets[0]) != null ? _f : event.venueMarkets[0]) != null ? _g : null;
2106
+ return {
2107
+ kind,
2108
+ status: resolveEventStateStatus(event, kind),
2109
+ isOpen: kind === "open",
2110
+ isTradingDisabled: kind !== "open",
2111
+ startsAt: (_i = (_h = event.startDate) != null ? _h : primaryMarket == null ? void 0 : primaryMarket.startDate) != null ? _i : null,
2112
+ endsAt: (_k = (_j = event.endDate) != null ? _j : primaryMarket == null ? void 0 : primaryMarket.endDate) != null ? _k : null,
2113
+ resolvesAt: (_n = (_m = (_l = marketStates.find((item) => item.state.resolvesAt)) == null ? void 0 : _l.state.resolvesAt) != null ? _m : primaryMarket == null ? void 0 : primaryMarket.resolutionDate) != null ? _n : null,
2114
+ winningOutcome: resolveEventWinningOutcome(marketStates, preferredWinningMarket),
2115
+ displayMarkets,
2116
+ tradableMarkets,
2117
+ marketStates,
2118
+ primaryMarket
2119
+ };
2120
+ };
2121
+ var toEventReason = (kind) => {
2122
+ var _a;
2123
+ const mapped = {
2124
+ resolved: "event_resolved",
2125
+ closed: "event_closed",
2126
+ paused: "event_paused",
2127
+ unopened: "event_unopened",
2128
+ unavailable: "event_unavailable"
2129
+ };
2130
+ return (_a = mapped[kind]) != null ? _a : "event_unavailable";
2131
+ };
2132
+ var toMarketReason = (kind) => {
2133
+ var _a;
2134
+ const mapped = {
2135
+ resolved: "market_resolved",
2136
+ closed: "market_closed",
2137
+ paused: "market_paused",
2138
+ unopened: "market_unopened",
2139
+ unavailable: "market_unavailable"
2140
+ };
2141
+ return (_a = mapped[kind]) != null ? _a : "market_unavailable";
2142
+ };
2143
+ var resolveOrderEligibility = (params) => {
2144
+ var _a;
2145
+ if (!params.event) return { canPlaceOrder: false, reason: "no_event_selected" };
2146
+ if (!params.market) return { canPlaceOrder: false, reason: "no_market_selected" };
2147
+ if (!params.outcome) return { canPlaceOrder: false, reason: "no_outcome_selected" };
2148
+ const eventState = (_a = params.eventTradingState) != null ? _a : resolveEventTradingState(params.event);
2149
+ if (eventState.isTradingDisabled) {
2150
+ return { canPlaceOrder: false, reason: toEventReason(eventState.kind) };
2151
+ }
2152
+ const marketState = resolveMarketTradingState(params.market);
2153
+ if (marketState.isTradingDisabled) {
2154
+ return { canPlaceOrder: false, reason: toMarketReason(marketState.kind) };
2155
+ }
2156
+ return { canPlaceOrder: true, reason: "eligible" };
2157
+ };
2158
+ function resolveDefaultMarket(event) {
2159
+ var _a;
2160
+ if (!(event == null ? void 0 : event.venueMarkets.length)) return null;
2161
+ const tradableMarket = event.venueMarkets.find(
2162
+ (market) => resolveMarketTradingState(market).isOpen
2163
+ );
2164
+ if (tradableMarket) return tradableMarket;
2165
+ const marketStates = event.venueMarkets.map((market) => ({
2166
+ market,
2167
+ state: resolveMarketTradingState(market)
2168
+ }));
2169
+ const preferredWinningMarket = resolvePreferredWinningMarket(marketStates);
2170
+ return (_a = preferredWinningMarket != null ? preferredWinningMarket : event.venueMarkets[0]) != null ? _a : null;
2171
+ }
2172
+ function resolveDefaultOutcome(market) {
2173
+ var _a, _b;
2174
+ const yesOutcome = market == null ? void 0 : market.venueMarketOutcomes.find((o) => {
2175
+ var _a2;
2176
+ return ((_a2 = o == null ? void 0 : o.label) == null ? void 0 : _a2.toLowerCase()) === "yes";
2177
+ });
2178
+ if (yesOutcome) return yesOutcome;
2179
+ return (_b = (_a = market == null ? void 0 : market.venueMarketOutcomes) == null ? void 0 : _a[0]) != null ? _b : null;
2180
+ }
2181
+ function findMarketById(event, marketId) {
2182
+ var _a;
2183
+ if (!event) return null;
2184
+ return (_a = event.venueMarkets.find((m) => m.id === marketId)) != null ? _a : null;
2185
+ }
2186
+ function findOutcomeById(market, outcomeId) {
2187
+ var _a;
2188
+ if (!market) return null;
2189
+ return (_a = market.venueMarketOutcomes.find((o) => o.id === outcomeId)) != null ? _a : null;
2190
+ }
2191
+ function findOutcomeAcrossMarkets(event, outcomeId) {
2192
+ if (!event) return null;
2193
+ for (const market of event.venueMarkets) {
2194
+ const outcome = market.venueMarketOutcomes.find((o) => o.id === outcomeId);
2195
+ if (outcome) return { market, outcome };
2196
+ }
2197
+ return null;
2198
+ }
2199
+ function tradingReducer(state, action) {
2200
+ var _a, _b;
2201
+ switch (action.type) {
2202
+ case "INITIALIZE_EVENT": {
2203
+ if (!action.event) {
2204
+ return { event: null, market: null, outcome: null };
2205
+ }
2206
+ const market = resolveDefaultMarket(action.event);
2207
+ return {
2208
+ event: action.event,
2209
+ market,
2210
+ outcome: resolveDefaultOutcome(market)
2211
+ };
2212
+ }
2213
+ case "SYNC_EVENT": {
2214
+ const nextEvent = action.event;
2215
+ const preservedMarket = state.market ? findMarketById(nextEvent, state.market.id) : null;
2216
+ if (preservedMarket) {
2217
+ const preservedMarketState = resolveMarketTradingState(preservedMarket);
2218
+ if (preservedMarketState.isTradingDisabled) {
2219
+ const tradableAlternative = resolveDefaultMarket(nextEvent);
2220
+ if (tradableAlternative && resolveMarketTradingState(tradableAlternative).isOpen) {
2221
+ return {
2222
+ event: nextEvent,
2223
+ market: tradableAlternative,
2224
+ outcome: resolveDefaultOutcome(tradableAlternative)
2225
+ };
2226
+ }
2227
+ }
2228
+ const preservedOutcome = state.outcome ? findOutcomeById(preservedMarket, state.outcome.id) : null;
2229
+ return {
2230
+ event: nextEvent,
2231
+ market: preservedMarket,
2232
+ outcome: preservedOutcome != null ? preservedOutcome : resolveDefaultOutcome(preservedMarket)
2233
+ };
2234
+ }
2235
+ const defaultMarket = resolveDefaultMarket(nextEvent);
2236
+ return {
2237
+ event: nextEvent,
2238
+ market: defaultMarket,
2239
+ outcome: resolveDefaultOutcome(defaultMarket)
2240
+ };
2241
+ }
2242
+ case "SELECT_MARKET": {
2243
+ const market = (_b = (_a = findMarketById(state.event, action.marketId)) != null ? _a : action.market) != null ? _b : null;
2244
+ if (!market) return state;
2245
+ if (resolveMarketTradingState(market).kind === "resolved") return state;
2246
+ return __spreadProps(__spreadValues({}, state), {
2247
+ market,
2248
+ outcome: resolveDefaultOutcome(market)
2249
+ });
2250
+ }
2251
+ case "SELECT_OUTCOME": {
2252
+ if (state.market) {
2253
+ const outcomeInCurrentMarket = findOutcomeById(state.market, action.outcomeId);
2254
+ if (outcomeInCurrentMarket) {
2255
+ if (resolveMarketTradingState(state.market).kind === "resolved") {
2256
+ return state;
2257
+ }
2258
+ return __spreadProps(__spreadValues({}, state), { outcome: outcomeInCurrentMarket });
2259
+ }
2260
+ }
2261
+ const found = findOutcomeAcrossMarkets(state.event, action.outcomeId);
2262
+ if (!found) return state;
2263
+ const targetMarketState = resolveMarketTradingState(found.market);
2264
+ if (targetMarketState.isTradingDisabled) return state;
2265
+ return __spreadProps(__spreadValues({}, state), {
2266
+ market: found.market,
2267
+ outcome: found.outcome
2268
+ });
2269
+ }
2270
+ case "SELECT_MARKET_AND_OUTCOME": {
2271
+ const market = findMarketById(state.event, action.marketId);
2272
+ if (!market) return state;
2273
+ if (resolveMarketTradingState(market).kind === "resolved") return state;
2274
+ const outcome = findOutcomeById(market, action.outcomeId);
2275
+ if (!outcome) return state;
2276
+ return __spreadProps(__spreadValues({}, state), { market, outcome });
2277
+ }
2278
+ default: {
2279
+ const _exhaustive = action;
2280
+ return _exhaustive;
2281
+ }
2282
+ }
2283
+ }
2284
+ function logAction(actionType, payload, prev, next, enableLogs) {
2285
+ var _a, _b, _c, _d, _e;
2286
+ if (!enableLogs) return;
2287
+ console.group(`[EventTrading] ${actionType}`);
2288
+ console.log("payload", payload);
2289
+ console.log("prev", prev);
2290
+ console.log("next", next);
2291
+ console.log("IDS", {
2292
+ eventId: (_a = next.event) == null ? void 0 : _a.id,
2293
+ marketIds: (_b = next.event) == null ? void 0 : _b.venueMarkets.map((m) => m.id),
2294
+ outcomeIds: (_c = next.event) == null ? void 0 : _c.venueMarkets.flatMap((m) => m.venueMarketOutcomes.map((o) => o.id)),
2295
+ selectedMarketId: (_d = next.market) == null ? void 0 : _d.id,
2296
+ selectedOutcomeId: (_e = next.outcome) == null ? void 0 : _e.id
2297
+ });
2298
+ console.groupEnd();
2299
+ }
2300
+ var initialState = {
2301
+ event: null,
2302
+ market: null,
2303
+ outcome: null
2304
+ };
2305
+ var EventTradingContext = createContext4(void 0);
2306
+ var useEventTradingContext = () => {
2307
+ return useContext5(EventTradingContext);
2308
+ };
2309
+ var EventTradingProvider = ({
2310
+ children,
2311
+ enableLogs = false
2312
+ }) => {
2313
+ const [state, rawDispatch] = useReducer(tradingReducer, initialState);
2314
+ const stateRef = useRef3(state);
2315
+ stateRef.current = state;
2316
+ const dispatch = useCallback4(
2317
+ (action) => {
2318
+ const prev = stateRef.current;
2319
+ rawDispatch(action);
2320
+ const next = tradingReducer(prev, action);
2321
+ logAction(action.type, action, prev, next, enableLogs);
2322
+ },
2323
+ [enableLogs]
2324
+ );
2325
+ const initializeFromEvent = useCallback4(
2326
+ (event) => dispatch({ type: "INITIALIZE_EVENT", event }),
2327
+ [dispatch]
2328
+ );
2329
+ const syncEvent = useCallback4(
2330
+ (event) => dispatch({ type: "SYNC_EVENT", event }),
2331
+ [dispatch]
2332
+ );
2333
+ const selectMarket = useCallback4(
2334
+ (marketId, market) => dispatch({ type: "SELECT_MARKET", marketId, market }),
2335
+ [dispatch]
2336
+ );
2337
+ const selectOutcome = useCallback4(
2338
+ (outcomeId) => dispatch({ type: "SELECT_OUTCOME", outcomeId }),
2339
+ [dispatch]
2340
+ );
2341
+ const selectMarketAndOutcome = useCallback4(
2342
+ (marketId, outcomeId) => dispatch({ type: "SELECT_MARKET_AND_OUTCOME", marketId, outcomeId }),
2343
+ [dispatch]
2344
+ );
2345
+ const value = useMemo3(
2346
+ () => {
2347
+ var _a, _b, _c, _d, _e, _f, _g, _h;
2348
+ return {
2349
+ selectedEvent: state.event,
2350
+ selectedMarket: state.market,
2351
+ selectedOutcome: state.outcome,
2352
+ selectedEventId: (_b = (_a = state.event) == null ? void 0 : _a.id) != null ? _b : null,
2353
+ selectedMarketId: (_d = (_c = state.market) == null ? void 0 : _c.id) != null ? _d : null,
2354
+ selectedOutcomeId: (_f = (_e = state.outcome) == null ? void 0 : _e.id) != null ? _f : null,
2355
+ selectedVenue: (_h = (_g = state.market) == null ? void 0 : _g.venue) != null ? _h : null,
2356
+ initializeFromEvent,
2357
+ syncEvent,
2358
+ selectMarket,
2359
+ selectOutcome,
2360
+ selectMarketAndOutcome
2361
+ };
2362
+ },
2363
+ [state, initializeFromEvent, syncEvent, selectMarket, selectOutcome, selectMarketAndOutcome]
2364
+ );
2365
+ return /* @__PURE__ */ jsx4(EventTradingContext.Provider, { value, children });
2366
+ };
2367
+
2368
+ // src/core/providers/ui-provider.tsx
2369
+ import { useCallback as useCallback5, useEffect as useEffect2, useMemo as useMemo4, useState as useState2 } from "react";
2370
+
2371
+ // src/core/ui-config/storage.ts
2372
+ var STORAGE_KEY = "agg_sdk_ui";
2373
+ var isBrowser = () => typeof window !== "undefined" && "localStorage" in window;
2374
+ var normalizeTheme = (value) => {
2375
+ if (value === "light" || value === "dark") {
2376
+ return value;
2377
+ }
2378
+ return void 0;
2379
+ };
2380
+ var normalizeChartTimeRange = (value) => {
2381
+ if (typeof value === "string" && CHART_TIME_RANGES.includes(value)) {
2382
+ return value;
2383
+ }
2384
+ return void 0;
2385
+ };
2386
+ var loadPersistedConfig = () => {
2387
+ var _a, _b, _c;
2388
+ if (!isBrowser()) return {};
2389
+ try {
2390
+ const raw = window.localStorage.getItem(STORAGE_KEY);
2391
+ if (!raw) return {};
2392
+ const parsed = JSON.parse(raw);
2393
+ const locale = typeof ((_a = parsed.general) == null ? void 0 : _a.locale) === "string" ? parsed.general.locale : void 0;
2394
+ const theme = normalizeTheme((_b = parsed.general) == null ? void 0 : _b.theme);
2395
+ const selectedChartTimeRange = normalizeChartTimeRange((_c = parsed.chart) == null ? void 0 : _c.selectedChartTimeRange);
2396
+ const result = {};
2397
+ if (locale || theme) {
2398
+ result.general = { locale, theme };
2399
+ }
2400
+ if (selectedChartTimeRange) {
2401
+ result.chart = { selectedChartTimeRange };
2402
+ }
2403
+ return result;
2404
+ } catch (e) {
2405
+ return {};
2406
+ }
2407
+ };
2408
+ var persistConfig = (config) => {
2409
+ if (!isBrowser()) return;
2410
+ const theme = normalizeTheme(config.theme);
2411
+ const selectedChartTimeRange = normalizeChartTimeRange(config.selectedChartTimeRange);
2412
+ const payload = __spreadValues({
2413
+ general: {
2414
+ locale: config.locale,
2415
+ theme
2416
+ }
2417
+ }, selectedChartTimeRange ? { chart: { selectedChartTimeRange } } : {});
2418
+ try {
2419
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
2420
+ } catch (e) {
2421
+ }
2422
+ };
2423
+
2424
+ // src/core/ui-config/theme-utils.ts
2425
+ var applyThemeToDocument = (theme) => {
2426
+ if (typeof document === "undefined") return;
2427
+ const isDark = theme === "dark";
2428
+ document.documentElement.dataset.aggTheme = theme;
2429
+ document.documentElement.classList.toggle("dark", isDark);
2430
+ document.documentElement.classList.toggle("agg-dark", isDark);
2431
+ document.documentElement.classList.toggle("light", !isDark);
2432
+ const aggRoots = document.querySelectorAll(".agg-root");
2433
+ aggRoots.forEach((rootElement) => {
2434
+ rootElement.dataset.aggTheme = theme;
2435
+ rootElement.classList.toggle("dark", isDark);
2436
+ rootElement.classList.toggle("agg-dark", isDark);
2437
+ rootElement.classList.toggle("light", !isDark);
2438
+ });
2439
+ };
2440
+
2441
+ // src/core/providers/ui-provider.tsx
2442
+ import { jsx as jsx5 } from "react/jsx-runtime";
2443
+ var hasWarnedMissingAggStyles = false;
2444
+ var warnIfAggStylesAreMissing = () => {
2445
+ if (hasWarnedMissingAggStyles) return;
2446
+ if (typeof window === "undefined" || typeof document === "undefined") return;
2447
+ const rootElement = document.querySelector(`.${DEFAULT_AGG_ROOT_CLASS_NAME}`);
2448
+ if (!rootElement) return;
2449
+ const computedStyle = window.getComputedStyle(rootElement);
2450
+ const hasSemanticColorToken = computedStyle.getPropertyValue("--agg-color-primary").trim().length > 0;
2451
+ const hasTailwindColorToken = computedStyle.getPropertyValue("--color-agg-primary").trim().length > 0;
2452
+ const hasTailwindRadiusToken = computedStyle.getPropertyValue("--radius-agg-md").trim().length > 0;
2453
+ if (hasSemanticColorToken && hasTailwindColorToken && hasTailwindRadiusToken) {
2454
+ return;
2455
+ }
2456
+ hasWarnedMissingAggStyles = true;
2457
+ console.warn(
2458
+ '[agg] Missing AGG UI styles. Import "@agg-build/ui/styles.css" once at your app entrypoint so agg token utilities resolve correctly.'
2459
+ );
2460
+ };
2461
+ function logConfig(config, enableLogs) {
2462
+ if (!enableLogs) return;
2463
+ console.group(`[AggUiProvider]`);
2464
+ console.log("config", config);
2465
+ console.groupEnd();
2466
+ }
2467
+ var getSearchStateAfterSelect = (selectedEvent) => {
2468
+ return {
2469
+ value: "",
2470
+ result: selectedEvent,
2471
+ isShowingAllResults: false
2472
+ };
2473
+ };
2474
+ var AggUiProvider = ({ config, children }) => {
2475
+ const persisted = useMemo4(() => loadPersistedConfig(), []);
2476
+ const mergedConfig = useMemo4(() => mergeAggUiConfig(persisted, config), [persisted, config]);
2477
+ const [selectedChartTimeRange, setSelectedChartTimeRange] = useState2(
2478
+ mergedConfig.chart.selectedChartTimeRange
2479
+ );
2480
+ const handleSetSelectedChartTimeRange = useCallback5((range) => {
2481
+ setSelectedChartTimeRange(range);
2482
+ }, []);
2483
+ const [searchValue, setSearchValue] = useState2(mergedConfig.search.value);
2484
+ const [searchResult, setSearchResult] = useState2(mergedConfig.search.result);
2485
+ const [isShowingAllResults, setIsShowingAllResults] = useState2(
2486
+ mergedConfig.search.isShowingAllResults
2487
+ );
2488
+ useEffect2(() => {
2489
+ setSearchValue(mergedConfig.search.value);
2490
+ }, [mergedConfig.search.value]);
2491
+ useEffect2(() => {
2492
+ setSearchResult(mergedConfig.search.result);
2493
+ }, [mergedConfig.search.result]);
2494
+ useEffect2(() => {
2495
+ setIsShowingAllResults(mergedConfig.search.isShowingAllResults);
2496
+ }, [mergedConfig.search.isShowingAllResults]);
2497
+ const handleSearchChange = useCallback5(
2498
+ (value) => {
2499
+ var _a, _b;
2500
+ setSearchValue(value);
2501
+ setSearchResult(null);
2502
+ setIsShowingAllResults(false);
2503
+ (_b = (_a = mergedConfig.search).onChange) == null ? void 0 : _b.call(_a, value);
2504
+ },
2505
+ [mergedConfig.search]
2506
+ );
2507
+ const handleSearchSelect = useCallback5(
2508
+ (value) => {
2509
+ var _a, _b;
2510
+ const nextSearchState = getSearchStateAfterSelect(value);
2511
+ setSearchValue(nextSearchState.value);
2512
+ setSearchResult(nextSearchState.result);
2513
+ setIsShowingAllResults(nextSearchState.isShowingAllResults);
2514
+ (_b = (_a = mergedConfig.search).onSelect) == null ? void 0 : _b.call(_a, value);
2515
+ },
2516
+ [mergedConfig.search]
2517
+ );
2518
+ const handleOpenResults = useCallback5(() => {
2519
+ var _a, _b;
2520
+ setIsShowingAllResults(true);
2521
+ (_b = (_a = mergedConfig.search).openResults) == null ? void 0 : _b.call(_a);
2522
+ }, [mergedConfig.search]);
2523
+ const handleCloseResults = useCallback5(() => {
2524
+ var _a, _b;
2525
+ setIsShowingAllResults(false);
2526
+ (_b = (_a = mergedConfig.search).closeResults) == null ? void 0 : _b.call(_a);
2527
+ }, [mergedConfig.search]);
2528
+ const resolvedConfig = useMemo4(() => {
2529
+ return __spreadProps(__spreadValues({}, mergedConfig), {
2530
+ chart: __spreadProps(__spreadValues({}, mergedConfig.chart), {
2531
+ selectedChartTimeRange,
2532
+ setSelectedChartTimeRange: handleSetSelectedChartTimeRange
2533
+ }),
2534
+ search: __spreadProps(__spreadValues({}, mergedConfig.search), {
2535
+ value: searchValue,
2536
+ onChange: handleSearchChange,
2537
+ onSelect: handleSearchSelect,
2538
+ openResults: handleOpenResults,
2539
+ closeResults: handleCloseResults,
2540
+ result: searchResult,
2541
+ isShowingAllResults
2542
+ })
2543
+ });
2544
+ }, [
2545
+ handleCloseResults,
2546
+ handleOpenResults,
2547
+ handleSearchChange,
2548
+ handleSearchSelect,
2549
+ handleSetSelectedChartTimeRange,
2550
+ isShowingAllResults,
2551
+ mergedConfig,
2552
+ searchResult,
2553
+ searchValue,
2554
+ selectedChartTimeRange
2555
+ ]);
2556
+ useEffect2(() => {
2557
+ persistConfig({
2558
+ locale: resolvedConfig.general.locale,
2559
+ theme: resolvedConfig.general.theme,
2560
+ selectedChartTimeRange: resolvedConfig.chart.selectedChartTimeRange
2561
+ });
2562
+ }, [
2563
+ resolvedConfig.general.locale,
2564
+ resolvedConfig.general.theme,
2565
+ resolvedConfig.chart.selectedChartTimeRange
2566
+ ]);
2567
+ useEffect2(() => {
2568
+ applyThemeToDocument(resolvedConfig.general.theme);
2569
+ }, [resolvedConfig.general.theme]);
2570
+ useEffect2(() => {
2571
+ warnIfAggStylesAreMissing();
2572
+ }, []);
2573
+ const resolvedRootClassName = [
2574
+ DEFAULT_AGG_ROOT_CLASS_NAME,
2575
+ resolvedConfig.general.theme === "dark" ? "dark" : null,
2576
+ resolvedConfig.general.rootClassName
2577
+ ].filter(Boolean).join(" ");
2578
+ logConfig(resolvedConfig, resolvedConfig.enableLogs);
2579
+ 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(
2580
+ "div",
2581
+ {
2582
+ className: resolvedRootClassName,
2583
+ "data-agg-animations": resolvedConfig.features.enableAnimations ? "true" : "false",
2584
+ "data-agg-gradients": resolvedConfig.features.enableGradients ? "true" : "false",
2585
+ "data-agg-theme": resolvedConfig.general.theme,
2586
+ children
2587
+ }
2588
+ ) }) }) });
2589
+ };
2590
+
2591
+ // src/core/providers/agg-provider.tsx
2592
+ import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
2593
+
2594
+ // src/core/providers/auth-provider.tsx
2595
+ import { useCallback as useCallback6, useContext as useContext6, useEffect as useEffect3, useMemo as useMemo5, useState as useState3 } from "react";
2596
+
2597
+ // src/core/providers/auth-utils.ts
2598
+ import { TurnstileChallengeError } from "@agg-build/sdk";
2599
+ var createPlaceholderUserProfile = (input) => {
2600
+ return {
2601
+ id: input.id,
2602
+ username: null,
2603
+ avatarUrl: null,
2604
+ externalId: null,
2605
+ isLocationBlocked: false,
2606
+ venueAccounts: null,
2607
+ accounts: [],
2608
+ wallets: []
2609
+ };
2610
+ };
2611
+ var createWalletSessionUser = (input) => {
2612
+ return __spreadProps(__spreadValues({}, createPlaceholderUserProfile({ id: input.id })), {
2613
+ accounts: [
2614
+ {
2615
+ type: "siwe" /* siwe */,
2616
+ provider: "wallet" /* wallet */,
2617
+ providerAccountId: input.address
2618
+ }
2619
+ ]
2620
+ });
2621
+ };
2622
+ var getBrowserAuthLocation = () => {
2623
+ if (typeof window === "undefined") {
2624
+ return {
2625
+ domain: "localhost",
2626
+ uri: "http://localhost"
2627
+ };
2628
+ }
2629
+ return {
2630
+ domain: window.location.host,
2631
+ uri: window.location.origin
2632
+ };
2633
+ };
2634
+ var resolveAuthCallbackUrl = (callbackUrl) => {
2635
+ return callbackUrl instanceof URL ? callbackUrl : typeof callbackUrl === "string" ? new URL(
2636
+ callbackUrl,
2637
+ typeof window === "undefined" ? "http://localhost" : window.location.origin
2638
+ ) : typeof window === "undefined" ? null : new URL(window.location.href);
2639
+ };
2640
+ var parseAuthCallbackCode = (callbackUrl) => {
2641
+ var _a;
2642
+ const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
2643
+ return (_a = resolvedUrl == null ? void 0 : resolvedUrl.searchParams.get("code")) != null ? _a : null;
2644
+ };
2645
+ var getAuthCallbackCleanupPath = (callbackUrl) => {
2646
+ const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
2647
+ if (!resolvedUrl) return null;
2648
+ const params = new URLSearchParams(resolvedUrl.search);
2649
+ params.delete("code");
2650
+ const search = params.toString();
2651
+ return `${resolvedUrl.pathname}${search ? `?${search}` : ""}`;
2652
+ };
2653
+ var exchangeAuthCallbackCode = (client, callbackUrl) => __async(null, null, function* () {
2654
+ const code = parseAuthCallbackCode(callbackUrl);
2655
+ if (!code) return null;
2656
+ const result = yield client.exchangeAuthCode(code);
2657
+ return {
2658
+ cleanupPath: getAuthCallbackCleanupPath(callbackUrl),
2659
+ user: result.user
2660
+ };
2661
+ });
2662
+ var parseAuthCallbackTokens = (callbackUrl) => {
2663
+ var _a, _b;
2664
+ const resolvedUrl = resolveAuthCallbackUrl(callbackUrl);
2665
+ if (!resolvedUrl) return null;
2666
+ const hash = resolvedUrl.hash.startsWith("#") ? resolvedUrl.hash.slice(1) : resolvedUrl.hash;
2667
+ if (!hash) return null;
2668
+ const params = new URLSearchParams(hash);
2669
+ const accessToken = params.get("access_token");
2670
+ const refreshToken = params.get("refresh_token");
2671
+ if (!accessToken || !refreshToken) return null;
2672
+ const userId = (_a = params.get("user_id")) != null ? _a : void 0;
2673
+ const tokenType = (_b = params.get("token_type")) != null ? _b : void 0;
2674
+ return {
2675
+ accessToken,
2676
+ refreshToken,
2677
+ tokenType,
2678
+ userId
2679
+ };
2680
+ };
2681
+ var createAuthCallbackSession = (tokens) => {
2682
+ return {
2683
+ accessToken: tokens.accessToken,
2684
+ refreshToken: tokens.refreshToken,
2685
+ user: tokens.userId ? createPlaceholderUserProfile({ id: tokens.userId }) : void 0
2686
+ };
2687
+ };
2688
+ var executeWalletAuthFlow = (input) => __async(null, null, function* () {
2689
+ var _a, _b;
2690
+ const address = input.options.address.trim();
2691
+ const chain = (_a = input.options.chain) != null ? _a : "ethereum";
2692
+ const provider = chain === "solana" ? "siws" : "siwe";
2693
+ const location = (_b = input.location) != null ? _b : getBrowserAuthLocation();
2694
+ const startResult = yield input.client.authStart(__spreadValues({
2695
+ provider
2696
+ }, input.options.turnstileToken ? { turnstileToken: input.options.turnstileToken } : {}));
2697
+ if (startResult.type === "challenge_required") {
2698
+ if (!startResult.siteKey) {
2699
+ throw new Error("Server returned challenge_required but no siteKey was provided.");
2700
+ }
2701
+ throw new TurnstileChallengeError(startResult.siteKey);
2702
+ }
2703
+ if (startResult.type !== "nonce") {
2704
+ throw new Error(`AGG auth start returned an unexpected "${startResult.type}" response`);
2705
+ }
2706
+ const message = chain === "solana" ? input.client.buildSiwsMessage({
2707
+ domain: location.domain,
2708
+ address,
2709
+ uri: location.uri,
2710
+ nonce: startResult.nonce,
2711
+ chainId: typeof input.options.chainId === "string" ? input.options.chainId : "mainnet",
2712
+ statement: input.options.statement
2713
+ }) : input.client.buildSiweMessage({
2714
+ domain: location.domain,
2715
+ address,
2716
+ uri: location.uri,
2717
+ nonce: startResult.nonce,
2718
+ chainId: typeof input.options.chainId === "number" ? input.options.chainId : void 0,
2719
+ statement: input.options.statement
2720
+ });
2721
+ const signature = yield input.options.signMessage(message);
2722
+ const result = yield input.client.verify({ message, signature });
2723
+ return {
2724
+ accessToken: result.accessToken,
2725
+ refreshToken: result.refreshToken,
2726
+ user: createWalletSessionUser({
2727
+ id: result.user.id,
2728
+ address
2729
+ })
2730
+ };
2731
+ });
2732
+
2733
+ // src/core/providers/auth-provider.tsx
2734
+ import { jsx as jsx6 } from "react/jsx-runtime";
2735
+ var getClientAuthSnapshot = (client) => {
2736
+ var _a;
2737
+ return {
2738
+ isAuthenticated: (_a = client == null ? void 0 : client.isAuthenticated) != null ? _a : false,
2739
+ user: client == null ? void 0 : client.user
2740
+ };
2741
+ };
2742
+ var toError = (value) => {
2743
+ return value instanceof Error ? value : new Error(String(value));
2744
+ };
2745
+ var replaceAuthCallbackUrl = (cleanupPath) => {
2746
+ if (!cleanupPath || typeof window === "undefined") return;
2747
+ window.history.replaceState(null, "", cleanupPath);
2748
+ };
2749
+ function AggAuthProvider({ children }) {
2750
+ const client = useContext6(AggClientContext);
2751
+ const snapshot = getClientAuthSnapshot(client);
2752
+ const [isAuthenticated, setIsAuthenticated] = useState3(snapshot.isAuthenticated);
2753
+ const [user, setUser] = useState3(snapshot.user);
2754
+ const [isLoading, setIsLoading] = useState3(false);
2755
+ const [error, setError] = useState3(null);
2756
+ const isWeb3User = useMemo5(() => {
2757
+ const accounts = user == null ? void 0 : user.accounts;
2758
+ if (!Array.isArray(accounts)) return true;
2759
+ return accounts.some((account) => {
2760
+ var _a;
2761
+ const provider = String((_a = account.provider) != null ? _a : "").toLowerCase();
2762
+ return provider === "wallet" || provider === "solana_wallet";
2763
+ });
2764
+ }, [user]);
2765
+ const refreshCurrentUser = useCallback6((targetClient) => __async(null, null, function* () {
2766
+ const fullUser = yield targetClient.getCurrentUser();
2767
+ setIsAuthenticated(true);
2768
+ setUser(fullUser);
2769
+ return fullUser;
2770
+ }), []);
2771
+ useEffect3(() => {
2772
+ const state = getClientAuthSnapshot(client);
2773
+ setIsAuthenticated(state.isAuthenticated);
2774
+ setUser(state.user);
2775
+ setIsLoading(false);
2776
+ setError(null);
2777
+ if (!client) return;
2778
+ if (state.isAuthenticated) {
2779
+ refreshCurrentUser(client).catch(() => {
2780
+ client.clearAccessToken();
2781
+ });
2782
+ } else if (client.authStatus === "unknown") {
2783
+ client.refreshAccessToken().then(() => refreshCurrentUser(client)).catch(() => {
2784
+ client.clearAccessToken();
2785
+ });
2786
+ }
2787
+ }, [client, refreshCurrentUser]);
2788
+ useEffect3(() => {
2789
+ if (!client) return;
2790
+ return client.onAuthStateChange((authenticated) => {
2791
+ setIsAuthenticated(authenticated);
2792
+ setUser(client.user);
2793
+ if (!authenticated) {
2794
+ setIsLoading(false);
2795
+ setError(null);
2796
+ }
2797
+ });
2798
+ }, [client]);
2799
+ const signIn = useCallback6(
2800
+ (options) => __async(null, null, function* () {
2801
+ if (!client) {
2802
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
2803
+ setError(missingClientError);
2804
+ throw missingClientError;
2805
+ }
2806
+ const address = options.address.trim();
2807
+ if (!address) {
2808
+ const missingAddressError = new Error("Wallet address is required");
2809
+ setError(missingAddressError);
2810
+ throw missingAddressError;
2811
+ }
2812
+ setIsLoading(true);
2813
+ setError(null);
2814
+ try {
2815
+ const result = yield executeWalletAuthFlow({
2816
+ client,
2817
+ options: __spreadProps(__spreadValues({}, options), {
2818
+ address
2819
+ })
2820
+ });
2821
+ client.setSession(result);
2822
+ setIsAuthenticated(true);
2823
+ setUser(result.user);
2824
+ yield refreshCurrentUser(client);
2825
+ } catch (signInError) {
2826
+ const resolvedError = toError(signInError);
2827
+ setError(resolvedError);
2828
+ throw resolvedError;
2829
+ } finally {
2830
+ setIsLoading(false);
2831
+ }
2832
+ }),
2833
+ [client, refreshCurrentUser]
2834
+ );
2835
+ const startAuth = useCallback6(
2836
+ (options) => __async(null, null, function* () {
2837
+ if (!client) {
2838
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
2839
+ setError(missingClientError);
2840
+ throw missingClientError;
2841
+ }
2842
+ setIsLoading(true);
2843
+ setError(null);
2844
+ try {
2845
+ return yield client.authStart(options);
2846
+ } catch (startAuthError) {
2847
+ const resolvedError = toError(startAuthError);
2848
+ setError(resolvedError);
2849
+ throw resolvedError;
2850
+ } finally {
2851
+ setIsLoading(false);
2852
+ }
2853
+ }),
2854
+ [client]
2855
+ );
2856
+ const setSession = useCallback6(
2857
+ (session) => __async(null, null, function* () {
2858
+ if (!client) {
2859
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
2860
+ setError(missingClientError);
2861
+ throw missingClientError;
2862
+ }
2863
+ setIsLoading(true);
2864
+ setError(null);
2865
+ try {
2866
+ client.setSession(session);
2867
+ const resolvedUser = yield refreshCurrentUser(client);
2868
+ setIsAuthenticated(true);
2869
+ setUser(resolvedUser);
2870
+ return resolvedUser;
2871
+ } catch (sessionError) {
2872
+ client.clearAccessToken();
2873
+ setIsAuthenticated(false);
2874
+ setUser(void 0);
2875
+ const resolvedError = toError(sessionError);
2876
+ setError(resolvedError);
2877
+ throw resolvedError;
2878
+ } finally {
2879
+ setIsLoading(false);
2880
+ }
2881
+ }),
2882
+ [client, refreshCurrentUser]
2883
+ );
2884
+ const handleAuthCallback = useCallback6(
2885
+ (callbackUrl) => __async(null, null, function* () {
2886
+ if (!client) {
2887
+ const missingClientError = new Error("Agg client is not configured in <AggProvider>");
2888
+ setError(missingClientError);
2889
+ throw missingClientError;
2890
+ }
2891
+ setIsLoading(true);
2892
+ setError(null);
2893
+ try {
2894
+ const exchangedSession = yield exchangeAuthCallbackCode(client, callbackUrl);
2895
+ if (exchangedSession) {
2896
+ const resolvedUser2 = yield refreshCurrentUser(client);
2897
+ if (callbackUrl === void 0) {
2898
+ replaceAuthCallbackUrl(exchangedSession.cleanupPath);
2899
+ }
2900
+ return resolvedUser2;
2901
+ }
2902
+ const tokens = parseAuthCallbackTokens(callbackUrl);
2903
+ if (!tokens) return null;
2904
+ client.setSession(createAuthCallbackSession(tokens));
2905
+ setIsAuthenticated(client.isAuthenticated);
2906
+ setUser(client.user);
2907
+ const resolvedUser = yield refreshCurrentUser(client);
2908
+ if (callbackUrl === void 0) {
2909
+ replaceAuthCallbackUrl(getAuthCallbackCleanupPath(callbackUrl));
2910
+ }
2911
+ return resolvedUser;
2912
+ } catch (callbackError) {
2913
+ const resolvedError = toError(callbackError);
2914
+ setError(resolvedError);
2915
+ throw resolvedError;
2916
+ } finally {
2917
+ setIsLoading(false);
2918
+ }
2919
+ }),
2920
+ [client, refreshCurrentUser]
2921
+ );
2922
+ const signOut = useCallback6(() => __async(null, null, function* () {
2923
+ yield client == null ? void 0 : client.signOut();
2924
+ setIsAuthenticated(false);
2925
+ setUser(void 0);
2926
+ setError(null);
2927
+ }), [client]);
2928
+ const clearError = useCallback6(() => {
2929
+ setError(null);
2930
+ }, []);
2931
+ const value = useMemo5(() => {
2932
+ return {
2933
+ isAuthenticated,
2934
+ isWeb3User,
2935
+ user,
2936
+ isLoading,
2937
+ error,
2938
+ signIn,
2939
+ startAuth,
2940
+ setSession,
2941
+ handleAuthCallback,
2942
+ signOut,
2943
+ clearError
2944
+ };
2945
+ }, [
2946
+ clearError,
2947
+ error,
2948
+ handleAuthCallback,
2949
+ isAuthenticated,
2950
+ isWeb3User,
2951
+ isLoading,
2952
+ setSession,
2953
+ signIn,
2954
+ signOut,
2955
+ startAuth,
2956
+ user
2957
+ ]);
2958
+ return /* @__PURE__ */ jsx6(AggAuthContext.Provider, { value, children });
2959
+ }
2960
+
2961
+ // src/core/providers/client-provider.tsx
2962
+ import { jsx as jsx7 } from "react/jsx-runtime";
2963
+ function AggClientProvider({ client, children }) {
2964
+ return /* @__PURE__ */ jsx7(AggClientContext.Provider, { value: client != null ? client : null, children });
2965
+ }
2966
+
2967
+ // src/core/providers/agg-provider.tsx
2968
+ import { jsx as jsx8 } from "react/jsx-runtime";
2969
+ var hasWarnedMissingQueryClient = false;
2970
+ function useQueryClientCheck() {
2971
+ try {
2972
+ useQueryClient2();
2973
+ } catch (e) {
2974
+ if (!hasWarnedMissingQueryClient) {
2975
+ hasWarnedMissingQueryClient = true;
2976
+ console.error(
2977
+ "[agg] AggProvider requires a QueryClientProvider ancestor. Either wrap AggProvider in a <QueryClientProvider>, or use <AggProviders> which includes one automatically."
2978
+ );
2979
+ }
2980
+ }
2981
+ }
2982
+ var AggProvider = ({ client, config, children }) => {
2983
+ useQueryClientCheck();
2984
+ if (!client) {
2985
+ throw new Error(
2986
+ "AggProvider requires a valid AggClient instance. Pass one via the 'client' prop, or use <AggProviders> which handles setup automatically."
2987
+ );
2988
+ }
2989
+ 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 }) }) }) }) }) });
2990
+ };
2991
+
2992
+ // src/use-ramp-quotes.ts
2993
+ import { useMutation } from "@tanstack/react-query";
2994
+ function useRampQuotes() {
2995
+ const client = useAggClient();
2996
+ return useMutation({
2997
+ mutationFn: (params) => __async(null, null, function* () {
2998
+ return client.getRampQuotes(params);
2999
+ })
3000
+ });
3001
+ }
3002
+
3003
+ // src/use-ramp-session.ts
3004
+ import { useMutation as useMutation2 } from "@tanstack/react-query";
3005
+ function useRampSession() {
3006
+ const client = useAggClient();
3007
+ return useMutation2({
3008
+ mutationFn: (params) => __async(null, null, function* () {
3009
+ return client.createRampSession(params);
3010
+ })
3011
+ });
3012
+ }
3013
+
3014
+ // src/execution/use-quote-managed.ts
3015
+ import { useMutation as useMutation3 } from "@tanstack/react-query";
3016
+ function useQuoteManaged(options) {
3017
+ const client = useAggClient();
3018
+ return useMutation3({
3019
+ mutationFn: (params) => client.quoteManaged(params),
3020
+ onSuccess: options == null ? void 0 : options.onSuccess,
3021
+ onError: options == null ? void 0 : options.onError
3022
+ });
3023
+ }
3024
+
3025
+ // src/execution/use-execute-managed.ts
3026
+ import { useMutation as useMutation4, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
3027
+ function useExecuteManaged(options) {
3028
+ const client = useAggClient();
3029
+ const queryClient = useQueryClient3();
3030
+ return useMutation4({
3031
+ mutationFn: (params) => client.executeManaged(params),
3032
+ onSuccess: (data) => {
3033
+ var _a;
3034
+ queryClient.invalidateQueries({ queryKey: executionKeys.ordersPrefix() });
3035
+ queryClient.invalidateQueries({ queryKey: executionKeys.positionsPrefix() });
3036
+ invalidateBalanceQueries(queryClient);
3037
+ (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
3038
+ },
3039
+ onError: options == null ? void 0 : options.onError
3040
+ });
3041
+ }
3042
+
3043
+ // src/execution/use-withdraw-managed.ts
3044
+ import { useMutation as useMutation5, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
3045
+ function useWithdrawManaged(options) {
3046
+ const client = useAggClient();
3047
+ const queryClient = useQueryClient4();
3048
+ return useMutation5({
3049
+ mutationFn: (params) => client.withdrawManaged(params),
3050
+ onSuccess: (data) => {
3051
+ var _a;
3052
+ invalidateBalanceQueries(queryClient);
3053
+ (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
3054
+ },
3055
+ onError: options == null ? void 0 : options.onError
3056
+ });
3057
+ }
3058
+
3059
+ // src/execution/use-managed-balances.ts
3060
+ import { useQuery as useQuery2 } from "@tanstack/react-query";
3061
+ function useManagedBalances(options) {
3062
+ const client = useAggClient();
3063
+ const { enabled = true } = options != null ? options : {};
3064
+ const query = useQuery2({
3065
+ queryKey: executionKeys.balances(),
3066
+ queryFn: () => client.getManagedBalances(),
3067
+ enabled,
3068
+ staleTime: 1e4,
3069
+ gcTime: 5 * 6e4,
3070
+ retry: 1
3071
+ });
3072
+ return __spreadProps(__spreadValues({}, query), {
3073
+ balances: query.data
3074
+ });
3075
+ }
3076
+
3077
+ // src/execution/use-positions.ts
3078
+ import { useQuery as useQuery3 } from "@tanstack/react-query";
3079
+ function usePositions(options) {
3080
+ var _a, _b, _c, _d;
3081
+ const client = useAggClient();
3082
+ const { enabled = true, cursor, limit, status } = options != null ? options : {};
3083
+ const query = useQuery3({
3084
+ queryKey: executionKeys.positions(cursor, limit, status),
3085
+ queryFn: () => client.getPositions({ cursor, limit, status }),
3086
+ enabled,
3087
+ staleTime: 1e4,
3088
+ gcTime: 5 * 6e4,
3089
+ retry: 1
3090
+ });
3091
+ return __spreadProps(__spreadValues({}, query), {
3092
+ positions: (_a = query.data) == null ? void 0 : _a.data,
3093
+ nextCursor: (_b = query.data) == null ? void 0 : _b.nextCursor,
3094
+ hasMore: (_d = (_c = query.data) == null ? void 0 : _c.hasMore) != null ? _d : false
3095
+ });
3096
+ }
3097
+
3098
+ // src/execution/use-deposit-addresses.ts
3099
+ import { useEffect as useEffect4, useMemo as useMemo6, useRef as useRef4, useState as useState4 } from "react";
3100
+ import { useQuery as useQuery4 } from "@tanstack/react-query";
3101
+ var SVM_CHAIN_IDS = /* @__PURE__ */ new Set([792703809]);
3102
+ function getDepositAddress(chainId, data) {
3103
+ return chainId !== void 0 && SVM_CHAIN_IDS.has(chainId) ? data.svmAddress : data.evmAddress;
3104
+ }
3105
+ function useDepositAddresses(options) {
3106
+ var _a;
3107
+ const client = useAggClient();
3108
+ const {
3109
+ enabled = true,
3110
+ poll = true,
3111
+ refetchIntervalMs = 5e3,
3112
+ timeoutMs = 6e4
3113
+ } = options != null ? options : {};
3114
+ const [isTimedOut, setIsTimedOut] = useState4(false);
3115
+ const timeoutRef = useRef4(null);
3116
+ useEffect4(() => {
3117
+ if (!enabled || !poll) return void 0;
3118
+ setIsTimedOut(false);
3119
+ timeoutRef.current = setTimeout(() => setIsTimedOut(true), timeoutMs);
3120
+ return () => {
3121
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
3122
+ };
3123
+ }, [enabled, poll, timeoutMs]);
3124
+ const query = useQuery4({
3125
+ queryKey: executionKeys.depositAddresses(),
3126
+ queryFn: () => client.getDepositAddresses(),
3127
+ enabled,
3128
+ staleTime: 6e4,
3129
+ gcTime: 5 * 6e4,
3130
+ retry: 1,
3131
+ refetchInterval: (q) => {
3132
+ if (!poll || isTimedOut) return false;
3133
+ const data = q.state.data;
3134
+ if ((data == null ? void 0 : data.ready) === true) return false;
3135
+ return refetchIntervalMs;
3136
+ }
3137
+ });
3138
+ const isReady = ((_a = query.data) == null ? void 0 : _a.ready) === true;
3139
+ const readyData = isReady ? query.data : void 0;
3140
+ const evmAddress = useMemo6(() => readyData == null ? void 0 : readyData.evmAddress, [readyData]);
3141
+ const svmAddress = useMemo6(() => readyData == null ? void 0 : readyData.svmAddress, [readyData]);
3142
+ const supportedChains = useMemo6(() => readyData == null ? void 0 : readyData.supportedChains, [readyData]);
3143
+ return __spreadProps(__spreadValues({}, query), {
3144
+ isReady,
3145
+ isTimedOut,
3146
+ evmAddress,
3147
+ svmAddress,
3148
+ supportedChains,
3149
+ depositAddresses: query.data,
3150
+ /** Resolve the correct address (EVM or SVM) for a given chainId. */
3151
+ getAddress: (chainId) => readyData ? getDepositAddress(chainId, readyData) : void 0
3152
+ });
3153
+ }
3154
+
3155
+ // src/execution/use-sync-balances.ts
3156
+ import { useMutation as useMutation6, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
3157
+ function useSyncBalances(options) {
3158
+ const client = useAggClient();
3159
+ const queryClient = useQueryClient5();
3160
+ return useMutation6({
3161
+ mutationFn: () => client.syncManagedBalances(),
3162
+ onSuccess: () => {
3163
+ var _a;
3164
+ invalidateBalanceQueries(queryClient);
3165
+ (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options);
3166
+ },
3167
+ onError: options == null ? void 0 : options.onError
3168
+ });
3169
+ }
3170
+
3171
+ // src/execution/use-execution-progress.ts
3172
+ import { useCallback as useCallback7, useEffect as useEffect5, useRef as useRef5, useState as useState5 } from "react";
3173
+ var TERMINAL_ORDER_STATUSES = /* @__PURE__ */ new Set(["filled", "partial_fill", "failed", "cancelled"]);
3174
+ var ORDER_POLL_INTERVAL_MS = 5e3;
3175
+ function mapOrderStatusToTerminalEvent(status) {
3176
+ if (status === "filled") return "filled";
3177
+ if (status === "partial_fill") return "partial_fill";
3178
+ if (status === "failed" || status === "cancelled") return "failed";
3179
+ return null;
3180
+ }
3181
+ function useExecutionProgress({
3182
+ orderIds,
3183
+ enabled
3184
+ }) {
3185
+ const [phase, setPhase] = useState5("idle");
3186
+ const [submittedOrders, setSubmittedOrders] = useState5([]);
3187
+ const [latestBalance, setLatestBalance] = useState5(null);
3188
+ const [dagProgress, setDagProgress] = useState5(null);
3189
+ const [terminalOrderEvents, setTerminalOrderEvents] = useState5([]);
3190
+ const orderIdSetRef = useRef5(/* @__PURE__ */ new Set());
3191
+ const submittedOrderVenueByIdRef = useRef5(/* @__PURE__ */ new Map());
3192
+ useEffect5(() => {
3193
+ orderIdSetRef.current = new Set(orderIds != null ? orderIds : []);
3194
+ }, [orderIds]);
3195
+ useEffect5(() => {
3196
+ if (enabled && orderIds && orderIds.length > 0) {
3197
+ setPhase("pending");
3198
+ setSubmittedOrders([]);
3199
+ setLatestBalance(null);
3200
+ setDagProgress(null);
3201
+ setTerminalOrderEvents([]);
3202
+ submittedOrderVenueByIdRef.current = /* @__PURE__ */ new Map();
3203
+ } else if (!enabled) {
3204
+ setPhase("idle");
3205
+ submittedOrderVenueByIdRef.current = /* @__PURE__ */ new Map();
3206
+ }
3207
+ }, [enabled, orderIds]);
3208
+ const handleOrderSubmitted = useCallback7((msg) => {
3209
+ if (!orderIdSetRef.current.has(msg.orderId)) return;
3210
+ const trimmedVenue = msg.venue.trim();
3211
+ if (trimmedVenue) {
3212
+ submittedOrderVenueByIdRef.current.set(msg.orderId, trimmedVenue);
3213
+ }
3214
+ setSubmittedOrders((prev) => [...prev, msg]);
3215
+ setPhase("order_submitted");
3216
+ }, []);
3217
+ const handleBalanceUpdate = useCallback7((msg) => {
3218
+ setLatestBalance(msg);
3219
+ setPhase((current) => {
3220
+ if (current === "order_submitted" || current === "pending") {
3221
+ return "balance_updated";
3222
+ }
3223
+ return current;
3224
+ });
3225
+ }, []);
3226
+ const handleOrderEvent = useCallback7((msg) => {
3227
+ var _a, _b, _c;
3228
+ if (!orderIdSetRef.current.has(msg.orderId)) return;
3229
+ const trimmedVenue = msg.venue.trim();
3230
+ if (trimmedVenue) {
3231
+ submittedOrderVenueByIdRef.current.set(msg.orderId, trimmedVenue);
3232
+ }
3233
+ const { event } = msg;
3234
+ if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed") {
3235
+ const mappedEvent = event === "bridge_ws_subscribe_failed" ? "failed" : event;
3236
+ const resolvedVenue = trimmedVenue || submittedOrderVenueByIdRef.current.get(msg.orderId) || "";
3237
+ if (resolvedVenue) {
3238
+ submittedOrderVenueByIdRef.current.set(msg.orderId, resolvedVenue);
3239
+ }
3240
+ const nextTerminalEvent = {
3241
+ orderId: msg.orderId,
3242
+ venue: resolvedVenue,
3243
+ event: mappedEvent,
3244
+ filledAmountRaw: msg.filledAmountRaw,
3245
+ remainingAmountRaw: msg.remainingAmountRaw,
3246
+ errorReason: event === "bridge_ws_subscribe_failed" ? (_a = msg.errorReason) != null ? _a : "Bridge event subscription failed." : msg.errorReason,
3247
+ timestamp: msg.timestamp
3248
+ };
3249
+ setTerminalOrderEvents((prev) => {
3250
+ const nextEvents = [
3251
+ ...prev.filter((terminalEvent) => terminalEvent.orderId !== msg.orderId),
3252
+ nextTerminalEvent
3253
+ ];
3254
+ return nextEvents.sort((left, right) => left.timestamp - right.timestamp);
3255
+ });
3256
+ return;
3257
+ }
3258
+ if (event === "dag_started") {
3259
+ const initialStepTypes = {};
3260
+ if (msg.stepTypes) {
3261
+ for (const [seq, type] of Object.entries(msg.stepTypes)) {
3262
+ initialStepTypes[Number(seq)] = type;
3263
+ }
3264
+ }
3265
+ setDagProgress({
3266
+ dagRunId: (_b = msg.dagRunId) != null ? _b : "",
3267
+ totalSteps: (_c = msg.totalSteps) != null ? _c : 0,
3268
+ currentSequence: 0,
3269
+ currentStepType: null,
3270
+ completedSequences: [],
3271
+ stepTypes: initialStepTypes,
3272
+ status: "running",
3273
+ errorReason: null
3274
+ });
3275
+ return;
3276
+ }
3277
+ if (event === "step_started") {
3278
+ setDagProgress((prev) => {
3279
+ var _a2, _b2;
3280
+ if (!prev) return prev;
3281
+ const seq = (_a2 = msg.sequence) != null ? _a2 : prev.currentSequence;
3282
+ const stepType = (_b2 = msg.stepType) != null ? _b2 : prev.currentStepType;
3283
+ return __spreadProps(__spreadValues({}, prev), {
3284
+ currentSequence: seq,
3285
+ currentStepType: stepType,
3286
+ stepTypes: stepType != null ? __spreadProps(__spreadValues({}, prev.stepTypes), { [seq]: stepType }) : prev.stepTypes
3287
+ });
3288
+ });
3289
+ return;
3290
+ }
3291
+ if (event === "step_waiting") {
3292
+ setDagProgress((prev) => {
3293
+ var _a2, _b2;
3294
+ if (!prev) return prev;
3295
+ const seq = (_a2 = msg.sequence) != null ? _a2 : prev.currentSequence;
3296
+ const stepType = (_b2 = msg.stepType) != null ? _b2 : prev.currentStepType;
3297
+ return __spreadProps(__spreadValues({}, prev), {
3298
+ currentSequence: seq,
3299
+ currentStepType: stepType,
3300
+ stepTypes: stepType != null ? __spreadProps(__spreadValues({}, prev.stepTypes), { [seq]: stepType }) : prev.stepTypes
3301
+ });
3302
+ });
3303
+ return;
3304
+ }
3305
+ if (event === "step_completed") {
3306
+ setDagProgress((prev) => {
3307
+ if (!prev) return prev;
3308
+ const seq = msg.sequence;
3309
+ const stepType = msg.stepType;
3310
+ return __spreadProps(__spreadValues({}, prev), {
3311
+ completedSequences: seq != null ? [...prev.completedSequences, seq] : prev.completedSequences,
3312
+ stepTypes: seq != null && stepType != null ? __spreadProps(__spreadValues({}, prev.stepTypes), { [seq]: stepType }) : prev.stepTypes
3313
+ });
3314
+ });
3315
+ return;
3316
+ }
3317
+ if (event === "dag_completed") {
3318
+ setDagProgress((prev) => {
3319
+ if (!prev) return prev;
3320
+ return __spreadProps(__spreadValues({}, prev), { status: "completed" });
3321
+ });
3322
+ return;
3323
+ }
3324
+ if (event === "dag_failed") {
3325
+ setDagProgress((prev) => {
3326
+ var _a2;
3327
+ if (!prev) return prev;
3328
+ return __spreadProps(__spreadValues({}, prev), {
3329
+ status: "failed",
3330
+ errorReason: (_a2 = msg.errorReason) != null ? _a2 : null
3331
+ });
3332
+ });
3333
+ return;
3334
+ }
3335
+ }, []);
3336
+ const isListening = enabled && !!orderIds && orderIds.length > 0;
3337
+ useOnOrderSubmitted(isListening ? handleOrderSubmitted : null);
3338
+ useOnBalanceUpdate(isListening ? handleBalanceUpdate : null);
3339
+ useOnOrderEvent(isListening ? handleOrderEvent : null);
3340
+ const client = useAggClient();
3341
+ const terminalOrderIdsRef = useRef5(/* @__PURE__ */ new Set());
3342
+ const pollInFlightRef = useRef5(false);
3343
+ useEffect5(() => {
3344
+ terminalOrderIdsRef.current = new Set(terminalOrderEvents.map((e) => e.orderId));
3345
+ }, [terminalOrderEvents]);
3346
+ useEffect5(() => {
3347
+ if (!isListening || !(orderIds == null ? void 0 : orderIds.length)) return;
3348
+ let cancelled = false;
3349
+ let interval = null;
3350
+ const stopPolling = () => {
3351
+ if (interval !== null) {
3352
+ clearInterval(interval);
3353
+ interval = null;
3354
+ }
3355
+ };
3356
+ const reconcile = () => __async(null, null, function* () {
3357
+ var _a, _b, _c;
3358
+ if (cancelled || pollInFlightRef.current) return;
3359
+ const pending = orderIds.filter((id) => !terminalOrderIdsRef.current.has(id));
3360
+ if (pending.length === 0) {
3361
+ stopPolling();
3362
+ return;
3363
+ }
3364
+ pollInFlightRef.current = true;
3365
+ try {
3366
+ const orders = yield Promise.all(
3367
+ pending.map((orderId) => __async(null, null, function* () {
3368
+ var _a2, _b2;
3369
+ try {
3370
+ const res = yield client.getExecutionOrders({ orderId, limit: 1 });
3371
+ return (_b2 = (_a2 = res.data) == null ? void 0 : _a2[0]) != null ? _b2 : null;
3372
+ } catch (e) {
3373
+ return null;
3374
+ }
3375
+ }))
3376
+ );
3377
+ if (cancelled) return;
3378
+ const terminalEvents = [];
3379
+ for (const order of orders) {
3380
+ if (!order) continue;
3381
+ if (!TERMINAL_ORDER_STATUSES.has(order.status)) continue;
3382
+ const mapped = mapOrderStatusToTerminalEvent(order.status);
3383
+ if (!mapped) continue;
3384
+ terminalEvents.push({
3385
+ orderId: order.id,
3386
+ venue: (_a = order.venue) != null ? _a : "",
3387
+ event: mapped,
3388
+ filledAmountRaw: (_b = order.filledAmountRaw) != null ? _b : void 0,
3389
+ errorReason: (_c = order.errorMessage) != null ? _c : void 0,
3390
+ timestamp: new Date(order.updatedAt).getTime() || Date.now()
3391
+ });
3392
+ }
3393
+ if (terminalEvents.length > 0) {
3394
+ setTerminalOrderEvents((prev) => {
3395
+ const nextById = /* @__PURE__ */ new Map();
3396
+ for (const ev of prev) nextById.set(ev.orderId, ev);
3397
+ for (const ev of terminalEvents) {
3398
+ const existing = nextById.get(ev.orderId);
3399
+ if (!existing || existing.timestamp < ev.timestamp) {
3400
+ nextById.set(ev.orderId, ev);
3401
+ }
3402
+ }
3403
+ return Array.from(nextById.values()).sort((l, r) => l.timestamp - r.timestamp);
3404
+ });
3405
+ }
3406
+ const covered = /* @__PURE__ */ new Set([
3407
+ ...terminalOrderIdsRef.current,
3408
+ ...terminalEvents.map((e) => e.orderId)
3409
+ ]);
3410
+ if (orderIds.every((id) => covered.has(id))) {
3411
+ stopPolling();
3412
+ }
3413
+ } finally {
3414
+ pollInFlightRef.current = false;
3415
+ }
3416
+ });
3417
+ void reconcile();
3418
+ interval = setInterval(() => {
3419
+ void reconcile();
3420
+ }, ORDER_POLL_INTERVAL_MS);
3421
+ return () => {
3422
+ cancelled = true;
3423
+ stopPolling();
3424
+ };
3425
+ }, [client, isListening, orderIds]);
3426
+ return { phase, submittedOrders, latestBalance, dagProgress, terminalOrderEvents };
3427
+ }
3428
+
3429
+ // src/execution/compute-closed-position-totals.ts
3430
+ var computeClosedPositionTotals = (group) => {
3431
+ const outcomes = group.venueMarket.venueMarketOutcomes;
3432
+ const isResolved = group.venueMarket.status === "resolved";
3433
+ let totalTraded = 0;
3434
+ let amountWon = 0;
3435
+ const winningOutcomeIds = /* @__PURE__ */ new Set();
3436
+ let winningCount = 0;
3437
+ let settledCount = 0;
3438
+ for (const outcome of outcomes) {
3439
+ totalTraded += outcome.avgEntryPrice * outcome.totalSize;
3440
+ if (isResolved) {
3441
+ if (outcome.winner === true) {
3442
+ amountWon += outcome.totalValue;
3443
+ winningCount += 1;
3444
+ for (const breakdown of outcome.venueBreakdown) {
3445
+ if (breakdown.venueMarketOutcomeId) {
3446
+ winningOutcomeIds.add(breakdown.venueMarketOutcomeId);
3447
+ }
3448
+ }
3449
+ }
3450
+ } else {
3451
+ amountWon += outcome.totalValue;
3452
+ }
3453
+ if (outcome.winner !== null) {
3454
+ settledCount += 1;
3455
+ }
3456
+ }
3457
+ const returnPct = totalTraded === 0 ? 0 : (amountWon - totalTraded) / totalTraded;
3458
+ return {
3459
+ totalTraded,
3460
+ amountWon,
3461
+ returnPct,
3462
+ winningOutcomeIds: Array.from(winningOutcomeIds),
3463
+ isPartialWin: winningCount > 0 && winningCount < settledCount
3464
+ };
3465
+ };
3466
+
3467
+ // src/execution/use-redeem.ts
3468
+ import { useMutation as useMutation7, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
3469
+ var useRedeem = () => {
3470
+ const client = useAggClient();
3471
+ const queryClient = useQueryClient6();
3472
+ return useMutation7({
3473
+ mutationFn: (body) => client.redeem(body),
3474
+ onSuccess: () => {
3475
+ queryClient.invalidateQueries({ queryKey: executionKeys.positionsPrefix() });
3476
+ queryClient.invalidateQueries({ queryKey: executionKeys.balances() });
3477
+ queryClient.invalidateQueries({ queryKey: executionKeys.claimableClosedPositionsCount() });
3478
+ }
3479
+ });
3480
+ };
3481
+
3482
+ // src/execution/use-on-redeem-event.ts
3483
+ var useOnRedeemEvent2 = (listener) => {
3484
+ useOnRedeemEvent(listener);
3485
+ };
3486
+
3487
+ // src/execution/use-redeem-eligible-count.ts
3488
+ import { useQuery as useQuery5 } from "@tanstack/react-query";
3489
+ var CLAIMABLE_COUNT_PAGE_LIMIT = 100;
3490
+ var getClaimableClosedPositionsCount = (client) => __async(null, null, function* () {
3491
+ var _a;
3492
+ let total = 0;
3493
+ let cursor;
3494
+ do {
3495
+ const page = yield client.getExecutionPositions({
3496
+ status: "closed",
3497
+ limit: CLAIMABLE_COUNT_PAGE_LIMIT,
3498
+ cursor
3499
+ });
3500
+ for (const group of page.data) {
3501
+ if (group.redeemStatus === "eligible") {
3502
+ total += 1;
3503
+ }
3504
+ }
3505
+ cursor = page.hasMore ? (_a = page.nextCursor) != null ? _a : void 0 : void 0;
3506
+ } while (cursor);
3507
+ return total;
3508
+ });
3509
+ var useRedeemEligibleCount = () => {
3510
+ var _a;
3511
+ const client = useAggClient();
3512
+ const { isAuthenticated } = useAggAuthState();
3513
+ const query = useQuery5({
3514
+ queryKey: executionKeys.claimableClosedPositionsCount(),
3515
+ queryFn: () => getClaimableClosedPositionsCount(client),
3516
+ enabled: isAuthenticated,
3517
+ staleTime: 3e4,
3518
+ refetchInterval: isAuthenticated ? 45e3 : false
3519
+ });
3520
+ if (!isAuthenticated) return 0;
3521
+ return (_a = query.data) != null ? _a : 0;
3522
+ };
3523
+
3524
+ export {
3525
+ __spreadValues,
3526
+ __spreadProps,
3527
+ __objRest,
3528
+ __async,
3529
+ Venue,
3530
+ MatchStatus,
3531
+ MatchType,
3532
+ CONFIRMED_MATCH_STATUSES,
3533
+ MarketStatus,
3534
+ getWalletAddressFromUserProfile,
3535
+ parseEmail,
3536
+ parseEmailStrict,
3537
+ optimizedImageUrl,
3538
+ sortVenues,
3539
+ getOrCreateBuilder,
3540
+ getBuilder,
3541
+ resolveAggUiLabels,
3542
+ defaultAggUiConfig,
3543
+ AggClientContext,
3544
+ AggAuthContext,
3545
+ executionKeys,
3546
+ invalidateBalanceQueries,
3547
+ invalidatePositionQueries,
3548
+ AggBalanceProvider,
3549
+ EventListStateProvider,
3550
+ useEventListState,
3551
+ createMarketChartData,
3552
+ mergeMarketChartData,
3553
+ createMarketLiveState,
3554
+ createMarketOrderbookDataFromVenueOrderbooks,
3555
+ createMarketOrderbookDataFromState,
3556
+ marketOrderbookDataToResponse,
3557
+ applyOrderbookDepth,
3558
+ marketDataKeys,
3559
+ useAggClient,
3560
+ useAggUiConfig,
3561
+ useAggLabels,
3562
+ useAggAuthContext,
3563
+ useAggAuthState,
3564
+ useAggBalanceContext,
3565
+ useAggBalanceState,
3566
+ useAggBalance,
3567
+ useSdkUiConfig,
3568
+ useSdkLabels,
3569
+ useLabels,
3570
+ useAggWebSocket,
3571
+ useAggWebSocketConnectionState,
3572
+ useOnOrderSubmitted,
3573
+ useOnBalanceUpdate,
3574
+ DEFAULT_AGG_ROOT_CLASS_NAME,
3575
+ CHART_TIME_RANGES,
3576
+ resolveTradingStateKind,
3577
+ resolveMarketWinningOutcome,
3578
+ resolveMarketTradingState,
3579
+ resolveEventTradingState,
3580
+ resolveOrderEligibility,
3581
+ resolveDefaultMarket,
3582
+ tradingReducer,
3583
+ useEventTradingContext,
3584
+ AggUiProvider,
3585
+ AggProvider,
3586
+ useRampQuotes,
3587
+ useRampSession,
3588
+ useQuoteManaged,
3589
+ useExecuteManaged,
3590
+ useWithdrawManaged,
3591
+ useManagedBalances,
3592
+ usePositions,
3593
+ getDepositAddress,
3594
+ useDepositAddresses,
3595
+ useSyncBalances,
3596
+ useExecutionProgress,
3597
+ computeClosedPositionTotals,
3598
+ useRedeem,
3599
+ useOnRedeemEvent2 as useOnRedeemEvent,
3600
+ useRedeemEligibleCount
3601
+ };