@agg-build/hooks 4.17.2 → 4.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-IVUHIMRY.mjs → chunk-5B2F3GMC.mjs} +1 -1
- package/dist/{chunk-KQ5TOPNY.mjs → chunk-ESDA4NZI.mjs} +687 -604
- package/dist/{chunk-BBAKQDOH.mjs → chunk-SBGLJDPJ.mjs} +1 -1
- package/dist/deposit.js +128 -2
- package/dist/deposit.mjs +2 -2
- package/dist/index.d.mts +983 -26
- package/dist/index.d.ts +983 -26
- package/dist/index.js +2453 -1281
- package/dist/index.mjs +1462 -385
- package/dist/withdraw.d.mts +5 -0
- package/dist/withdraw.d.ts +5 -0
- package/dist/withdraw.js +132 -5
- package/dist/withdraw.mjs +2 -2
- package/package.json +2 -2
|
@@ -59,11 +59,13 @@ var Venue = /* @__PURE__ */ ((Venue2) => {
|
|
|
59
59
|
Venue2["opinion"] = "opinion";
|
|
60
60
|
Venue2["predict"] = "predict";
|
|
61
61
|
Venue2["pred"] = "pred";
|
|
62
|
+
Venue2["tiprun"] = "tiprun";
|
|
62
63
|
Venue2["probable"] = "probable";
|
|
63
64
|
Venue2["myriad"] = "myriad";
|
|
64
65
|
Venue2["hyperliquid"] = "hyperliquid";
|
|
65
66
|
Venue2["novig"] = "novig";
|
|
66
67
|
Venue2["prophetx"] = "prophetx";
|
|
68
|
+
Venue2["betdex"] = "betdex";
|
|
67
69
|
return Venue2;
|
|
68
70
|
})(Venue || {});
|
|
69
71
|
var ACTIVE_VENUES = [
|
|
@@ -73,11 +75,13 @@ var ACTIVE_VENUES = [
|
|
|
73
75
|
"opinion" /* opinion */,
|
|
74
76
|
"predict" /* predict */,
|
|
75
77
|
"pred" /* pred */,
|
|
78
|
+
"tiprun" /* tiprun */,
|
|
76
79
|
"probable" /* probable */,
|
|
77
80
|
"myriad" /* myriad */,
|
|
78
81
|
"hyperliquid" /* hyperliquid */,
|
|
79
82
|
"novig" /* novig */,
|
|
80
|
-
"prophetx" /* prophetx
|
|
83
|
+
"prophetx" /* prophetx */,
|
|
84
|
+
"betdex" /* betdex */
|
|
81
85
|
];
|
|
82
86
|
var INACTIVE_VENUES = [];
|
|
83
87
|
var ACTIVE_VENUE_SET = new Set(ACTIVE_VENUES);
|
|
@@ -158,6 +162,9 @@ function parseEmailStrict(raw) {
|
|
|
158
162
|
return result.data;
|
|
159
163
|
}
|
|
160
164
|
|
|
165
|
+
// ../common/src/enums/image-size.ts
|
|
166
|
+
var RETINA_IMAGE_SIZES = [80 /* xl */, 96 /* xxl */, 120 /* xxxl */];
|
|
167
|
+
|
|
161
168
|
// ../common/src/utils/image-url.ts
|
|
162
169
|
function pickVariant(px) {
|
|
163
170
|
if (px <= 44 /* sm */) return 44 /* sm */;
|
|
@@ -173,6 +180,13 @@ function optimizedImageUrl(url, maxPx) {
|
|
|
173
180
|
const filename = variant === 0 /* original */ ? "original.webp" : `${variant}.webp`;
|
|
174
181
|
return url.replace(VARIANT_RE, `/${filename}`);
|
|
175
182
|
}
|
|
183
|
+
function retinaImageUrl(url, maxPx) {
|
|
184
|
+
if (!url) return void 0;
|
|
185
|
+
if (!VARIANT_RE.test(url)) return void 0;
|
|
186
|
+
const variant = RETINA_IMAGE_SIZES.find((size) => size >= maxPx * 2);
|
|
187
|
+
if (variant == null) return void 0;
|
|
188
|
+
return url.replace(VARIANT_RE, `/${variant}.webp`);
|
|
189
|
+
}
|
|
176
190
|
|
|
177
191
|
// ../common/src/utils/sort-venues.ts
|
|
178
192
|
var VENUE_SORT_ORDER = [
|
|
@@ -180,10 +194,12 @@ var VENUE_SORT_ORDER = [
|
|
|
180
194
|
"hyperliquid" /* hyperliquid */,
|
|
181
195
|
"predict" /* predict */,
|
|
182
196
|
"prophetx" /* prophetx */,
|
|
197
|
+
"betdex" /* betdex */,
|
|
183
198
|
"kalshi" /* kalshi */,
|
|
184
199
|
"limitless" /* limitless */,
|
|
185
200
|
"myriad" /* myriad */,
|
|
186
201
|
"pred" /* pred */,
|
|
202
|
+
"tiprun" /* tiprun */,
|
|
187
203
|
"probable" /* probable */,
|
|
188
204
|
"novig" /* novig */,
|
|
189
205
|
"opinion" /* opinion */
|
|
@@ -228,6 +244,19 @@ function evict() {
|
|
|
228
244
|
builders.delete(oldest);
|
|
229
245
|
}
|
|
230
246
|
}
|
|
247
|
+
function getCandleStoreDiagnostics() {
|
|
248
|
+
return {
|
|
249
|
+
builders: builders.size,
|
|
250
|
+
retainedCandles: [...builders.values()].reduce(
|
|
251
|
+
(total, builder) => total + ["1m", "5m", "1h", "1d"].reduce(
|
|
252
|
+
(count, interval) => count + builder.getClosed(interval).length + (builder.getForming(interval) ? 1 : 0),
|
|
253
|
+
0
|
|
254
|
+
),
|
|
255
|
+
0
|
|
256
|
+
),
|
|
257
|
+
maxBuilders: MAX_BUILDERS
|
|
258
|
+
};
|
|
259
|
+
}
|
|
231
260
|
|
|
232
261
|
// src/core/ui-config/labels.ts
|
|
233
262
|
var enUsLabels = {
|
|
@@ -244,6 +273,10 @@ var enUsLabels = {
|
|
|
244
273
|
lineChartAria: "Line chart",
|
|
245
274
|
candlestickChartAria: "Candlestick chart",
|
|
246
275
|
lineChartSeriesSwitchAria: "Chart series switch",
|
|
276
|
+
chartSources: (historyVenue, liquidityVenue) => `History: ${historyVenue} \xB7 Resting liquidity: ${liquidityVenue != null ? liquidityVenue : "all venues"}`,
|
|
277
|
+
chartBidLiquidity: (amount) => `Bid ${amount}`,
|
|
278
|
+
chartAskLiquidity: (amount) => `Ask ${amount}`,
|
|
279
|
+
chartEmpty: "No price history in this range",
|
|
247
280
|
lineChartSeriesOptionAria: (seriesLabel) => `Show ${seriesLabel} series`,
|
|
248
281
|
chartTypeSwitchAria: "Chart type switch",
|
|
249
282
|
lineChartType: "Line",
|
|
@@ -255,12 +288,14 @@ var enUsLabels = {
|
|
|
255
288
|
opinion: "Opinion",
|
|
256
289
|
predict: "Predict",
|
|
257
290
|
pred: "PRED",
|
|
291
|
+
tiprun: "Tip Run",
|
|
258
292
|
limitless: "Limitless",
|
|
259
293
|
probable: "Probable",
|
|
260
294
|
myriad: "Myriad",
|
|
261
295
|
hyperliquid: "Hyperliquid",
|
|
262
296
|
novig: "Novig",
|
|
263
|
-
prophetx: "ProphetX"
|
|
297
|
+
prophetx: "ProphetX",
|
|
298
|
+
betdex: "BETDEX"
|
|
264
299
|
},
|
|
265
300
|
auth: {
|
|
266
301
|
connect: (connectorName) => connectorName ? `Sign in with ${connectorName}` : "Sign in",
|
|
@@ -551,10 +586,74 @@ var enUsLabels = {
|
|
|
551
586
|
positionsValue: "Positions Value",
|
|
552
587
|
kalshiBalance: "Kalshi Balance",
|
|
553
588
|
balanceByNetwork: "Balance by network",
|
|
589
|
+
venueAccount: "Venue account",
|
|
590
|
+
balanceUnavailable: "Balance unavailable",
|
|
554
591
|
paperModeNetwork: "Paper",
|
|
555
592
|
paperModeWarning: "Paper mode is enabled. These are simulated funds for paper trading.",
|
|
556
593
|
networkTooltipDescription: "Funds are stored across networks. We handle routing automatically, but keeping funds on the right network enables faster trades and lower fees. When depositing, you can choose your preferred network."
|
|
557
594
|
},
|
|
595
|
+
hostedBetdex: {
|
|
596
|
+
deposit: "Deposit USDC",
|
|
597
|
+
depositInstructions: {
|
|
598
|
+
production: "Send USDC on Solana to this BETDEX account address.",
|
|
599
|
+
sandbox: "This is a sandbox account. Use sandbox test funds only."
|
|
600
|
+
},
|
|
601
|
+
depositAddress: "BETDEX Solana deposit address",
|
|
602
|
+
transferUnavailable: "This transfer is temporarily unavailable. Check its status before trying again.",
|
|
603
|
+
withdraw: "Withdraw USDC",
|
|
604
|
+
withdrawalAmount: "Amount (USDC)",
|
|
605
|
+
withdrawalDestination: "Your Solana wallet address",
|
|
606
|
+
withdrawalSubmit: "Withdraw from BETDEX",
|
|
607
|
+
withdrawalCheck: "Check withdrawal",
|
|
608
|
+
withdrawalRetry: "Retry the same withdrawal",
|
|
609
|
+
withdrawalNew: "New withdrawal",
|
|
610
|
+
withdrawalUnknown: "The response was not confirmed. Your request is saved; retrying checks the same withdrawal.",
|
|
611
|
+
withdrawalStatuses: {
|
|
612
|
+
processing: "Withdrawal is processing.",
|
|
613
|
+
confirmed: "Withdrawal confirmed.",
|
|
614
|
+
failed: "Withdrawal failed. Funds are available again.",
|
|
615
|
+
flagged: "Withdrawal needs review. Funds remain reserved.",
|
|
616
|
+
review_required: "Withdrawal needs review. Funds remain reserved."
|
|
617
|
+
},
|
|
618
|
+
title: "BETDEX account",
|
|
619
|
+
description: "USDC held with BETDEX, separate from your connected wallets.",
|
|
620
|
+
sandbox: "Sandbox \xB7 simulated funds",
|
|
621
|
+
createAccount: "Set up BETDEX account",
|
|
622
|
+
checkSetup: "Check account setup",
|
|
623
|
+
provisioning: "Account setup is processing. Check again for confirmation.",
|
|
624
|
+
suspended: "This BETDEX account is suspended.",
|
|
625
|
+
unavailable: "BETDEX balance is temporarily unavailable.",
|
|
626
|
+
provisioningUnavailable: "BETDEX account setup is currently unavailable.",
|
|
627
|
+
total: "Total balance",
|
|
628
|
+
available: "Available to trade",
|
|
629
|
+
reserved: "Reserved for open orders",
|
|
630
|
+
refresh: "Refresh account",
|
|
631
|
+
creationFailed: "We could not confirm account setup. Refresh to check its status before trying again.",
|
|
632
|
+
showActivity: "Show account activity",
|
|
633
|
+
hideActivity: "Hide account activity",
|
|
634
|
+
activityTitle: "BETDEX account activity",
|
|
635
|
+
activityDescription: "Observed ledger entries, not spendable balances or per-order fees. A ledger entry alone does not confirm a withdrawal's completion.",
|
|
636
|
+
activityEmpty: "No account activity on this page.",
|
|
637
|
+
activityUnavailable: "BETDEX account activity is temporarily unavailable.",
|
|
638
|
+
activityPrevious: "Previous activity page",
|
|
639
|
+
activityNext: "Next activity page",
|
|
640
|
+
activityRefresh: "Refresh activity",
|
|
641
|
+
activityCodes: {
|
|
642
|
+
Deposit: "Deposit",
|
|
643
|
+
Withdrawal: "Withdrawal",
|
|
644
|
+
TradeCreation: "Trade created",
|
|
645
|
+
TradeVoid: "Trade voided",
|
|
646
|
+
TradeWin: "Trade payout",
|
|
647
|
+
WalletToWallet: "Wallet transfer",
|
|
648
|
+
Commission: "Commission",
|
|
649
|
+
MarketPositionVoid: "Position voided",
|
|
650
|
+
MarketPositionPayout: "Position payout",
|
|
651
|
+
MarketPositionRefund: "Position refund",
|
|
652
|
+
ManualDebit: "Manual debit",
|
|
653
|
+
ManualCredit: "Manual credit",
|
|
654
|
+
SettlementResidual: "Settlement adjustment"
|
|
655
|
+
}
|
|
656
|
+
},
|
|
558
657
|
activity: {
|
|
559
658
|
depositType: "Deposit",
|
|
560
659
|
redeemType: "Claim",
|
|
@@ -708,6 +807,17 @@ var enUsLabels = {
|
|
|
708
807
|
priceGap: "Price Gap"
|
|
709
808
|
},
|
|
710
809
|
eventItemDetails: {
|
|
810
|
+
chartLegend: "Markets on chart",
|
|
811
|
+
selectChartMarkets: "Select a line above to show its history",
|
|
812
|
+
marketHistoryUnavailable: "History unavailable",
|
|
813
|
+
comparisonSource: (venue) => `${venue} \xB7 Outcome probabilities \xB7 Click a line to show or hide it`,
|
|
814
|
+
comparisonSeriesCount: (shown, total) => `Showing ${shown} of ${total} series`,
|
|
815
|
+
comparisonSeriesPage: (page, total) => `Page ${page} of ${total}`,
|
|
816
|
+
comparisonSeriesBudget: (limit) => `Up to ${limit} series are live at once. Change pages to compare others; your selected outcome stays visible.`,
|
|
817
|
+
comparisonPreviousSeries: "Previous series",
|
|
818
|
+
comparisonNextSeries: "Next series",
|
|
819
|
+
comparisonSelectedSeries: "Selected",
|
|
820
|
+
comparisonHiddenSeries: "Hidden",
|
|
711
821
|
loading: "Loading market details",
|
|
712
822
|
unavailableAria: "Market details unavailable",
|
|
713
823
|
unavailableTitle: "Market details unavailable",
|
|
@@ -813,6 +923,7 @@ var enUsLabels = {
|
|
|
813
923
|
settlementCriticalDifferenceLabel: "Critical",
|
|
814
924
|
settlementValueUnavailable: "Not provided",
|
|
815
925
|
settlementLoading: "Loading settlement",
|
|
926
|
+
settlementDetailsLoadError: "Settlement details could not be loaded.",
|
|
816
927
|
settlementDetailsAria: (venueLabel) => `${venueLabel} settlement details`,
|
|
817
928
|
settlementShowMoreAria: (ctaLabel, venueLabel) => `${ctaLabel} for ${venueLabel}`,
|
|
818
929
|
settlementDescriptionLabel: "Description",
|
|
@@ -834,6 +945,9 @@ var enUsLabels = {
|
|
|
834
945
|
maximumFractionDigits: 2
|
|
835
946
|
})}\xA2 avg. price`,
|
|
836
947
|
balance: (value) => `Balance ${value}`,
|
|
948
|
+
betdexBalance: (value) => `BETDEX balance ${value}`,
|
|
949
|
+
betdexBalanceUnavailable: "BETDEX balance unavailable",
|
|
950
|
+
manageBetdexAccount: "Manage BETDEX account",
|
|
837
951
|
shares: (value) => `${value.toLocaleString("en-US", {
|
|
838
952
|
minimumFractionDigits: Number.isInteger(value) ? 0 : 1,
|
|
839
953
|
maximumFractionDigits: 2
|
|
@@ -951,6 +1065,10 @@ var enUsLabels = {
|
|
|
951
1065
|
}
|
|
952
1066
|
},
|
|
953
1067
|
connectKalshi: "Connect Kalshi to trade",
|
|
1068
|
+
connectProphetx: "Connect ProphetX to trade",
|
|
1069
|
+
manageProphetx: "Manage ProphetX connection",
|
|
1070
|
+
prophetxFundingNotice: "Manage funds on ProphetX",
|
|
1071
|
+
prophetxSettlementNotice: "This position settles on ProphetX",
|
|
954
1072
|
requiresKalshiAccount: "Requires Kalshi account",
|
|
955
1073
|
tradingAccessVenues: "Venues",
|
|
956
1074
|
tradingAccessAvailable: "Available",
|
|
@@ -999,6 +1117,7 @@ var enUsLabels = {
|
|
|
999
1117
|
verified: "Verified",
|
|
1000
1118
|
platformFee: "0% platform fees",
|
|
1001
1119
|
estimatedFees: "Estimated fees",
|
|
1120
|
+
betdexSettlementFeeNotice: "BETDEX charges 1% of net profit per market at settlement, not per fill. The final fee depends on all positions in that market.",
|
|
1002
1121
|
executionReserve: "Execution reserve",
|
|
1003
1122
|
executionReserveTooltipAria: "Why funds are reserved",
|
|
1004
1123
|
executionReserveDescription: "Held for price movement or possible venue charges, not a confirmed fee. Unused funds are returned after execution.",
|
|
@@ -1062,6 +1181,11 @@ var enUsLabels = {
|
|
|
1062
1181
|
orderFullyFilled: "Order fully filled",
|
|
1063
1182
|
orderPartiallyFilled: "Order partially filled",
|
|
1064
1183
|
orderAveragePrice: (priceLabel) => `avg. ${priceLabel}`,
|
|
1184
|
+
orderAmount: "Order amount",
|
|
1185
|
+
orderLimitPrice: (priceLabel) => `limit ${priceLabel}`,
|
|
1186
|
+
limitVenueOrder: (venueLabel) => `${venueLabel} limit order`,
|
|
1187
|
+
limitOrderSubmitting: "Submitting limit order...",
|
|
1188
|
+
limitOrderSubmitted: "Limit order submitted",
|
|
1065
1189
|
orderComplete: "Order complete",
|
|
1066
1190
|
orderFilledAtPrice: (venueLabel, priceLabel) => `${venueLabel} order filled at ${priceLabel}`,
|
|
1067
1191
|
orderFilledAtPriceWithAmount: (venueLabel, priceLabel, amountLabel) => `${venueLabel} order filled at ${priceLabel} (${amountLabel})`,
|
|
@@ -1144,6 +1268,22 @@ var enUsLabels = {
|
|
|
1144
1268
|
cancel: "Cancel",
|
|
1145
1269
|
fallbackError: "Signature declined. Please try again."
|
|
1146
1270
|
},
|
|
1271
|
+
connectProphetxModal: {
|
|
1272
|
+
disconnect: "Disconnect ProphetX",
|
|
1273
|
+
disconnecting: "Disconnecting\u2026",
|
|
1274
|
+
disconnectError: "Could not disconnect ProphetX. Finish any open orders and try again.",
|
|
1275
|
+
title: "Connect ProphetX Account",
|
|
1276
|
+
description: "Add your ProphetX access key and secret key to trade with your existing account.",
|
|
1277
|
+
fundingNotice: "Trades use your ProphetX balance. Deposits, withdrawals, and transfers are managed on ProphetX, outside AGG.",
|
|
1278
|
+
instructions: "Create an API key in your ProphetX account settings",
|
|
1279
|
+
accessKey: "Access key",
|
|
1280
|
+
secretKey: "Secret key",
|
|
1281
|
+
verify: "Verify connection",
|
|
1282
|
+
verifying: "Verifying\u2026",
|
|
1283
|
+
error: "Could not connect to ProphetX. Check your credentials and try again.",
|
|
1284
|
+
connected: "Your ProphetX account is connected.",
|
|
1285
|
+
done: "Done"
|
|
1286
|
+
},
|
|
1147
1287
|
connectKalshiModal: {
|
|
1148
1288
|
ariaLabel: "Connect Kalshi Account",
|
|
1149
1289
|
title: "Connect Kalshi Account",
|
|
@@ -1190,6 +1330,20 @@ var enUsLabels = {
|
|
|
1190
1330
|
}
|
|
1191
1331
|
},
|
|
1192
1332
|
eventMarketPage: {
|
|
1333
|
+
loadMoreMarkets: "Load more markets",
|
|
1334
|
+
loadingMoreMarkets: "Loading markets\u2026",
|
|
1335
|
+
openOrders: {
|
|
1336
|
+
title: "Open orders",
|
|
1337
|
+
limitPriceHeader: "Limit price",
|
|
1338
|
+
filledHeader: "Filled",
|
|
1339
|
+
totalHeader: "Total",
|
|
1340
|
+
expirationHeader: "Expiration",
|
|
1341
|
+
// Abbreviated forms for the stacked mobile card.
|
|
1342
|
+
limitShort: "Limit",
|
|
1343
|
+
filledShort: "Filled",
|
|
1344
|
+
totalShort: "Tot.",
|
|
1345
|
+
expirationShort: "Exp."
|
|
1346
|
+
},
|
|
1193
1347
|
unavailableAria: "Event market page unavailable",
|
|
1194
1348
|
unavailableTitle: "Something went wrong",
|
|
1195
1349
|
unavailableDescription: "We're having trouble loading this event right now.\nTry refreshing or check back later.",
|
|
@@ -1556,7 +1710,7 @@ var mergeAggUiConfig = (persisted, config) => {
|
|
|
1556
1710
|
// src/execution/query-keys.ts
|
|
1557
1711
|
var executionKeys = {
|
|
1558
1712
|
all: () => ["execution"],
|
|
1559
|
-
balances: (mode) => mode ? ["execution", "balances", mode] : ["execution", "balances"],
|
|
1713
|
+
balances: (mode, custody) => custody && custody !== "managed" ? ["execution", "balances", mode != null ? mode : "live", custody] : mode ? ["execution", "balances", mode] : ["execution", "balances"],
|
|
1560
1714
|
positions: (cursor, limit, status, mode) => mode ? ["execution", "positions", cursor != null ? cursor : null, limit != null ? limit : null, status != null ? status : null, mode] : ["execution", "positions", cursor != null ? cursor : null, limit != null ? limit : null, status != null ? status : null],
|
|
1561
1715
|
positionsPrefix: () => ["execution", "positions"],
|
|
1562
1716
|
claimablePositionsCount: () => ["execution", "positions", "claimable-count"],
|
|
@@ -1582,7 +1736,11 @@ var balanceQueryKeys = {
|
|
|
1582
1736
|
venue: (venuesKey) => ["venue-balances", venuesKey],
|
|
1583
1737
|
venuePrefix: () => ["venue-balances"]
|
|
1584
1738
|
};
|
|
1585
|
-
var BALANCE_REFRESHING_ORDER_EVENTS = /* @__PURE__ */ new Set([
|
|
1739
|
+
var BALANCE_REFRESHING_ORDER_EVENTS = /* @__PURE__ */ new Set([
|
|
1740
|
+
"filled",
|
|
1741
|
+
"partial_fill",
|
|
1742
|
+
"cancelled"
|
|
1743
|
+
]);
|
|
1586
1744
|
var invalidateBalanceQueries = (queryClient, options) => {
|
|
1587
1745
|
var _a;
|
|
1588
1746
|
const refetchType = (_a = options == null ? void 0 : options.refetchType) != null ? _a : "active";
|
|
@@ -1603,6 +1761,7 @@ var invalidateBalanceQueries = (queryClient, options) => {
|
|
|
1603
1761
|
queryKey: balanceQueryKeys.venuePrefix(),
|
|
1604
1762
|
refetchType
|
|
1605
1763
|
});
|
|
1764
|
+
queryClient.invalidateQueries({ queryKey: ["agg", "hosted-venue-account"], refetchType });
|
|
1606
1765
|
};
|
|
1607
1766
|
var invalidatePositionQueries = (queryClient, options) => {
|
|
1608
1767
|
var _a;
|
|
@@ -1653,7 +1812,7 @@ var invalidateUserClaimState = (queryClient, options) => {
|
|
|
1653
1812
|
import { useContext as useContext7 } from "react";
|
|
1654
1813
|
|
|
1655
1814
|
// src/core/providers/agg-provider.tsx
|
|
1656
|
-
import { useQueryClient as
|
|
1815
|
+
import { useQueryClient as useQueryClient4 } from "@tanstack/react-query";
|
|
1657
1816
|
|
|
1658
1817
|
// src/core/providers/auth-provider.tsx
|
|
1659
1818
|
import { QueryClient, QueryClientContext } from "@tanstack/react-query";
|
|
@@ -2105,7 +2264,7 @@ var EMPTY_MANAGED_BALANCES = {
|
|
|
2105
2264
|
positions: []
|
|
2106
2265
|
};
|
|
2107
2266
|
function AggBalanceProvider({ children }) {
|
|
2108
|
-
var _a;
|
|
2267
|
+
var _a, _b;
|
|
2109
2268
|
const client = useContext2(AggClientContext);
|
|
2110
2269
|
const authContext = useContext2(AggAuthContext);
|
|
2111
2270
|
const { executionMode } = useResolvedExecutionMode();
|
|
@@ -2168,8 +2327,8 @@ function AggBalanceProvider({ children }) {
|
|
|
2168
2327
|
}
|
|
2169
2328
|
return sum + token.chains.reduce(
|
|
2170
2329
|
(chainSum, chain) => {
|
|
2171
|
-
var _a2,
|
|
2172
|
-
return chainSum + toTokenUnits((_a2 = chain.availableRaw) != null ? _a2 : chain.balanceRaw, (
|
|
2330
|
+
var _a2, _b2;
|
|
2331
|
+
return chainSum + toTokenUnits((_a2 = chain.availableRaw) != null ? _a2 : chain.balanceRaw, (_b2 = chain.decimals) != null ? _b2 : token.decimals);
|
|
2173
2332
|
},
|
|
2174
2333
|
0
|
|
2175
2334
|
);
|
|
@@ -2183,8 +2342,8 @@ function AggBalanceProvider({ children }) {
|
|
|
2183
2342
|
}
|
|
2184
2343
|
return sum + token.chains.reduce(
|
|
2185
2344
|
(chainSum, chain) => {
|
|
2186
|
-
var _a2,
|
|
2187
|
-
return chainSum + toTokenUnits((_a2 = chain.heldRaw) != null ? _a2 : "0", (
|
|
2345
|
+
var _a2, _b2;
|
|
2346
|
+
return chainSum + toTokenUnits((_a2 = chain.heldRaw) != null ? _a2 : "0", (_b2 = chain.decimals) != null ? _b2 : token.decimals);
|
|
2188
2347
|
},
|
|
2189
2348
|
0
|
|
2190
2349
|
);
|
|
@@ -2192,29 +2351,40 @@ function AggBalanceProvider({ children }) {
|
|
|
2192
2351
|
}, [managedBalances]);
|
|
2193
2352
|
const buildBalanceBreakdown = useCallback2(
|
|
2194
2353
|
(rawForChain) => {
|
|
2195
|
-
var _a2,
|
|
2196
|
-
const
|
|
2354
|
+
var _a2, _b2;
|
|
2355
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
2197
2356
|
const cash = managedBalances.cash;
|
|
2357
|
+
const chainVenues = connectedVenues.filter((venue) => venue !== "betdex");
|
|
2198
2358
|
for (const token of cash) {
|
|
2199
2359
|
if (!isUsdBasedToken(token.tokenSymbol)) continue;
|
|
2200
2360
|
for (const chain of token.chains) {
|
|
2201
|
-
const
|
|
2202
|
-
|
|
2361
|
+
const native = chain.custodyKind === "VENUE_ACCOUNT";
|
|
2362
|
+
const key = native ? JSON.stringify([
|
|
2363
|
+
"venue-account",
|
|
2364
|
+
chain.venue,
|
|
2365
|
+
chain.venueAccountId,
|
|
2366
|
+
chain.externalAccountId,
|
|
2367
|
+
chain.chainId
|
|
2368
|
+
]) : String(chain.chainId);
|
|
2369
|
+
const current = (_a2 = bySource.get(key)) != null ? _a2 : __spreadValues({
|
|
2370
|
+
key,
|
|
2371
|
+
label: native ? chain.venue ? resolveAggUiLabels("en").venues[chain.venue] : resolveAggUiLabels("en").userProfile.balance.venueAccount : chainLabelFromId(chain.chainId),
|
|
2203
2372
|
balance: 0,
|
|
2204
|
-
accountCount: 0
|
|
2205
|
-
|
|
2206
|
-
|
|
2373
|
+
accountCount: 0,
|
|
2374
|
+
venues: native && chain.venue ? [chain.venue] : chainVenues.length > 0 ? chainVenues : void 0
|
|
2375
|
+
}, native ? {
|
|
2376
|
+
venue: chain.venue,
|
|
2377
|
+
venueAccountId: chain.venueAccountId,
|
|
2378
|
+
externalAccountId: chain.externalAccountId,
|
|
2379
|
+
isFresh: chain.isFresh === true
|
|
2380
|
+
} : {});
|
|
2381
|
+
current.balance += toTokenUnits(rawForChain(chain), (_b2 = chain.decimals) != null ? _b2 : token.decimals);
|
|
2207
2382
|
current.accountCount += 1;
|
|
2208
|
-
|
|
2383
|
+
if (native) current.isFresh = current.isFresh === true && chain.isFresh === true;
|
|
2384
|
+
bySource.set(key, current);
|
|
2209
2385
|
}
|
|
2210
2386
|
}
|
|
2211
|
-
return Array.from(
|
|
2212
|
-
key: String(chainId),
|
|
2213
|
-
label: value2.label,
|
|
2214
|
-
balance: value2.balance,
|
|
2215
|
-
accountCount: value2.accountCount,
|
|
2216
|
-
venues: connectedVenues.length > 0 ? connectedVenues : void 0
|
|
2217
|
-
}));
|
|
2387
|
+
return Array.from(bySource.values()).sort((a, b) => a.label.localeCompare(b.label));
|
|
2218
2388
|
},
|
|
2219
2389
|
[connectedVenues, managedBalances.cash]
|
|
2220
2390
|
);
|
|
@@ -2236,8 +2406,27 @@ function AggBalanceProvider({ children }) {
|
|
|
2236
2406
|
return actualPositionsBalance + reservedBalance;
|
|
2237
2407
|
}, [managedBalances.positions, reservedBalance]);
|
|
2238
2408
|
const kalshiVenueCash = (_a = managedBalances.venueCash) == null ? void 0 : _a.find((item) => item.venue === "kalshi");
|
|
2409
|
+
const venueCashBalances = useMemo2(
|
|
2410
|
+
() => {
|
|
2411
|
+
var _a2;
|
|
2412
|
+
return Object.fromEntries(
|
|
2413
|
+
((_a2 = managedBalances.venueCash) != null ? _a2 : []).map((item) => [item.venue, item.balanceCents / 100])
|
|
2414
|
+
);
|
|
2415
|
+
},
|
|
2416
|
+
[managedBalances.venueCash]
|
|
2417
|
+
);
|
|
2239
2418
|
const kalshiBalance = kalshiVenueCash ? kalshiVenueCash.balanceCents / 100 : null;
|
|
2240
2419
|
const kalshiPortfolioValue = (kalshiVenueCash == null ? void 0 : kalshiVenueCash.portfolioValueCents) == null ? null : kalshiVenueCash.portfolioValueCents / 100;
|
|
2420
|
+
const betdexCash = (_b = managedBalances.venueCash) == null ? void 0 : _b.find(
|
|
2421
|
+
(item) => item.venue === "betdex" && item.accountModel === "platform-hosted"
|
|
2422
|
+
);
|
|
2423
|
+
const hostedUsd = (raw) => {
|
|
2424
|
+
if (raw === void 0 || !/^-?\d+$/.test(raw)) return null;
|
|
2425
|
+
const value2 = Number(raw) / 1e6;
|
|
2426
|
+
return Number.isFinite(value2) ? value2 : null;
|
|
2427
|
+
};
|
|
2428
|
+
const betdexBalance = (betdexCash == null ? void 0 : betdexCash.decimals) === 6 ? hostedUsd(betdexCash.balanceRaw) : null;
|
|
2429
|
+
const betdexAvailableBalance = (betdexCash == null ? void 0 : betdexCash.decimals) === 6 ? hostedUsd(betdexCash.availableRaw) : null;
|
|
2241
2430
|
const refetch = useCallback2(() => {
|
|
2242
2431
|
if (!isAuthenticated) return;
|
|
2243
2432
|
void refetchBalances();
|
|
@@ -2257,6 +2446,8 @@ function AggBalanceProvider({ children }) {
|
|
|
2257
2446
|
positionsBalanceTotal: 0,
|
|
2258
2447
|
kalshiBalance: null,
|
|
2259
2448
|
kalshiPortfolioValue: null,
|
|
2449
|
+
betdexBalance: null,
|
|
2450
|
+
betdexAvailableBalance: null,
|
|
2260
2451
|
balanceBreakdown: [],
|
|
2261
2452
|
availableBalanceBreakdown: [],
|
|
2262
2453
|
connectedVenues: [],
|
|
@@ -2275,7 +2466,10 @@ function AggBalanceProvider({ children }) {
|
|
|
2275
2466
|
reservedBalance,
|
|
2276
2467
|
positionsBalanceTotal,
|
|
2277
2468
|
kalshiBalance,
|
|
2469
|
+
venueCashBalances,
|
|
2278
2470
|
kalshiPortfolioValue,
|
|
2471
|
+
betdexBalance,
|
|
2472
|
+
betdexAvailableBalance,
|
|
2279
2473
|
balanceBreakdown,
|
|
2280
2474
|
availableBalanceBreakdown,
|
|
2281
2475
|
connectedVenues,
|
|
@@ -2293,7 +2487,10 @@ function AggBalanceProvider({ children }) {
|
|
|
2293
2487
|
isBalancesLoading,
|
|
2294
2488
|
isAuthenticated,
|
|
2295
2489
|
kalshiBalance,
|
|
2490
|
+
venueCashBalances,
|
|
2296
2491
|
kalshiPortfolioValue,
|
|
2492
|
+
betdexBalance,
|
|
2493
|
+
betdexAvailableBalance,
|
|
2297
2494
|
managedBalances,
|
|
2298
2495
|
balancesQuery.dataUpdatedAt,
|
|
2299
2496
|
positionsBalanceTotal,
|
|
@@ -2353,14 +2550,15 @@ function useCachedAppConfig() {
|
|
|
2353
2550
|
});
|
|
2354
2551
|
}
|
|
2355
2552
|
var toAppConfigResult = (query) => {
|
|
2356
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2553
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
2357
2554
|
return {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2555
|
+
prophetxExecutionMode: query.data ? (_a = query.data.prophetxExecutionMode) != null ? _a : "clearinghouse" : void 0,
|
|
2556
|
+
disabledVenues: (_c = (_b = query.data) == null ? void 0 : _b.disabledVenues) != null ? _c : [],
|
|
2557
|
+
disabledCategoryPresets: (_e = (_d = query.data) == null ? void 0 : _d.disabledCategoryPresets) != null ? _e : [],
|
|
2558
|
+
earlyAccessEnabled: (_g = (_f = query.data) == null ? void 0 : _f.earlyAccessEnabled) != null ? _g : false,
|
|
2559
|
+
authOptions: (_i = (_h = query.data) == null ? void 0 : _h.authOptions) != null ? _i : [],
|
|
2560
|
+
tradingMode: (_j = query.data) == null ? void 0 : _j.tradingMode,
|
|
2561
|
+
paperStartingBalance: (_k = query.data) == null ? void 0 : _k.paperStartingBalance,
|
|
2364
2562
|
isLoading: query.isLoading,
|
|
2365
2563
|
error: query.error
|
|
2366
2564
|
};
|
|
@@ -2422,254 +2620,11 @@ import {
|
|
|
2422
2620
|
useCallback as useCallback4,
|
|
2423
2621
|
useContext as useContext5,
|
|
2424
2622
|
useEffect as useEffect2,
|
|
2425
|
-
useMemo as
|
|
2623
|
+
useMemo as useMemo5,
|
|
2426
2624
|
useRef as useRef2,
|
|
2427
2625
|
useState as useState2
|
|
2428
2626
|
} from "react";
|
|
2429
|
-
import { useQueryClient as
|
|
2430
|
-
|
|
2431
|
-
// src/market-data/chart-cache.ts
|
|
2432
|
-
var MAX_CACHE_RETENTION_SECONDS = 7 * 30 * 24 * 60 * 60 + 14 * 24 * 60 * 60;
|
|
2433
|
-
var getIntervalSeconds = (interval) => {
|
|
2434
|
-
switch (interval) {
|
|
2435
|
-
case "1m":
|
|
2436
|
-
return 60;
|
|
2437
|
-
case "5m":
|
|
2438
|
-
return 5 * 60;
|
|
2439
|
-
case "1h":
|
|
2440
|
-
return 60 * 60;
|
|
2441
|
-
case "1d":
|
|
2442
|
-
return 24 * 60 * 60;
|
|
2443
|
-
}
|
|
2444
|
-
};
|
|
2445
|
-
var createVenueData = (venue, outcomeIds = []) => ({
|
|
2446
|
-
venue,
|
|
2447
|
-
outcomeIds,
|
|
2448
|
-
candles: [],
|
|
2449
|
-
liveCandle: null,
|
|
2450
|
-
lineValue: void 0,
|
|
2451
|
-
lastTrade: null,
|
|
2452
|
-
lastUpdateTs: null
|
|
2453
|
-
});
|
|
2454
|
-
var pruneCandlesBefore = (candles, cutoffTs) => {
|
|
2455
|
-
if (cutoffTs <= 0) return candles;
|
|
2456
|
-
let firstKeptIndex = 0;
|
|
2457
|
-
while (firstKeptIndex < candles.length && candles[firstKeptIndex].time < cutoffTs) {
|
|
2458
|
-
firstKeptIndex += 1;
|
|
2459
|
-
}
|
|
2460
|
-
if (firstKeptIndex === 0) return candles;
|
|
2461
|
-
return candles.slice(firstKeptIndex);
|
|
2462
|
-
};
|
|
2463
|
-
var promoteClosedLiveCandle = (candles, liveCandle, expectedCandleTime) => {
|
|
2464
|
-
if (!liveCandle || liveCandle.time >= expectedCandleTime) {
|
|
2465
|
-
return { candles, promoted: false };
|
|
2466
|
-
}
|
|
2467
|
-
if (candles.some((candle) => candle.time === liveCandle.time)) {
|
|
2468
|
-
return { candles, promoted: false };
|
|
2469
|
-
}
|
|
2470
|
-
return { candles: sortCandles([...candles, liveCandle]), promoted: true };
|
|
2471
|
-
};
|
|
2472
|
-
var resolveMaxLastUpdateTs = (venues) => {
|
|
2473
|
-
let max = null;
|
|
2474
|
-
for (const venueData of Object.values(venues)) {
|
|
2475
|
-
if (venueData.lastUpdateTs != null && (max == null || venueData.lastUpdateTs > max)) {
|
|
2476
|
-
max = venueData.lastUpdateTs;
|
|
2477
|
-
}
|
|
2478
|
-
}
|
|
2479
|
-
return max;
|
|
2480
|
-
};
|
|
2481
|
-
var sortCandles = (candles) => {
|
|
2482
|
-
return [...candles].sort((left, right) => left.time - right.time);
|
|
2483
|
-
};
|
|
2484
|
-
var createMarketChartData = (params) => {
|
|
2485
|
-
var _a;
|
|
2486
|
-
const candles = sortCandles(
|
|
2487
|
-
params.response.data.map((candle) => ({
|
|
2488
|
-
time: Math.floor(candle.t / 1e3),
|
|
2489
|
-
open: candle.o,
|
|
2490
|
-
high: candle.h,
|
|
2491
|
-
low: candle.l,
|
|
2492
|
-
close: candle.c,
|
|
2493
|
-
volume: candle.v,
|
|
2494
|
-
source: "rest"
|
|
2495
|
-
}))
|
|
2496
|
-
);
|
|
2497
|
-
const lastCandle = candles[candles.length - 1];
|
|
2498
|
-
const lastUpdateTs = (_a = lastCandle == null ? void 0 : lastCandle.time) != null ? _a : null;
|
|
2499
|
-
const venues = {
|
|
2500
|
-
[params.response.venue]: {
|
|
2501
|
-
venue: params.response.venue,
|
|
2502
|
-
outcomeIds: [params.response.venueMarketOutcomeId],
|
|
2503
|
-
candles,
|
|
2504
|
-
liveCandle: null,
|
|
2505
|
-
lineValue: lastCandle == null ? void 0 : lastCandle.close,
|
|
2506
|
-
lastTrade: null,
|
|
2507
|
-
lastUpdateTs
|
|
2508
|
-
}
|
|
2509
|
-
};
|
|
2510
|
-
return {
|
|
2511
|
-
marketId: params.marketId,
|
|
2512
|
-
outcomeIds: [params.response.venueMarketOutcomeId],
|
|
2513
|
-
primaryVenue: params.response.venue,
|
|
2514
|
-
interval: params.interval,
|
|
2515
|
-
startTs: params.startTs,
|
|
2516
|
-
endTs: params.endTs,
|
|
2517
|
-
venues,
|
|
2518
|
-
lastUpdateTs
|
|
2519
|
-
};
|
|
2520
|
-
};
|
|
2521
|
-
var mergeMarketChartData = (params) => {
|
|
2522
|
-
var _a, _b;
|
|
2523
|
-
if (params.datasets.length === 0) {
|
|
2524
|
-
return null;
|
|
2525
|
-
}
|
|
2526
|
-
const primaryVenue = (_b = (_a = params.datasets[0]) == null ? void 0 : _a.primaryVenue) != null ? _b : "aggregate";
|
|
2527
|
-
const outcomeIds = Array.from(
|
|
2528
|
-
new Set(
|
|
2529
|
-
params.datasets.flatMap((dataset) => {
|
|
2530
|
-
return dataset.outcomeIds.length > 0 ? dataset.outcomeIds : [dataset.marketId];
|
|
2531
|
-
})
|
|
2532
|
-
)
|
|
2533
|
-
);
|
|
2534
|
-
const venues = params.datasets.reduce((acc, dataset) => {
|
|
2535
|
-
for (const [venue, venueData] of Object.entries(dataset.venues)) {
|
|
2536
|
-
const existingVenueData = acc[venue];
|
|
2537
|
-
acc[venue] = existingVenueData ? __spreadProps(__spreadValues({}, venueData), {
|
|
2538
|
-
outcomeIds: Array.from(
|
|
2539
|
-
/* @__PURE__ */ new Set([...existingVenueData.outcomeIds, ...venueData.outcomeIds])
|
|
2540
|
-
)
|
|
2541
|
-
}) : venueData;
|
|
2542
|
-
}
|
|
2543
|
-
return acc;
|
|
2544
|
-
}, {});
|
|
2545
|
-
return {
|
|
2546
|
-
marketId: params.marketId,
|
|
2547
|
-
outcomeIds,
|
|
2548
|
-
primaryVenue,
|
|
2549
|
-
interval: params.interval,
|
|
2550
|
-
startTs: params.startTs,
|
|
2551
|
-
endTs: params.endTs,
|
|
2552
|
-
venues,
|
|
2553
|
-
lastUpdateTs: resolveMaxLastUpdateTs(venues)
|
|
2554
|
-
};
|
|
2555
|
-
};
|
|
2556
|
-
var applyMidpointToMarketChart = (data, update) => {
|
|
2557
|
-
var _a;
|
|
2558
|
-
if (!data || !Number.isFinite(update.midpoint)) {
|
|
2559
|
-
return data;
|
|
2560
|
-
}
|
|
2561
|
-
const targetVenueEntry = Object.entries(data.venues).find(
|
|
2562
|
-
([, venueData]) => venueData.outcomeIds.includes(update.outcomeId)
|
|
2563
|
-
);
|
|
2564
|
-
if (!targetVenueEntry && data.marketId !== update.outcomeId) {
|
|
2565
|
-
return data;
|
|
2566
|
-
}
|
|
2567
|
-
const [targetVenueName, currentVenue] = targetVenueEntry != null ? targetVenueEntry : [
|
|
2568
|
-
data.primaryVenue,
|
|
2569
|
-
(_a = data.venues[data.primaryVenue]) != null ? _a : createVenueData(data.primaryVenue, [update.outcomeId])
|
|
2570
|
-
];
|
|
2571
|
-
const intervalSeconds = getIntervalSeconds(data.interval);
|
|
2572
|
-
const expectedCandleTime = update.timestamp - update.timestamp % intervalSeconds;
|
|
2573
|
-
let liveCandle = currentVenue.liveCandle;
|
|
2574
|
-
const { candles: promotedCandles } = promoteClosedLiveCandle(
|
|
2575
|
-
currentVenue.candles,
|
|
2576
|
-
liveCandle,
|
|
2577
|
-
expectedCandleTime
|
|
2578
|
-
);
|
|
2579
|
-
const nextCandles = pruneCandlesBefore(
|
|
2580
|
-
promotedCandles,
|
|
2581
|
-
update.timestamp - MAX_CACHE_RETENTION_SECONDS
|
|
2582
|
-
);
|
|
2583
|
-
if (liveCandle && liveCandle.time === expectedCandleTime) {
|
|
2584
|
-
if (liveCandle.source === "trade") {
|
|
2585
|
-
liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
|
|
2586
|
-
close: update.midpoint
|
|
2587
|
-
});
|
|
2588
|
-
} else {
|
|
2589
|
-
liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
|
|
2590
|
-
close: update.midpoint,
|
|
2591
|
-
high: Math.max(liveCandle.high, update.midpoint),
|
|
2592
|
-
low: Math.min(liveCandle.low, update.midpoint),
|
|
2593
|
-
source: "midpoint"
|
|
2594
|
-
});
|
|
2595
|
-
}
|
|
2596
|
-
} else {
|
|
2597
|
-
liveCandle = {
|
|
2598
|
-
time: expectedCandleTime,
|
|
2599
|
-
open: update.midpoint,
|
|
2600
|
-
high: update.midpoint,
|
|
2601
|
-
low: update.midpoint,
|
|
2602
|
-
close: update.midpoint,
|
|
2603
|
-
volume: 0,
|
|
2604
|
-
source: "midpoint"
|
|
2605
|
-
};
|
|
2606
|
-
}
|
|
2607
|
-
const nextVenues = __spreadProps(__spreadValues({}, data.venues), {
|
|
2608
|
-
[targetVenueName]: __spreadProps(__spreadValues({}, currentVenue), {
|
|
2609
|
-
outcomeIds: currentVenue.outcomeIds.includes(update.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, update.outcomeId],
|
|
2610
|
-
candles: nextCandles,
|
|
2611
|
-
liveCandle,
|
|
2612
|
-
lineValue: update.midpoint,
|
|
2613
|
-
lastUpdateTs: update.timestamp
|
|
2614
|
-
})
|
|
2615
|
-
});
|
|
2616
|
-
return __spreadProps(__spreadValues({}, data), {
|
|
2617
|
-
venues: nextVenues,
|
|
2618
|
-
lastUpdateTs: resolveMaxLastUpdateTs(nextVenues)
|
|
2619
|
-
});
|
|
2620
|
-
};
|
|
2621
|
-
var applyTradeToMarketChart = (data, trade) => {
|
|
2622
|
-
var _a, _b, _c;
|
|
2623
|
-
if (!data || data.marketId !== trade.outcomeId) {
|
|
2624
|
-
return data;
|
|
2625
|
-
}
|
|
2626
|
-
const currentVenue = (_a = data.venues[trade.venue]) != null ? _a : createVenueData(trade.venue);
|
|
2627
|
-
const intervalSeconds = getIntervalSeconds(data.interval);
|
|
2628
|
-
const expectedCandleTime = trade.timestamp - trade.timestamp % intervalSeconds;
|
|
2629
|
-
let liveCandle = currentVenue.liveCandle;
|
|
2630
|
-
const { candles: promotedCandles } = promoteClosedLiveCandle(
|
|
2631
|
-
currentVenue.candles,
|
|
2632
|
-
liveCandle,
|
|
2633
|
-
expectedCandleTime
|
|
2634
|
-
);
|
|
2635
|
-
const nextCandles = pruneCandlesBefore(
|
|
2636
|
-
promotedCandles,
|
|
2637
|
-
trade.timestamp - MAX_CACHE_RETENTION_SECONDS
|
|
2638
|
-
);
|
|
2639
|
-
if (liveCandle && liveCandle.time === expectedCandleTime) {
|
|
2640
|
-
liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
|
|
2641
|
-
close: trade.price,
|
|
2642
|
-
high: Math.max(liveCandle.high, trade.price),
|
|
2643
|
-
low: Math.min(liveCandle.low, trade.price),
|
|
2644
|
-
volume: ((_b = liveCandle.volume) != null ? _b : 0) + trade.size,
|
|
2645
|
-
source: "trade"
|
|
2646
|
-
});
|
|
2647
|
-
} else if (!liveCandle || liveCandle.time !== expectedCandleTime) {
|
|
2648
|
-
liveCandle = {
|
|
2649
|
-
time: expectedCandleTime,
|
|
2650
|
-
open: trade.price,
|
|
2651
|
-
high: trade.price,
|
|
2652
|
-
low: trade.price,
|
|
2653
|
-
close: trade.price,
|
|
2654
|
-
volume: trade.size,
|
|
2655
|
-
source: "trade"
|
|
2656
|
-
};
|
|
2657
|
-
}
|
|
2658
|
-
const nextVenues = __spreadProps(__spreadValues({}, data.venues), {
|
|
2659
|
-
[trade.venue]: __spreadProps(__spreadValues({}, currentVenue), {
|
|
2660
|
-
outcomeIds: currentVenue.outcomeIds.includes(trade.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, trade.outcomeId],
|
|
2661
|
-
candles: nextCandles,
|
|
2662
|
-
liveCandle,
|
|
2663
|
-
lineValue: (_c = liveCandle == null ? void 0 : liveCandle.close) != null ? _c : trade.price,
|
|
2664
|
-
lastTrade: trade,
|
|
2665
|
-
lastUpdateTs: trade.timestamp
|
|
2666
|
-
})
|
|
2667
|
-
});
|
|
2668
|
-
return __spreadProps(__spreadValues({}, data), {
|
|
2669
|
-
venues: nextVenues,
|
|
2670
|
-
lastUpdateTs: resolveMaxLastUpdateTs(nextVenues)
|
|
2671
|
-
});
|
|
2672
|
-
};
|
|
2627
|
+
import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
|
|
2673
2628
|
|
|
2674
2629
|
// src/market-data/live-cache.ts
|
|
2675
2630
|
var MAX_TRADES = 50;
|
|
@@ -2682,13 +2637,6 @@ var createMarketLiveState = (marketId, overrides) => __spreadValues({
|
|
|
2682
2637
|
isConnected: false,
|
|
2683
2638
|
integrity: "ok"
|
|
2684
2639
|
}, overrides);
|
|
2685
|
-
var withLiveConnectionState = (data, isConnected) => {
|
|
2686
|
-
if (!data) return data;
|
|
2687
|
-
if (data.isConnected === isConnected) return data;
|
|
2688
|
-
return __spreadProps(__spreadValues({}, data), {
|
|
2689
|
-
isConnected
|
|
2690
|
-
});
|
|
2691
|
-
};
|
|
2692
2640
|
var withLiveOrderbook = (data, orderbook, source) => {
|
|
2693
2641
|
const current = data != null ? data : createMarketLiveState(orderbook.marketId);
|
|
2694
2642
|
return __spreadProps(__spreadValues({}, current), {
|
|
@@ -2723,133 +2671,254 @@ var withLiveTrade = (data, trade) => {
|
|
|
2723
2671
|
});
|
|
2724
2672
|
};
|
|
2725
2673
|
|
|
2726
|
-
// src/market-data/
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2674
|
+
// src/market-data/live-store.ts
|
|
2675
|
+
import { useMemo as useMemo4, useSyncExternalStore } from "react";
|
|
2676
|
+
import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
2677
|
+
|
|
2678
|
+
// src/market-data/query-keys.ts
|
|
2679
|
+
var marketDataKeys = {
|
|
2680
|
+
all: () => ["market-data"],
|
|
2681
|
+
live: (marketId) => ["market-data", "live", marketId],
|
|
2682
|
+
livePrefix: () => ["market-data", "live"],
|
|
2683
|
+
orderbook: (marketId, selectionKey, depth) => ["market-data", "orderbook", marketId, selectionKey != null ? selectionKey : null, depth != null ? depth : null],
|
|
2684
|
+
orderbookPrefix: (marketId) => marketId == null ? ["market-data", "orderbook"] : ["market-data", "orderbook", marketId],
|
|
2685
|
+
orderbookQuote: (marketId, side, size) => ["market-data", "orderbook-quote", marketId, side, size],
|
|
2686
|
+
/**
|
|
2687
|
+
* Stable per `{marketId, interval, rangeKey}`. Deliberately excludes the
|
|
2688
|
+
* concrete `startTs`/`endTs` of the rolling window — those advance every
|
|
2689
|
+
* candle bucket, and including them would mint a fresh key on every
|
|
2690
|
+
* rollover, defeating React Query's cache on tab/page revisits. The
|
|
2691
|
+
* current window is passed to `queryFn` via closure instead, and
|
|
2692
|
+
* `refetchInterval` advances the data under the stable key.
|
|
2693
|
+
*/
|
|
2694
|
+
chart: (marketId, interval, rangeKey, countBack) => ["market-data", "chart", marketId, interval, rangeKey, countBack != null ? countBack : null],
|
|
2695
|
+
chartPrefix: (marketId, interval) => {
|
|
2696
|
+
if (!marketId) return ["market-data", "chart"];
|
|
2697
|
+
if (!interval) return ["market-data", "chart", marketId];
|
|
2698
|
+
return ["market-data", "chart", marketId, interval];
|
|
2699
|
+
}
|
|
2730
2700
|
};
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
asks: truncateLevels(book.asks, depth)
|
|
2739
|
-
}
|
|
2740
|
-
])
|
|
2741
|
-
);
|
|
2701
|
+
|
|
2702
|
+
// src/market-data/live-store.ts
|
|
2703
|
+
var LIVE_RETENTION = {
|
|
2704
|
+
maxInactiveSnapshots: 32,
|
|
2705
|
+
maxInactiveLevels: 16384,
|
|
2706
|
+
inactiveTtlMs: 5e3,
|
|
2707
|
+
maxEntries: 300
|
|
2742
2708
|
};
|
|
2743
|
-
var
|
|
2744
|
-
var _a;
|
|
2745
|
-
const
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2709
|
+
var levelEntries = (state) => {
|
|
2710
|
+
var _a, _b, _c, _d, _e;
|
|
2711
|
+
const book = state.orderbook;
|
|
2712
|
+
return book ? ((_b = (_a = book.bids) == null ? void 0 : _a.length) != null ? _b : 0) + ((_d = (_c = book.asks) == null ? void 0 : _c.length) != null ? _d : 0) + Object.values((_e = book.venueOrderbooks) != null ? _e : {}).reduce(
|
|
2713
|
+
(n, venue) => n + venue.bids.length + venue.asks.length,
|
|
2714
|
+
0
|
|
2715
|
+
) : 0;
|
|
2716
|
+
};
|
|
2717
|
+
var hasSnapshot = (state) => !!state.orderbook || !!state.candles || state.trades.length > 0;
|
|
2718
|
+
var MarketLiveStore = class {
|
|
2719
|
+
constructor(seed) {
|
|
2720
|
+
this.seed = seed;
|
|
2721
|
+
this.connectionState = false;
|
|
2722
|
+
this.connectionGeneration = 0;
|
|
2723
|
+
this.states = /* @__PURE__ */ new Map();
|
|
2724
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
2725
|
+
this.touched = /* @__PURE__ */ new Map();
|
|
2726
|
+
this.needsPrune = false;
|
|
2727
|
+
}
|
|
2728
|
+
ensure(id) {
|
|
2729
|
+
var _a, _b;
|
|
2730
|
+
let state = this.states.get(id);
|
|
2731
|
+
if (state && !this.listeners.has(id) && Date.now() - ((_a = this.touched.get(id)) != null ? _a : 0) >= LIVE_RETENTION.inactiveTtlMs) {
|
|
2732
|
+
this.drop(id);
|
|
2733
|
+
state = void 0;
|
|
2734
|
+
}
|
|
2735
|
+
if (!state) {
|
|
2736
|
+
const seed = (_b = this.seed) == null ? void 0 : _b.call(this, id);
|
|
2737
|
+
state = __spreadProps(__spreadValues({}, createMarketLiveState(id, __spreadValues({ isConnected: this.connectionState }, seed))), {
|
|
2738
|
+
connectionGeneration: this.connectionGeneration,
|
|
2739
|
+
orderbookGeneration: (seed == null ? void 0 : seed.orderbook) ? -1 : this.connectionGeneration
|
|
2760
2740
|
});
|
|
2741
|
+
this.states.set(id, state);
|
|
2742
|
+
this.touched.set(id, Date.now());
|
|
2743
|
+
this.needsPrune = true;
|
|
2761
2744
|
}
|
|
2745
|
+
return state;
|
|
2746
|
+
}
|
|
2747
|
+
get(id) {
|
|
2748
|
+
const state = this.ensure(id);
|
|
2749
|
+
this.touched.set(id, Date.now());
|
|
2750
|
+
if (this.needsPrune) this.prune(/* @__PURE__ */ new Set([id]));
|
|
2751
|
+
return state;
|
|
2752
|
+
}
|
|
2753
|
+
/** Read retained data without creating a state, keeping it alive, or observing updates. */
|
|
2754
|
+
peek(id) {
|
|
2755
|
+
var _a;
|
|
2756
|
+
if (!this.listeners.has(id) && Date.now() - ((_a = this.touched.get(id)) != null ? _a : 0) >= LIVE_RETENTION.inactiveTtlMs)
|
|
2757
|
+
return void 0;
|
|
2758
|
+
return this.states.get(id);
|
|
2759
|
+
}
|
|
2760
|
+
/** Protect a render's whole selection before useSyncExternalStore subscribes. */
|
|
2761
|
+
getMany(ids) {
|
|
2762
|
+
const result = ids.map((id) => {
|
|
2763
|
+
const state = this.ensure(id);
|
|
2764
|
+
this.touched.set(id, Date.now());
|
|
2765
|
+
return state;
|
|
2766
|
+
});
|
|
2767
|
+
if (this.needsPrune) this.prune(new Set(ids));
|
|
2768
|
+
return result;
|
|
2769
|
+
}
|
|
2770
|
+
update(id, updater) {
|
|
2771
|
+
var _a;
|
|
2772
|
+
const previous = this.ensure(id);
|
|
2773
|
+
const next = updater(previous);
|
|
2774
|
+
if (!next || next === previous) return;
|
|
2775
|
+
const bookChanged = next.orderbook && (!previous.orderbook || next.orderbook.seq !== previous.orderbook.seq || next.orderbook.checksum !== previous.orderbook.checksum || next.orderbook.timestamp !== previous.orderbook.timestamp || next.orderbookSnapshotVersion !== previous.orderbookSnapshotVersion);
|
|
2776
|
+
this.states.set(
|
|
2777
|
+
id,
|
|
2778
|
+
bookChanged ? __spreadProps(__spreadValues({}, next), { orderbookGeneration: this.connectionGeneration }) : next
|
|
2779
|
+
);
|
|
2780
|
+
if (bookChanged || next.candles !== previous.candles || next.trades !== previous.trades)
|
|
2781
|
+
this.touched.set(id, Date.now());
|
|
2782
|
+
for (const listener of (_a = this.listeners.get(id)) != null ? _a : []) listener();
|
|
2783
|
+
if (!this.listeners.has(id) || this.needsPrune) this.prune(/* @__PURE__ */ new Set([id]));
|
|
2784
|
+
}
|
|
2785
|
+
connected(connected) {
|
|
2786
|
+
if (connected && !this.connectionState) this.connectionGeneration++;
|
|
2787
|
+
this.connectionState = connected;
|
|
2788
|
+
for (const id of [...this.states.keys()])
|
|
2789
|
+
this.update(
|
|
2790
|
+
id,
|
|
2791
|
+
(state) => state.isConnected === connected && state.connectionGeneration === this.connectionGeneration ? state : __spreadValues(__spreadProps(__spreadValues({}, state), {
|
|
2792
|
+
isConnected: connected,
|
|
2793
|
+
connectionGeneration: this.connectionGeneration
|
|
2794
|
+
}), connected ? {} : { candles: void 0 })
|
|
2795
|
+
);
|
|
2796
|
+
}
|
|
2797
|
+
subscribe(ids, listener) {
|
|
2798
|
+
var _a;
|
|
2799
|
+
for (const id of ids) {
|
|
2800
|
+
const set = (_a = this.listeners.get(id)) != null ? _a : /* @__PURE__ */ new Set();
|
|
2801
|
+
set.add(listener);
|
|
2802
|
+
this.listeners.set(id, set);
|
|
2803
|
+
this.touched.set(id, Date.now());
|
|
2804
|
+
}
|
|
2805
|
+
return () => {
|
|
2806
|
+
for (const id of ids) {
|
|
2807
|
+
const set = this.listeners.get(id);
|
|
2808
|
+
set == null ? void 0 : set.delete(listener);
|
|
2809
|
+
if (!(set == null ? void 0 : set.size)) {
|
|
2810
|
+
this.listeners.delete(id);
|
|
2811
|
+
this.touched.set(id, Date.now());
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
this.prune();
|
|
2815
|
+
};
|
|
2816
|
+
}
|
|
2817
|
+
getDiagnostics() {
|
|
2818
|
+
const inactive = [...this.states].filter(([id]) => !this.listeners.has(id));
|
|
2819
|
+
return {
|
|
2820
|
+
entries: this.states.size,
|
|
2821
|
+
activeEntries: this.listeners.size,
|
|
2822
|
+
cachedBooks: [...this.states.values()].filter((state) => state.orderbook).length,
|
|
2823
|
+
cachedLevelEntries: [...this.states.values()].reduce(
|
|
2824
|
+
(n, state) => n + levelEntries(state),
|
|
2825
|
+
0
|
|
2826
|
+
),
|
|
2827
|
+
inactiveSnapshots: inactive.filter(([, state]) => hasSnapshot(state)).length,
|
|
2828
|
+
inactiveLevelEntries: inactive.reduce((n, [, state]) => n + levelEntries(state), 0),
|
|
2829
|
+
limits: LIVE_RETENTION
|
|
2830
|
+
};
|
|
2831
|
+
}
|
|
2832
|
+
drop(id) {
|
|
2833
|
+
this.states.delete(id);
|
|
2834
|
+
this.touched.delete(id);
|
|
2835
|
+
}
|
|
2836
|
+
prune(protectedIds = /* @__PURE__ */ new Set()) {
|
|
2837
|
+
var _a, _b;
|
|
2838
|
+
this.needsPrune = false;
|
|
2839
|
+
if (this.timer) clearTimeout(this.timer);
|
|
2840
|
+
this.timer = void 0;
|
|
2841
|
+
const now = Date.now();
|
|
2842
|
+
const inactive = [...this.states].filter(([id]) => !this.listeners.has(id) && !protectedIds.has(id)).sort(([a], [b]) => {
|
|
2843
|
+
var _a2, _b2;
|
|
2844
|
+
return ((_a2 = this.touched.get(a)) != null ? _a2 : 0) - ((_b2 = this.touched.get(b)) != null ? _b2 : 0);
|
|
2845
|
+
});
|
|
2846
|
+
let count = inactive.filter(([, state]) => hasSnapshot(state)).length;
|
|
2847
|
+
let levels = inactive.reduce((n, [, state]) => n + levelEntries(state), 0);
|
|
2848
|
+
for (const [id, state] of inactive) {
|
|
2849
|
+
if (now - ((_a = this.touched.get(id)) != null ? _a : 0) >= LIVE_RETENTION.inactiveTtlMs || this.states.size > LIVE_RETENTION.maxEntries || count > LIVE_RETENTION.maxInactiveSnapshots || levels > LIVE_RETENTION.maxInactiveLevels) {
|
|
2850
|
+
if (hasSnapshot(state)) count--;
|
|
2851
|
+
levels -= levelEntries(state);
|
|
2852
|
+
this.drop(id);
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
let nextExpiry = Infinity;
|
|
2856
|
+
for (const id of this.states.keys())
|
|
2857
|
+
if (!this.listeners.has(id))
|
|
2858
|
+
nextExpiry = Math.min(
|
|
2859
|
+
nextExpiry,
|
|
2860
|
+
((_b = this.touched.get(id)) != null ? _b : now) + LIVE_RETENTION.inactiveTtlMs
|
|
2861
|
+
);
|
|
2862
|
+
if (Number.isFinite(nextExpiry))
|
|
2863
|
+
this.timer = setTimeout(
|
|
2864
|
+
() => {
|
|
2865
|
+
this.timer = void 0;
|
|
2866
|
+
this.prune();
|
|
2867
|
+
},
|
|
2868
|
+
Math.max(1, nextExpiry - now)
|
|
2869
|
+
);
|
|
2762
2870
|
}
|
|
2763
|
-
return [...levelsByPrice.values()].sort(
|
|
2764
|
-
(left, right) => side === "bids" ? right.price - left.price : left.price - right.price
|
|
2765
|
-
);
|
|
2766
|
-
};
|
|
2767
|
-
var createMarketOrderbookDataFromVenueOrderbooks = ({
|
|
2768
|
-
marketId,
|
|
2769
|
-
venueOrderbooks,
|
|
2770
|
-
timestamp = Math.floor(Date.now() / 1e3)
|
|
2771
|
-
}) => {
|
|
2772
|
-
var _a, _b, _c, _d;
|
|
2773
|
-
const bids = aggregateVenueLevels(venueOrderbooks, "bids");
|
|
2774
|
-
const asks = aggregateVenueLevels(venueOrderbooks, "asks");
|
|
2775
|
-
const bestBid = (_b = (_a = bids[0]) == null ? void 0 : _a.price) != null ? _b : null;
|
|
2776
|
-
const bestAsk = (_d = (_c = asks[0]) == null ? void 0 : _c.price) != null ? _d : null;
|
|
2777
|
-
return {
|
|
2778
|
-
marketId,
|
|
2779
|
-
orderbook: {
|
|
2780
|
-
bids,
|
|
2781
|
-
asks
|
|
2782
|
-
},
|
|
2783
|
-
venueOrderbooks,
|
|
2784
|
-
venues: Object.fromEntries(
|
|
2785
|
-
Object.entries(venueOrderbooks).map(([venue, orderbook]) => {
|
|
2786
|
-
var _a2, _b2, _c2, _d2;
|
|
2787
|
-
return [
|
|
2788
|
-
venue,
|
|
2789
|
-
{
|
|
2790
|
-
bestBid: (_b2 = (_a2 = orderbook.bids[0]) == null ? void 0 : _a2.price) != null ? _b2 : null,
|
|
2791
|
-
bestAsk: (_d2 = (_c2 = orderbook.asks[0]) == null ? void 0 : _c2.price) != null ? _d2 : null
|
|
2792
|
-
}
|
|
2793
|
-
];
|
|
2794
|
-
})
|
|
2795
|
-
),
|
|
2796
|
-
midpoint: bestBid != null && bestAsk != null ? (bestBid + bestAsk) / 2 : null,
|
|
2797
|
-
spread: bestBid != null && bestAsk != null ? bestAsk - bestBid : null,
|
|
2798
|
-
timestamp,
|
|
2799
|
-
snapshotVersion: 0,
|
|
2800
|
-
integrity: "ok"
|
|
2801
|
-
};
|
|
2802
|
-
};
|
|
2803
|
-
var createMarketOrderbookDataFromState = (state, options) => {
|
|
2804
|
-
var _a;
|
|
2805
|
-
return {
|
|
2806
|
-
marketId: state.marketId,
|
|
2807
|
-
orderbook: {
|
|
2808
|
-
bids: state.bids,
|
|
2809
|
-
asks: state.asks
|
|
2810
|
-
},
|
|
2811
|
-
venueOrderbooks: state.venueOrderbooks,
|
|
2812
|
-
venues: state.venues,
|
|
2813
|
-
midpoint: state.midpoint,
|
|
2814
|
-
spread: state.spread,
|
|
2815
|
-
timestamp: state.timestamp,
|
|
2816
|
-
snapshotVersion: (_a = options == null ? void 0 : options.snapshotVersion) != null ? _a : 0,
|
|
2817
|
-
seq: state.seq,
|
|
2818
|
-
checksum: state.checksum,
|
|
2819
|
-
integrity: "ok"
|
|
2820
|
-
};
|
|
2821
|
-
};
|
|
2822
|
-
var marketOrderbookDataToResponse = (data) => {
|
|
2823
|
-
return {
|
|
2824
|
-
venueMarketId: data.marketId,
|
|
2825
|
-
orderbook: data.orderbook,
|
|
2826
|
-
venueOrderbooks: data.venueOrderbooks,
|
|
2827
|
-
venues: data.venues,
|
|
2828
|
-
midpoint: data.midpoint,
|
|
2829
|
-
spread: data.spread,
|
|
2830
|
-
timestamp: data.timestamp,
|
|
2831
|
-
seq: data.seq,
|
|
2832
|
-
checksum: data.checksum,
|
|
2833
|
-
matchedMarkets: data.matchedMarkets
|
|
2834
|
-
};
|
|
2835
|
-
};
|
|
2836
|
-
var withOrderbookIntegrity = (data, integrity) => {
|
|
2837
|
-
if (!data) return data;
|
|
2838
|
-
if (data.integrity === integrity) return data;
|
|
2839
|
-
return __spreadProps(__spreadValues({}, data), {
|
|
2840
|
-
integrity
|
|
2841
|
-
});
|
|
2842
|
-
};
|
|
2843
|
-
var applyOrderbookDepth = (data, depth) => {
|
|
2844
|
-
if (depth == null) return data;
|
|
2845
|
-
return __spreadProps(__spreadValues({}, data), {
|
|
2846
|
-
orderbook: {
|
|
2847
|
-
bids: truncateLevels(data.orderbook.bids, depth),
|
|
2848
|
-
asks: truncateLevels(data.orderbook.asks, depth)
|
|
2849
|
-
},
|
|
2850
|
-
venueOrderbooks: truncateVenueOrderbooks(data.venueOrderbooks, depth)
|
|
2851
|
-
});
|
|
2852
2871
|
};
|
|
2872
|
+
var stores = /* @__PURE__ */ new WeakMap();
|
|
2873
|
+
function getMarketLiveStore(client) {
|
|
2874
|
+
let store = stores.get(client);
|
|
2875
|
+
if (!store) {
|
|
2876
|
+
store = new MarketLiveStore((id) => {
|
|
2877
|
+
var _a;
|
|
2878
|
+
return (_a = client.getQueryData) == null ? void 0 : _a.call(client, marketDataKeys.live(id));
|
|
2879
|
+
});
|
|
2880
|
+
stores.set(client, store);
|
|
2881
|
+
}
|
|
2882
|
+
return store;
|
|
2883
|
+
}
|
|
2884
|
+
function useLiveStates(ids) {
|
|
2885
|
+
const client = useQueryClient2();
|
|
2886
|
+
const store = getMarketLiveStore(client);
|
|
2887
|
+
const key = JSON.stringify(ids);
|
|
2888
|
+
const selector = useMemo4(() => {
|
|
2889
|
+
const selectedIds = JSON.parse(key);
|
|
2890
|
+
let previous = [];
|
|
2891
|
+
return {
|
|
2892
|
+
subscribe: (listener) => store.subscribe(selectedIds, listener),
|
|
2893
|
+
get: () => {
|
|
2894
|
+
const next = store.getMany(selectedIds).map((data) => ({ data }));
|
|
2895
|
+
if (next.length === previous.length && next.every((entry, index) => {
|
|
2896
|
+
var _a;
|
|
2897
|
+
return entry.data === ((_a = previous[index]) == null ? void 0 : _a.data);
|
|
2898
|
+
}))
|
|
2899
|
+
return previous;
|
|
2900
|
+
previous = next;
|
|
2901
|
+
return next;
|
|
2902
|
+
}
|
|
2903
|
+
};
|
|
2904
|
+
}, [key, store]);
|
|
2905
|
+
return useSyncExternalStore(selector.subscribe, selector.get, selector.get);
|
|
2906
|
+
}
|
|
2907
|
+
function mergeCandleTails(previous, next) {
|
|
2908
|
+
return Object.fromEntries(
|
|
2909
|
+
["1m", "5m", "1h", "1d"].map((interval) => {
|
|
2910
|
+
var _a;
|
|
2911
|
+
const oldClosed = (_a = previous == null ? void 0 : previous[interval].closed) != null ? _a : [];
|
|
2912
|
+
const incoming = next[interval].closed;
|
|
2913
|
+
const closed = incoming.length ? [
|
|
2914
|
+
...new Map(
|
|
2915
|
+
[...oldClosed, ...incoming].map((candle) => [candle.openTime, candle])
|
|
2916
|
+
).values()
|
|
2917
|
+
].sort((a, b) => a.openTime - b.openTime).slice(-500) : oldClosed;
|
|
2918
|
+
return [interval, { forming: next[interval].forming, closed }];
|
|
2919
|
+
})
|
|
2920
|
+
);
|
|
2921
|
+
}
|
|
2853
2922
|
|
|
2854
2923
|
// src/market-data/market-resolution-cache.ts
|
|
2855
2924
|
var isRecord = (value) => {
|
|
@@ -2943,29 +3012,116 @@ var applyResolutionToCachedData = (data, resolution) => {
|
|
|
2943
3012
|
return changed ? next : data;
|
|
2944
3013
|
};
|
|
2945
3014
|
|
|
2946
|
-
// src/market-data/
|
|
2947
|
-
var
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
* current window is passed to `queryFn` via closure instead, and
|
|
2960
|
-
* `refetchInterval` advances the data under the stable key.
|
|
2961
|
-
*/
|
|
2962
|
-
chart: (marketId, interval, rangeKey, countBack) => ["market-data", "chart", marketId, interval, rangeKey, countBack != null ? countBack : null],
|
|
2963
|
-
chartPrefix: (marketId, interval) => {
|
|
2964
|
-
if (!marketId) return ["market-data", "chart"];
|
|
2965
|
-
if (!interval) return ["market-data", "chart", marketId];
|
|
2966
|
-
return ["market-data", "chart", marketId, interval];
|
|
2967
|
-
}
|
|
3015
|
+
// src/market-data/history-retention.ts
|
|
3016
|
+
var DEFAULT_HISTORY_RETENTION = {
|
|
3017
|
+
maxInactiveQueries: 16,
|
|
3018
|
+
maxInactivePoints: 2e4
|
|
3019
|
+
};
|
|
3020
|
+
var owners = /* @__PURE__ */ new WeakMap();
|
|
3021
|
+
var isHistory = (key) => key[0] === "market-data" && key[1] === "chart";
|
|
3022
|
+
var points = (data) => {
|
|
3023
|
+
const chart = data;
|
|
3024
|
+
return (chart == null ? void 0 : chart.venues) ? Object.values(chart.venues).reduce(
|
|
3025
|
+
(total, venue) => total + venue.candles.length + (venue.liveCandle ? 1 : 0),
|
|
3026
|
+
0
|
|
3027
|
+
) : 0;
|
|
2968
3028
|
};
|
|
3029
|
+
function getChartHistoryRetentionStats(client) {
|
|
3030
|
+
var _a, _b, _c;
|
|
3031
|
+
const queries = client.getQueryCache().findAll({ queryKey: marketDataKeys.chartPrefix() });
|
|
3032
|
+
const active = queries.filter((query) => query.getObserversCount() > 0);
|
|
3033
|
+
const inactive = queries.filter((query) => query.getObserversCount() === 0);
|
|
3034
|
+
const owner = owners.get(client);
|
|
3035
|
+
return {
|
|
3036
|
+
activeQueries: active.length,
|
|
3037
|
+
inactiveQueries: inactive.length,
|
|
3038
|
+
activePoints: active.reduce((sum, query) => sum + points(query.state.data), 0),
|
|
3039
|
+
inactivePoints: inactive.reduce((sum, query) => sum + points(query.state.data), 0),
|
|
3040
|
+
inFlightQueries: queries.filter((query) => query.state.fetchStatus === "fetching").length,
|
|
3041
|
+
trackedQueries: (_a = owner == null ? void 0 : owner.touched.size) != null ? _a : 0,
|
|
3042
|
+
evictedQueries: (_b = owner == null ? void 0 : owner.evicted) != null ? _b : 0,
|
|
3043
|
+
limits: (_c = owner == null ? void 0 : owner.limits) != null ? _c : DEFAULT_HISTORY_RETENTION
|
|
3044
|
+
};
|
|
3045
|
+
}
|
|
3046
|
+
function installChartHistoryRetention(client, limits = DEFAULT_HISTORY_RETENTION) {
|
|
3047
|
+
let owner = owners.get(client);
|
|
3048
|
+
if (!owner) {
|
|
3049
|
+
owner = {
|
|
3050
|
+
refs: 0,
|
|
3051
|
+
clock: Date.now(),
|
|
3052
|
+
touched: /* @__PURE__ */ new Map(),
|
|
3053
|
+
evicted: 0,
|
|
3054
|
+
queued: false,
|
|
3055
|
+
pruning: false,
|
|
3056
|
+
limits,
|
|
3057
|
+
unsubscribe: () => {
|
|
3058
|
+
},
|
|
3059
|
+
prune: () => {
|
|
3060
|
+
}
|
|
3061
|
+
};
|
|
3062
|
+
owners.set(client, owner);
|
|
3063
|
+
const current2 = owner;
|
|
3064
|
+
const prune = () => {
|
|
3065
|
+
if (current2.pruning) return;
|
|
3066
|
+
current2.pruning = true;
|
|
3067
|
+
try {
|
|
3068
|
+
const inactive = client.getQueryCache().findAll({ queryKey: marketDataKeys.chartPrefix() }).filter((query) => query.getObserversCount() === 0).sort(
|
|
3069
|
+
(a, b) => {
|
|
3070
|
+
var _a, _b;
|
|
3071
|
+
return ((_a = current2.touched.get(a.queryHash)) != null ? _a : a.state.dataUpdatedAt) - ((_b = current2.touched.get(b.queryHash)) != null ? _b : b.state.dataUpdatedAt);
|
|
3072
|
+
}
|
|
3073
|
+
);
|
|
3074
|
+
let count = inactive.length;
|
|
3075
|
+
let totalPoints = inactive.reduce((sum, query) => sum + points(query.state.data), 0);
|
|
3076
|
+
for (const query of inactive) {
|
|
3077
|
+
if (count <= current2.limits.maxInactiveQueries && totalPoints <= current2.limits.maxInactivePoints)
|
|
3078
|
+
break;
|
|
3079
|
+
if (query.getObserversCount() > 0) continue;
|
|
3080
|
+
count--;
|
|
3081
|
+
totalPoints -= points(query.state.data);
|
|
3082
|
+
current2.evicted++;
|
|
3083
|
+
current2.touched.delete(query.queryHash);
|
|
3084
|
+
client.removeQueries({ queryKey: query.queryKey, exact: true });
|
|
3085
|
+
}
|
|
3086
|
+
} finally {
|
|
3087
|
+
current2.pruning = false;
|
|
3088
|
+
}
|
|
3089
|
+
};
|
|
3090
|
+
current2.prune = prune;
|
|
3091
|
+
const schedule = () => {
|
|
3092
|
+
if (current2.queued) return;
|
|
3093
|
+
current2.queued = true;
|
|
3094
|
+
queueMicrotask(() => {
|
|
3095
|
+
current2.queued = false;
|
|
3096
|
+
prune();
|
|
3097
|
+
});
|
|
3098
|
+
};
|
|
3099
|
+
current2.unsubscribe = client.getQueryCache().subscribe((event) => {
|
|
3100
|
+
if (!isHistory(event.query.queryKey)) return;
|
|
3101
|
+
if (event.type === "removed") current2.touched.delete(event.query.queryHash);
|
|
3102
|
+
else if (event.type === "observerAdded" || event.type === "updated" || event.type === "added") {
|
|
3103
|
+
current2.clock = Math.max(current2.clock + 1, Date.now());
|
|
3104
|
+
current2.touched.set(event.query.queryHash, current2.clock);
|
|
3105
|
+
}
|
|
3106
|
+
if (!current2.pruning) schedule();
|
|
3107
|
+
});
|
|
3108
|
+
schedule();
|
|
3109
|
+
}
|
|
3110
|
+
owner.refs++;
|
|
3111
|
+
const current = owner;
|
|
3112
|
+
let released = false;
|
|
3113
|
+
return () => {
|
|
3114
|
+
if (released) return;
|
|
3115
|
+
released = true;
|
|
3116
|
+
if (--current.refs > 0) return;
|
|
3117
|
+
queueMicrotask(() => {
|
|
3118
|
+
if (current.refs > 0) return;
|
|
3119
|
+
current.prune();
|
|
3120
|
+
current.unsubscribe();
|
|
3121
|
+
owners.delete(client);
|
|
3122
|
+
});
|
|
3123
|
+
};
|
|
3124
|
+
}
|
|
2969
3125
|
|
|
2970
3126
|
// src/core/providers/hooks.ts
|
|
2971
3127
|
import { useContext as useContext4 } from "react";
|
|
@@ -3012,20 +3168,12 @@ var AggWebSocketContext = createContext3(null);
|
|
|
3012
3168
|
var AggWebSocketConnectionContext = createContext3(false);
|
|
3013
3169
|
var AggWsUserEventContext = createContext3(null);
|
|
3014
3170
|
var snapshotUnavailableOutcomeIdPattern = /snapshot unavailable for\s+([^\s]+)/i;
|
|
3015
|
-
var ORDERBOOK_DEBUG_TOP_LEVELS = 5;
|
|
3016
3171
|
var resolveSnapshotUnavailableOutcomeId = (errorMessage) => {
|
|
3017
3172
|
var _a;
|
|
3018
3173
|
const matchedOutcomeId = (_a = snapshotUnavailableOutcomeIdPattern.exec(errorMessage)) == null ? void 0 : _a[1];
|
|
3019
3174
|
if (!matchedOutcomeId) return null;
|
|
3020
3175
|
return matchedOutcomeId.replace(/[.,;:!?]+$/, "");
|
|
3021
3176
|
};
|
|
3022
|
-
var summarizeTopLevels = (levels) => {
|
|
3023
|
-
return levels.slice(0, ORDERBOOK_DEBUG_TOP_LEVELS).map((level) => ({ price: level.price, size: level.size }));
|
|
3024
|
-
};
|
|
3025
|
-
var debugOrderbook = (enabled, event, payload) => {
|
|
3026
|
-
if (!enabled) return;
|
|
3027
|
-
console.debug(`[AggHooks][ws-provider] ${event}`, payload);
|
|
3028
|
-
};
|
|
3029
3177
|
function useAggWebSocket() {
|
|
3030
3178
|
return useContext5(AggWebSocketContext);
|
|
3031
3179
|
}
|
|
@@ -3105,7 +3253,9 @@ function useOnWithdrawalLifecycle(callback) {
|
|
|
3105
3253
|
function AggWebSocketProvider({ children }) {
|
|
3106
3254
|
const client = useAggClient();
|
|
3107
3255
|
const { enableWebsocketsLogs } = useAggUiConfig();
|
|
3108
|
-
const queryClient =
|
|
3256
|
+
const queryClient = useQueryClient3();
|
|
3257
|
+
const liveStore = getMarketLiveStore(queryClient);
|
|
3258
|
+
useEffect2(() => installChartHistoryRetention(queryClient), [queryClient]);
|
|
3109
3259
|
const [ws, setWs] = useState2(null);
|
|
3110
3260
|
const [isConnected, setIsConnected] = useState2(false);
|
|
3111
3261
|
const [isClientAuthenticated, setIsClientAuthenticated] = useState2(client.isAuthenticated);
|
|
@@ -3125,7 +3275,7 @@ function AggWebSocketProvider({ children }) {
|
|
|
3125
3275
|
const withdrawalLifecycleListenersRef = useRef2(
|
|
3126
3276
|
/* @__PURE__ */ new Set()
|
|
3127
3277
|
);
|
|
3128
|
-
const userEventListeners =
|
|
3278
|
+
const userEventListeners = useMemo5(
|
|
3129
3279
|
() => ({
|
|
3130
3280
|
addOrderSubmittedListener: (cb) => {
|
|
3131
3281
|
orderSubmittedListenersRef.current.add(cb);
|
|
@@ -3160,43 +3310,11 @@ function AggWebSocketProvider({ children }) {
|
|
|
3160
3310
|
}),
|
|
3161
3311
|
[]
|
|
3162
3312
|
);
|
|
3163
|
-
const syncOrderbookQueries = useCallback4(
|
|
3164
|
-
(marketId, updater) => {
|
|
3165
|
-
var _a;
|
|
3166
|
-
const queries = queryClient.getQueryCache().findAll({
|
|
3167
|
-
queryKey: marketDataKeys.orderbookPrefix(marketId)
|
|
3168
|
-
});
|
|
3169
|
-
for (const query of queries) {
|
|
3170
|
-
const depth = (_a = query.queryKey[4]) != null ? _a : null;
|
|
3171
|
-
queryClient.setQueryData(
|
|
3172
|
-
query.queryKey,
|
|
3173
|
-
(previous) => updater(query.queryKey, depth, previous)
|
|
3174
|
-
);
|
|
3175
|
-
}
|
|
3176
|
-
},
|
|
3177
|
-
[queryClient]
|
|
3178
|
-
);
|
|
3179
|
-
const syncChartQueries = useCallback4(
|
|
3180
|
-
(marketId, updater) => {
|
|
3181
|
-
const queries = queryClient.getQueryCache().findAll({
|
|
3182
|
-
queryKey: marketDataKeys.chartPrefix(marketId)
|
|
3183
|
-
});
|
|
3184
|
-
for (const query of queries) {
|
|
3185
|
-
queryClient.setQueryData(
|
|
3186
|
-
query.queryKey,
|
|
3187
|
-
(previous) => updater(query.queryKey, previous)
|
|
3188
|
-
);
|
|
3189
|
-
}
|
|
3190
|
-
},
|
|
3191
|
-
[queryClient]
|
|
3192
|
-
);
|
|
3193
3313
|
const syncLiveQuery = useCallback4(
|
|
3194
3314
|
(marketId, updater) => {
|
|
3195
|
-
|
|
3196
|
-
return updater(previous);
|
|
3197
|
-
});
|
|
3315
|
+
liveStore.update(marketId, (previous) => updater(previous));
|
|
3198
3316
|
},
|
|
3199
|
-
[
|
|
3317
|
+
[liveStore]
|
|
3200
3318
|
);
|
|
3201
3319
|
const invalidateBalanceCaches = useCallback4(() => {
|
|
3202
3320
|
const now = Date.now();
|
|
@@ -3215,9 +3333,9 @@ function AggWebSocketProvider({ children }) {
|
|
|
3215
3333
|
const { outcomeId } = resolution;
|
|
3216
3334
|
syncLiveQuery(outcomeId, (previous) => {
|
|
3217
3335
|
if (!previous) return previous;
|
|
3218
|
-
if (previous.orderbook == null && previous.orderbookError == null) return previous;
|
|
3219
3336
|
return __spreadProps(__spreadValues({}, previous), {
|
|
3220
3337
|
orderbook: null,
|
|
3338
|
+
orderbookSnapshotVersion: previous.orderbookSnapshotVersion + 1,
|
|
3221
3339
|
orderbookError: null,
|
|
3222
3340
|
integrity: "ok"
|
|
3223
3341
|
});
|
|
@@ -3266,93 +3384,63 @@ function AggWebSocketProvider({ children }) {
|
|
|
3266
3384
|
},
|
|
3267
3385
|
[queryClient, syncLiveQuery]
|
|
3268
3386
|
);
|
|
3269
|
-
const
|
|
3387
|
+
const publishLocalCandles = useCallback4(
|
|
3388
|
+
(id) => {
|
|
3389
|
+
const builder = getOrCreateBuilder(id);
|
|
3390
|
+
const candles = Object.fromEntries(
|
|
3391
|
+
["1m", "5m", "1h", "1d"].map((interval) => [
|
|
3392
|
+
interval,
|
|
3393
|
+
{
|
|
3394
|
+
forming: builder.getForming(interval) ? __spreadValues({}, builder.getForming(interval)) : null,
|
|
3395
|
+
closed: builder.getClosed(interval).slice(-2)
|
|
3396
|
+
}
|
|
3397
|
+
])
|
|
3398
|
+
);
|
|
3399
|
+
liveStore.update(id, (previous) => __spreadProps(__spreadValues({}, previous), { candles }));
|
|
3400
|
+
},
|
|
3401
|
+
[liveStore]
|
|
3402
|
+
);
|
|
3403
|
+
const callbacks = useMemo5(
|
|
3270
3404
|
() => ({
|
|
3405
|
+
onMarketView: (view) => {
|
|
3406
|
+
if (view.book && view.integrity === "ok")
|
|
3407
|
+
resyncDeadlineByMarketRef.current.delete(view.outcomeId);
|
|
3408
|
+
liveStore.update(view.outcomeId, (previous) => __spreadProps(__spreadValues({}, view.book ? withLiveOrderbook(previous, view.book, view.snapshot ? "snapshot" : "delta") : previous), {
|
|
3409
|
+
integrity: view.integrity,
|
|
3410
|
+
candles: mergeCandleTails(previous.candles, view.candles),
|
|
3411
|
+
receivedAtMs: view.receivedAtMs,
|
|
3412
|
+
trades: [...view.trades, ...previous.trades].slice(0, 50)
|
|
3413
|
+
}));
|
|
3414
|
+
getOrCreateBuilder(view.outcomeId).replaceTail(view.candles);
|
|
3415
|
+
},
|
|
3271
3416
|
onSnapshot: (marketId, book) => {
|
|
3272
|
-
|
|
3417
|
+
var _a, _b;
|
|
3418
|
+
if ((_a = wsRef.current) == null ? void 0 : _a.processesCandles) return;
|
|
3273
3419
|
resyncDeadlineByMarketRef.current.delete(marketId);
|
|
3274
|
-
syncOrderbookQueries(marketId, (_queryKey, depth, previous) => {
|
|
3275
|
-
var _a;
|
|
3276
|
-
const previousSnapshotVersion = (_a = previous == null ? void 0 : previous.snapshotVersion) != null ? _a : 0;
|
|
3277
|
-
return applyOrderbookDepth(
|
|
3278
|
-
__spreadProps(__spreadValues({}, orderbook), {
|
|
3279
|
-
snapshotVersion: previousSnapshotVersion + 1
|
|
3280
|
-
}),
|
|
3281
|
-
depth
|
|
3282
|
-
);
|
|
3283
|
-
});
|
|
3284
3420
|
syncLiveQuery(marketId, (previous) => withLiveOrderbook(previous, book, "snapshot"));
|
|
3285
|
-
if (book.midpoint != null) {
|
|
3421
|
+
if (!((_b = wsRef.current) == null ? void 0 : _b.processesCandles) && book.midpoint != null) {
|
|
3286
3422
|
getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
|
|
3287
|
-
|
|
3288
|
-
marketId,
|
|
3289
|
-
(_queryKey, previous) => applyMidpointToMarketChart(previous, {
|
|
3290
|
-
outcomeId: marketId,
|
|
3291
|
-
midpoint: book.midpoint,
|
|
3292
|
-
timestamp: book.timestamp
|
|
3293
|
-
})
|
|
3294
|
-
);
|
|
3423
|
+
publishLocalCandles(marketId);
|
|
3295
3424
|
}
|
|
3296
3425
|
},
|
|
3297
3426
|
onDelta: (marketId, book) => {
|
|
3298
3427
|
var _a, _b;
|
|
3299
|
-
|
|
3300
|
-
debugOrderbook(enableWebsocketsLogs, "delta_received", {
|
|
3301
|
-
outcomeId: marketId,
|
|
3302
|
-
seq: book.seq,
|
|
3303
|
-
checksum: book.checksum,
|
|
3304
|
-
hasTargetOrderbook: Boolean(previousLiveState == null ? void 0 : previousLiveState.orderbook),
|
|
3305
|
-
beforeTop: (previousLiveState == null ? void 0 : previousLiveState.orderbook) ? {
|
|
3306
|
-
bids: summarizeTopLevels(previousLiveState.orderbook.bids),
|
|
3307
|
-
asks: summarizeTopLevels(previousLiveState.orderbook.asks)
|
|
3308
|
-
} : null,
|
|
3309
|
-
afterTop: {
|
|
3310
|
-
bids: summarizeTopLevels(book.bids),
|
|
3311
|
-
asks: summarizeTopLevels(book.asks)
|
|
3312
|
-
}
|
|
3313
|
-
});
|
|
3314
|
-
const orderbook = createMarketOrderbookDataFromState(book);
|
|
3428
|
+
if ((_a = wsRef.current) == null ? void 0 : _a.processesCandles) return;
|
|
3315
3429
|
resyncDeadlineByMarketRef.current.delete(marketId);
|
|
3316
|
-
syncOrderbookQueries(marketId, (_queryKey, depth, previous) => {
|
|
3317
|
-
var _a2;
|
|
3318
|
-
const previousSnapshotVersion = (_a2 = previous == null ? void 0 : previous.snapshotVersion) != null ? _a2 : 0;
|
|
3319
|
-
return applyOrderbookDepth(
|
|
3320
|
-
__spreadProps(__spreadValues({}, orderbook), {
|
|
3321
|
-
snapshotVersion: previousSnapshotVersion
|
|
3322
|
-
}),
|
|
3323
|
-
depth
|
|
3324
|
-
);
|
|
3325
|
-
});
|
|
3326
3430
|
syncLiveQuery(marketId, (previous) => withLiveOrderbook(previous, book, "delta"));
|
|
3327
|
-
|
|
3328
|
-
marketDataKeys.live(marketId)
|
|
3329
|
-
);
|
|
3330
|
-
debugOrderbook(enableWebsocketsLogs, "delta_cached", {
|
|
3331
|
-
outcomeId: marketId,
|
|
3332
|
-
seq: (_b = (_a = nextLiveState == null ? void 0 : nextLiveState.orderbook) == null ? void 0 : _a.seq) != null ? _b : null,
|
|
3333
|
-
selectorTop: (nextLiveState == null ? void 0 : nextLiveState.orderbook) ? {
|
|
3334
|
-
bids: summarizeTopLevels(nextLiveState.orderbook.bids),
|
|
3335
|
-
asks: summarizeTopLevels(nextLiveState.orderbook.asks)
|
|
3336
|
-
} : null
|
|
3337
|
-
});
|
|
3338
|
-
if (book.midpoint != null) {
|
|
3431
|
+
if (!((_b = wsRef.current) == null ? void 0 : _b.processesCandles) && book.midpoint != null) {
|
|
3339
3432
|
getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
|
|
3340
|
-
|
|
3341
|
-
marketId,
|
|
3342
|
-
(_queryKey, previous) => applyMidpointToMarketChart(previous, {
|
|
3343
|
-
outcomeId: marketId,
|
|
3344
|
-
midpoint: book.midpoint,
|
|
3345
|
-
timestamp: book.timestamp
|
|
3346
|
-
})
|
|
3347
|
-
);
|
|
3433
|
+
publishLocalCandles(marketId);
|
|
3348
3434
|
}
|
|
3349
3435
|
},
|
|
3350
3436
|
onTrade: (trade) => {
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
});
|
|
3437
|
+
var _a, _b;
|
|
3438
|
+
if ((_a = wsRef.current) == null ? void 0 : _a.processesCandles) return;
|
|
3354
3439
|
syncLiveQuery(trade.outcomeId, (previous) => withLiveTrade(previous, trade));
|
|
3355
|
-
|
|
3440
|
+
if (!((_b = wsRef.current) == null ? void 0 : _b.processesCandles)) {
|
|
3441
|
+
getOrCreateBuilder(trade.outcomeId).addTrade(trade.price, trade.size, trade.timestamp);
|
|
3442
|
+
publishLocalCandles(trade.outcomeId);
|
|
3443
|
+
}
|
|
3356
3444
|
},
|
|
3357
3445
|
onHeartbeat: () => {
|
|
3358
3446
|
const now = Date.now();
|
|
@@ -3368,10 +3456,6 @@ function AggWebSocketProvider({ children }) {
|
|
|
3368
3456
|
if (event.type !== "seq_gap" && event.type !== "checksum_mismatch") return;
|
|
3369
3457
|
const id = (_a = event.outcomeId) != null ? _a : event.marketId;
|
|
3370
3458
|
resyncDeadlineByMarketRef.current.set(id, Date.now() + 35e3);
|
|
3371
|
-
syncOrderbookQueries(
|
|
3372
|
-
id,
|
|
3373
|
-
(_queryKey, _depth, previous) => withOrderbookIntegrity(previous, "resyncing")
|
|
3374
|
-
);
|
|
3375
3459
|
syncLiveQuery(id, (previous) => withLiveIntegrity(previous, "resyncing"));
|
|
3376
3460
|
},
|
|
3377
3461
|
onOrderSubmitted: (msg) => {
|
|
@@ -3440,38 +3524,34 @@ function AggWebSocketProvider({ children }) {
|
|
|
3440
3524
|
} else {
|
|
3441
3525
|
resetAllBuilders();
|
|
3442
3526
|
}
|
|
3443
|
-
|
|
3444
|
-
queryKey: marketDataKeys.livePrefix()
|
|
3445
|
-
});
|
|
3446
|
-
for (const query of liveQueries) {
|
|
3447
|
-
queryClient.setQueryData(query.queryKey, (previous) => {
|
|
3448
|
-
return withLiveConnectionState(
|
|
3449
|
-
previous,
|
|
3450
|
-
connected
|
|
3451
|
-
);
|
|
3452
|
-
});
|
|
3453
|
-
}
|
|
3527
|
+
liveStore.connected(connected);
|
|
3454
3528
|
}
|
|
3455
3529
|
}),
|
|
3456
3530
|
[
|
|
3457
3531
|
client,
|
|
3458
|
-
enableWebsocketsLogs,
|
|
3459
3532
|
invalidateActivityCaches,
|
|
3460
3533
|
invalidateBalanceCaches,
|
|
3461
3534
|
invalidatePositionCaches,
|
|
3462
3535
|
invalidateResolutionCaches,
|
|
3463
3536
|
isClientAuthenticated,
|
|
3464
3537
|
queryClient,
|
|
3465
|
-
syncChartQueries,
|
|
3466
3538
|
syncLiveQuery,
|
|
3467
|
-
|
|
3539
|
+
liveStore,
|
|
3540
|
+
publishLocalCandles
|
|
3468
3541
|
]
|
|
3469
3542
|
);
|
|
3543
|
+
const callbacksRef = useRef2(callbacks);
|
|
3544
|
+
callbacksRef.current = callbacks;
|
|
3545
|
+
useEffect2(() => {
|
|
3546
|
+
var _a;
|
|
3547
|
+
(_a = wsRef.current) == null ? void 0 : _a.setCallbacks(callbacks);
|
|
3548
|
+
}, [callbacks]);
|
|
3470
3549
|
useEffect2(() => {
|
|
3550
|
+
var _a;
|
|
3471
3551
|
let instance = null;
|
|
3472
3552
|
const resyncDeadlineByMarket = resyncDeadlineByMarketRef.current;
|
|
3473
3553
|
try {
|
|
3474
|
-
instance = client.createWebSocket(
|
|
3554
|
+
instance = client.createWebSocket(callbacksRef.current, { enableLogs: enableWebsocketsLogs });
|
|
3475
3555
|
} catch (e) {
|
|
3476
3556
|
console.warn(
|
|
3477
3557
|
"[AggUI] WebSocket connection could not be established. Ensure wsUrl is configured in createAggClient(). Real-time features (live prices, order updates) are disabled."
|
|
@@ -3481,6 +3561,11 @@ function AggWebSocketProvider({ children }) {
|
|
|
3481
3561
|
setIsConnected(false);
|
|
3482
3562
|
return;
|
|
3483
3563
|
}
|
|
3564
|
+
(_a = instance.setHostDiagnostics) == null ? void 0 : _a.call(instance, () => ({
|
|
3565
|
+
live: liveStore.getDiagnostics(),
|
|
3566
|
+
history: getChartHistoryRetentionStats(queryClient),
|
|
3567
|
+
candles: getCandleStoreDiagnostics()
|
|
3568
|
+
}));
|
|
3484
3569
|
setWs(instance);
|
|
3485
3570
|
wsRef.current = instance;
|
|
3486
3571
|
return () => {
|
|
@@ -3492,12 +3577,12 @@ function AggWebSocketProvider({ children }) {
|
|
|
3492
3577
|
setWs(null);
|
|
3493
3578
|
setIsConnected(false);
|
|
3494
3579
|
};
|
|
3495
|
-
}, [
|
|
3580
|
+
}, [client, enableWebsocketsLogs, isClientAuthenticated, liveStore, queryClient]);
|
|
3496
3581
|
return /* @__PURE__ */ jsx6(AggWebSocketConnectionContext.Provider, { value: isConnected, children: /* @__PURE__ */ jsx6(AggWsUserEventContext.Provider, { value: userEventListeners, children: /* @__PURE__ */ jsx6(AggWebSocketContext.Provider, { value: ws, children }) }) });
|
|
3497
3582
|
}
|
|
3498
3583
|
|
|
3499
3584
|
// src/core/providers/ui-provider.tsx
|
|
3500
|
-
import { useCallback as useCallback6, useEffect as useEffect3, useMemo as
|
|
3585
|
+
import { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo7, useState as useState3 } from "react";
|
|
3501
3586
|
|
|
3502
3587
|
// src/core/ui-config/constants.ts
|
|
3503
3588
|
var DEFAULT_AGG_ROOT_CLASS_NAME = "agg-root";
|
|
@@ -3574,7 +3659,7 @@ var applyThemeToDocument = (theme) => {
|
|
|
3574
3659
|
};
|
|
3575
3660
|
|
|
3576
3661
|
// src/core/providers/event-trading-context.tsx
|
|
3577
|
-
import { createContext as createContext4, useCallback as useCallback5, useContext as useContext6, useMemo as
|
|
3662
|
+
import { createContext as createContext4, useCallback as useCallback5, useContext as useContext6, useMemo as useMemo6, useReducer, useRef as useRef3 } from "react";
|
|
3578
3663
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
3579
3664
|
var OPEN_TRADING_STATE = {
|
|
3580
3665
|
kind: "open",
|
|
@@ -3975,7 +4060,7 @@ var EventTradingProvider = ({
|
|
|
3975
4060
|
(tradeSide) => dispatch({ type: "SET_TRADE_SIDE", tradeSide }),
|
|
3976
4061
|
[dispatch]
|
|
3977
4062
|
);
|
|
3978
|
-
const value =
|
|
4063
|
+
const value = useMemo6(
|
|
3979
4064
|
() => {
|
|
3980
4065
|
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
|
|
3981
4066
|
return {
|
|
@@ -4042,8 +4127,8 @@ var getSearchStateAfterSelect = (selectedEvent) => {
|
|
|
4042
4127
|
};
|
|
4043
4128
|
};
|
|
4044
4129
|
var AggUiProvider = ({ config, children }) => {
|
|
4045
|
-
const persisted =
|
|
4046
|
-
const mergedConfig =
|
|
4130
|
+
const persisted = useMemo7(() => loadPersistedConfig(), []);
|
|
4131
|
+
const mergedConfig = useMemo7(() => mergeAggUiConfig(persisted, config), [persisted, config]);
|
|
4047
4132
|
const [selectedChartTimeRange, setSelectedChartTimeRange] = useState3(
|
|
4048
4133
|
mergedConfig.chart.selectedChartTimeRange
|
|
4049
4134
|
);
|
|
@@ -4095,7 +4180,7 @@ var AggUiProvider = ({ config, children }) => {
|
|
|
4095
4180
|
setIsShowingAllResults(false);
|
|
4096
4181
|
(_b = (_a = mergedConfig.search).closeResults) == null ? void 0 : _b.call(_a);
|
|
4097
4182
|
}, [mergedConfig.search]);
|
|
4098
|
-
const resolvedConfig =
|
|
4183
|
+
const resolvedConfig = useMemo7(() => {
|
|
4099
4184
|
return __spreadProps(__spreadValues({}, mergedConfig), {
|
|
4100
4185
|
chart: __spreadProps(__spreadValues({}, mergedConfig.chart), {
|
|
4101
4186
|
selectedChartTimeRange,
|
|
@@ -4163,7 +4248,7 @@ import { jsx as jsx9 } from "react/jsx-runtime";
|
|
|
4163
4248
|
var hasWarnedMissingQueryClient = false;
|
|
4164
4249
|
function useQueryClientCheck() {
|
|
4165
4250
|
try {
|
|
4166
|
-
|
|
4251
|
+
useQueryClient4();
|
|
4167
4252
|
} catch (e) {
|
|
4168
4253
|
if (!hasWarnedMissingQueryClient) {
|
|
4169
4254
|
hasWarnedMissingQueryClient = true;
|
|
@@ -4202,10 +4287,10 @@ function useResolvedExecutionMode(override) {
|
|
|
4202
4287
|
}
|
|
4203
4288
|
|
|
4204
4289
|
// src/execution/use-execute-managed.ts
|
|
4205
|
-
import { useMutation, useQueryClient as
|
|
4290
|
+
import { useMutation, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
|
|
4206
4291
|
function useExecuteManaged(options) {
|
|
4207
4292
|
const client = useAggClient();
|
|
4208
|
-
const queryClient =
|
|
4293
|
+
const queryClient = useQueryClient5();
|
|
4209
4294
|
return useMutation({
|
|
4210
4295
|
mutationFn: (params) => client.executeManaged(params),
|
|
4211
4296
|
onSuccess: (data) => {
|
|
@@ -4234,10 +4319,10 @@ function useExecuteManaged(options) {
|
|
|
4234
4319
|
}
|
|
4235
4320
|
|
|
4236
4321
|
// src/execution/use-place-limit-order.ts
|
|
4237
|
-
import { useMutation as useMutation2, useQueryClient as
|
|
4322
|
+
import { useMutation as useMutation2, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
|
|
4238
4323
|
function usePlaceLimitOrder(options) {
|
|
4239
4324
|
const client = useAggClient();
|
|
4240
|
-
const queryClient =
|
|
4325
|
+
const queryClient = useQueryClient6();
|
|
4241
4326
|
return useMutation2({
|
|
4242
4327
|
mutationFn: (params) => client.placeLimitOrder(params),
|
|
4243
4328
|
onSuccess: (data) => {
|
|
@@ -4253,10 +4338,10 @@ function usePlaceLimitOrder(options) {
|
|
|
4253
4338
|
}
|
|
4254
4339
|
|
|
4255
4340
|
// src/execution/use-cancel-managed-order.ts
|
|
4256
|
-
import { useMutation as useMutation3, useQueryClient as
|
|
4341
|
+
import { useMutation as useMutation3, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
|
|
4257
4342
|
function useCancelManagedOrder(options) {
|
|
4258
4343
|
const client = useAggClient();
|
|
4259
|
-
const queryClient =
|
|
4344
|
+
const queryClient = useQueryClient7();
|
|
4260
4345
|
return useMutation3({
|
|
4261
4346
|
mutationFn: (orderId) => client.cancelManagedOrder(orderId),
|
|
4262
4347
|
onSuccess: (data, orderId) => {
|
|
@@ -4276,10 +4361,10 @@ function useCancelManagedOrder(options) {
|
|
|
4276
4361
|
}
|
|
4277
4362
|
|
|
4278
4363
|
// src/execution/use-withdraw-managed.ts
|
|
4279
|
-
import { useMutation as useMutation4, useQueryClient as
|
|
4364
|
+
import { useMutation as useMutation4, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
|
|
4280
4365
|
function useWithdrawManaged(options) {
|
|
4281
4366
|
const client = useAggClient();
|
|
4282
|
-
const queryClient =
|
|
4367
|
+
const queryClient = useQueryClient8();
|
|
4283
4368
|
return useMutation4({
|
|
4284
4369
|
mutationFn: (params) => client.withdrawManaged(params),
|
|
4285
4370
|
onSuccess: (data) => {
|
|
@@ -4295,10 +4380,11 @@ function useWithdrawManaged(options) {
|
|
|
4295
4380
|
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
4296
4381
|
function useManagedBalances(options) {
|
|
4297
4382
|
const client = useAggClient();
|
|
4298
|
-
const { enabled = true, mode } = options != null ? options : {};
|
|
4383
|
+
const { enabled = true, mode, custody } = options != null ? options : {};
|
|
4384
|
+
const params = __spreadValues(__spreadValues({}, mode ? { mode } : {}), custody ? { custody } : {});
|
|
4299
4385
|
const query = useQuery3({
|
|
4300
|
-
queryKey: executionKeys.balances(mode),
|
|
4301
|
-
queryFn: () => client.getManagedBalances(
|
|
4386
|
+
queryKey: executionKeys.balances(mode, custody),
|
|
4387
|
+
queryFn: () => client.getManagedBalances(Object.keys(params).length ? params : void 0),
|
|
4302
4388
|
enabled,
|
|
4303
4389
|
staleTime: 1e4,
|
|
4304
4390
|
// A matched fill can precede settlement and the API's next balance snapshot.
|
|
@@ -4335,7 +4421,7 @@ function usePositions(options) {
|
|
|
4335
4421
|
}
|
|
4336
4422
|
|
|
4337
4423
|
// src/execution/use-deposit-addresses.ts
|
|
4338
|
-
import { useEffect as useEffect4, useMemo as
|
|
4424
|
+
import { useEffect as useEffect4, useMemo as useMemo8, useRef as useRef4, useState as useState4 } from "react";
|
|
4339
4425
|
import { useQuery as useQuery5 } from "@tanstack/react-query";
|
|
4340
4426
|
var SVM_CHAIN_IDS = /* @__PURE__ */ new Set([792703809]);
|
|
4341
4427
|
function getDepositAddress(chainId, data) {
|
|
@@ -4376,9 +4462,9 @@ function useDepositAddresses(options) {
|
|
|
4376
4462
|
});
|
|
4377
4463
|
const isReady = ((_a = query.data) == null ? void 0 : _a.ready) === true;
|
|
4378
4464
|
const readyData = isReady ? query.data : void 0;
|
|
4379
|
-
const evmAddress =
|
|
4380
|
-
const svmAddress =
|
|
4381
|
-
const supportedChains =
|
|
4465
|
+
const evmAddress = useMemo8(() => readyData == null ? void 0 : readyData.evmAddress, [readyData]);
|
|
4466
|
+
const svmAddress = useMemo8(() => readyData == null ? void 0 : readyData.svmAddress, [readyData]);
|
|
4467
|
+
const supportedChains = useMemo8(() => readyData == null ? void 0 : readyData.supportedChains, [readyData]);
|
|
4382
4468
|
return __spreadProps(__spreadValues({}, query), {
|
|
4383
4469
|
isReady,
|
|
4384
4470
|
isTimedOut,
|
|
@@ -4392,10 +4478,10 @@ function useDepositAddresses(options) {
|
|
|
4392
4478
|
}
|
|
4393
4479
|
|
|
4394
4480
|
// src/execution/use-sync-balances.ts
|
|
4395
|
-
import { useMutation as useMutation5, useQueryClient as
|
|
4481
|
+
import { useMutation as useMutation5, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
|
|
4396
4482
|
function useSyncBalances(options) {
|
|
4397
4483
|
const client = useAggClient();
|
|
4398
|
-
const queryClient =
|
|
4484
|
+
const queryClient = useQueryClient9();
|
|
4399
4485
|
return useMutation5({
|
|
4400
4486
|
mutationFn: () => client.syncManagedBalances(),
|
|
4401
4487
|
onSuccess: () => {
|
|
@@ -4605,7 +4691,7 @@ function useExecutionProgress({
|
|
|
4605
4691
|
submittedOrderVenueByIdRef.current.set(msg.orderId, trimmedVenue);
|
|
4606
4692
|
}
|
|
4607
4693
|
const { event } = msg;
|
|
4608
|
-
if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed" || event === "expired" || event === "dag_cancelled") {
|
|
4694
|
+
if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed" || event === "expired" || event === "dag_cancelled" || event === "cancelled") {
|
|
4609
4695
|
const mappedEvent = event === "filled" || event === "partial_fill" ? event : "failed";
|
|
4610
4696
|
const resolvedVenue = trimmedVenue || submittedOrderVenueByIdRef.current.get(msg.orderId) || "";
|
|
4611
4697
|
if (resolvedVenue) {
|
|
@@ -5124,11 +5210,11 @@ function useExecutionProgress({
|
|
|
5124
5210
|
}
|
|
5125
5211
|
|
|
5126
5212
|
// src/execution/use-balance-refill-policies.ts
|
|
5127
|
-
import { useMutation as useMutation6, useQuery as useQuery6, useQueryClient as
|
|
5213
|
+
import { useMutation as useMutation6, useQuery as useQuery6, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
|
|
5128
5214
|
function useBalanceRefillPolicies(options) {
|
|
5129
5215
|
var _a, _b;
|
|
5130
5216
|
const client = useAggClient();
|
|
5131
|
-
const queryClient =
|
|
5217
|
+
const queryClient = useQueryClient10();
|
|
5132
5218
|
const queryKey = executionKeys.balanceRefillPolicies();
|
|
5133
5219
|
const query = useQuery6({
|
|
5134
5220
|
queryKey,
|
|
@@ -5209,7 +5295,7 @@ var computeClosedPositionTotals = (group) => {
|
|
|
5209
5295
|
};
|
|
5210
5296
|
|
|
5211
5297
|
// src/execution/use-redeem.ts
|
|
5212
|
-
import { useMutation as useMutation7, useQueryClient as
|
|
5298
|
+
import { useMutation as useMutation7, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
|
|
5213
5299
|
var RedeemRejectedError = class extends Error {
|
|
5214
5300
|
constructor(message, response) {
|
|
5215
5301
|
super(message);
|
|
@@ -5220,7 +5306,7 @@ var RedeemRejectedError = class extends Error {
|
|
|
5220
5306
|
var isLegRejected = (status) => status === "ineligible" || status === "rejected";
|
|
5221
5307
|
var useRedeem = () => {
|
|
5222
5308
|
const client = useAggClient();
|
|
5223
|
-
const queryClient =
|
|
5309
|
+
const queryClient = useQueryClient11();
|
|
5224
5310
|
const { executionMode } = useResolvedExecutionMode();
|
|
5225
5311
|
return useMutation7({
|
|
5226
5312
|
mutationFn: (body) => __async(null, null, function* () {
|
|
@@ -5281,7 +5367,7 @@ var useRedeemEligibleCount = () => {
|
|
|
5281
5367
|
};
|
|
5282
5368
|
|
|
5283
5369
|
// src/execution/use-redeem-lifecycles.ts
|
|
5284
|
-
import { useEffect as useEffect6, useMemo as
|
|
5370
|
+
import { useEffect as useEffect6, useMemo as useMemo9, useState as useState6 } from "react";
|
|
5285
5371
|
var computeDerivedState = (legs, expectedCount) => {
|
|
5286
5372
|
const legCount = Object.keys(legs).length;
|
|
5287
5373
|
let allTerminal = legCount === expectedCount;
|
|
@@ -5332,7 +5418,7 @@ var seedState = (input) => {
|
|
|
5332
5418
|
};
|
|
5333
5419
|
};
|
|
5334
5420
|
function useRedeemLifecycles(inputs) {
|
|
5335
|
-
const inputsByRedeemId =
|
|
5421
|
+
const inputsByRedeemId = useMemo9(() => {
|
|
5336
5422
|
const map = {};
|
|
5337
5423
|
for (const input of inputs) {
|
|
5338
5424
|
map[input.redeemId] = input;
|
|
@@ -5364,7 +5450,7 @@ function useRedeemLifecycles(inputs) {
|
|
|
5364
5450
|
});
|
|
5365
5451
|
}, [inputsByRedeemId]);
|
|
5366
5452
|
useOnRedeemEvent(
|
|
5367
|
-
|
|
5453
|
+
useMemo9(() => {
|
|
5368
5454
|
if (Object.keys(inputsByRedeemId).length === 0) return null;
|
|
5369
5455
|
return (event) => {
|
|
5370
5456
|
const input = inputsByRedeemId[event.redeemId];
|
|
@@ -5399,7 +5485,7 @@ function useRedeemLifecycles(inputs) {
|
|
|
5399
5485
|
}
|
|
5400
5486
|
|
|
5401
5487
|
// src/execution/use-redeem-lifecycle.ts
|
|
5402
|
-
import { useMemo as
|
|
5488
|
+
import { useMemo as useMemo10 } from "react";
|
|
5403
5489
|
var INITIAL_STATE = {
|
|
5404
5490
|
pending: true,
|
|
5405
5491
|
terminal: false,
|
|
@@ -5410,13 +5496,14 @@ var INITIAL_STATE = {
|
|
|
5410
5496
|
};
|
|
5411
5497
|
function useRedeemLifecycle(input) {
|
|
5412
5498
|
var _a;
|
|
5413
|
-
const inputs =
|
|
5499
|
+
const inputs = useMemo10(() => input ? [input] : [], [input]);
|
|
5414
5500
|
const map = useRedeemLifecycles(inputs);
|
|
5415
5501
|
if (!input) return INITIAL_STATE;
|
|
5416
5502
|
return (_a = map[input.redeemId]) != null ? _a : INITIAL_STATE;
|
|
5417
5503
|
}
|
|
5418
5504
|
|
|
5419
5505
|
export {
|
|
5506
|
+
__pow,
|
|
5420
5507
|
__spreadValues,
|
|
5421
5508
|
__spreadProps,
|
|
5422
5509
|
__objRest,
|
|
@@ -5430,6 +5517,7 @@ export {
|
|
|
5430
5517
|
parseEmail,
|
|
5431
5518
|
parseEmailStrict,
|
|
5432
5519
|
optimizedImageUrl,
|
|
5520
|
+
retinaImageUrl,
|
|
5433
5521
|
sortVenues,
|
|
5434
5522
|
getOrCreateBuilder,
|
|
5435
5523
|
getBuilder,
|
|
@@ -5451,15 +5539,10 @@ export {
|
|
|
5451
5539
|
useCachedAppConfig,
|
|
5452
5540
|
EventListStateProvider,
|
|
5453
5541
|
useEventListState,
|
|
5454
|
-
getIntervalSeconds,
|
|
5455
|
-
createMarketChartData,
|
|
5456
|
-
mergeMarketChartData,
|
|
5457
5542
|
createMarketLiveState,
|
|
5458
|
-
createMarketOrderbookDataFromVenueOrderbooks,
|
|
5459
|
-
createMarketOrderbookDataFromState,
|
|
5460
|
-
marketOrderbookDataToResponse,
|
|
5461
|
-
applyOrderbookDepth,
|
|
5462
5543
|
marketDataKeys,
|
|
5544
|
+
getMarketLiveStore,
|
|
5545
|
+
useLiveStates,
|
|
5463
5546
|
useAggClient,
|
|
5464
5547
|
useOptionalAggClient,
|
|
5465
5548
|
useAggUiConfig,
|