@agg-build/ui 4.7.1 → 4.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-EOLR7DHL.mjs → chunk-3UBMK2YH.mjs} +1 -1
- package/dist/{chunk-3RQCBGIK.mjs → chunk-KDBKKJ7W.mjs} +57 -29
- package/dist/index.js +57 -29
- package/dist/index.mjs +2 -2
- package/dist/pages.js +57 -29
- package/dist/pages.mjs +2 -2
- package/dist/trading.js +57 -29
- package/dist/trading.mjs +1 -1
- package/dist/types/trading/place-order/index.place-order.utils.d.mts +26 -0
- package/dist/types/trading/place-order/index.place-order.utils.d.ts +26 -0
- package/package.json +3 -3
|
@@ -993,6 +993,37 @@ var findMatchingVenueOutcome = (market, selectedOutcome) => {
|
|
|
993
993
|
return normalizedLabel !== "" && selectedNames.has(normalizedLabel);
|
|
994
994
|
})) != null ? _b : null;
|
|
995
995
|
};
|
|
996
|
+
var resolveSellableSharesByVenue = ({
|
|
997
|
+
positions,
|
|
998
|
+
market,
|
|
999
|
+
selectedOutcome
|
|
1000
|
+
}) => {
|
|
1001
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1002
|
+
const sharesByVenue = /* @__PURE__ */ new Map();
|
|
1003
|
+
if (!market || !selectedOutcome) return sharesByVenue;
|
|
1004
|
+
const normalizedSelectedOutcomeLabel = normalizeOutcomeName(selectedOutcome.label);
|
|
1005
|
+
const selectedMarketIdSet = new Set(
|
|
1006
|
+
[
|
|
1007
|
+
market.id,
|
|
1008
|
+
(_a = market.marketId) != null ? _a : void 0,
|
|
1009
|
+
(_b = market.externalIdentifier) != null ? _b : void 0,
|
|
1010
|
+
...((_c = market.matchedVenueMarkets) != null ? _c : []).map((matched) => matched.id)
|
|
1011
|
+
].filter((value) => Boolean(value))
|
|
1012
|
+
);
|
|
1013
|
+
for (const group of positions) {
|
|
1014
|
+
for (const outcome of (_e = (_d = group.venueMarket) == null ? void 0 : _d.venueMarketOutcomes) != null ? _e : []) {
|
|
1015
|
+
if (normalizeOutcomeName(outcome.label) !== normalizedSelectedOutcomeLabel) continue;
|
|
1016
|
+
for (const breakdown of (_f = outcome.venueBreakdown) != null ? _f : []) {
|
|
1017
|
+
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
1018
|
+
if (!matchesMarketId) continue;
|
|
1019
|
+
const size = Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
1020
|
+
if (size <= 0) continue;
|
|
1021
|
+
sharesByVenue.set(breakdown.venue, ((_g = sharesByVenue.get(breakdown.venue)) != null ? _g : 0) + size);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
return sharesByVenue;
|
|
1026
|
+
};
|
|
996
1027
|
var buildLimitOrderVenueOptions = ({
|
|
997
1028
|
currentPrices,
|
|
998
1029
|
livePrices,
|
|
@@ -4255,6 +4286,14 @@ var PlaceOrder = ({
|
|
|
4255
4286
|
enabled: Boolean(isAuthenticated && isSell),
|
|
4256
4287
|
mode: isPaperMode ? "paper" : void 0
|
|
4257
4288
|
});
|
|
4289
|
+
const sellableSharesByVenue = useMemo(
|
|
4290
|
+
() => isSell ? resolveSellableSharesByVenue({
|
|
4291
|
+
positions: executionPositions,
|
|
4292
|
+
market: scopedSelectedMarket,
|
|
4293
|
+
selectedOutcome: scopedSelectedOutcome
|
|
4294
|
+
}) : /* @__PURE__ */ new Map(),
|
|
4295
|
+
[executionPositions, isSell, scopedSelectedMarket, scopedSelectedOutcome]
|
|
4296
|
+
);
|
|
4258
4297
|
const isSmartRouteEnabled = !isLimitOrder && isQuotePanelActive && !isEndedWithoutKnownWinner && !submissionProgressState && !isBeforeActionPending && !executeManaged.isPending && debouncedAmount > 0 && orderEligibility.canPlaceOrder && // On the sell tab, hold the quote until the amount has been initialized
|
|
4259
4298
|
// from the user's position for THIS outcome AND the debounced value has
|
|
4260
4299
|
// caught up to it. The amount input is shared with the buy tab, so right
|
|
@@ -4305,13 +4344,26 @@ var PlaceOrder = ({
|
|
|
4305
4344
|
}, [limitVenueQuotes.quotes]);
|
|
4306
4345
|
const availableLimitVenueOptions = useMemo(() => {
|
|
4307
4346
|
return visibleLimitVenueOptions.filter((option) => {
|
|
4308
|
-
|
|
4347
|
+
var _a2;
|
|
4348
|
+
return !geoBlockedLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
|
|
4349
|
+
// venue the user has no position on is a guaranteed 409 from the
|
|
4350
|
+
// server's reservation check — and the automatic pick, which sorts on
|
|
4351
|
+
// price alone, would happily choose one. Only narrow once we know
|
|
4352
|
+
// where the shares are; an empty map means positions haven't resolved.
|
|
4353
|
+
(!isSell || sellableSharesByVenue.size === 0 || ((_a2 = sellableSharesByVenue.get(option.venue)) != null ? _a2 : 0) > 0) && getVenueAvailabilityState({
|
|
4309
4354
|
venueId: option.venue,
|
|
4310
4355
|
disabledVenues,
|
|
4311
4356
|
isConfigLoading: isAppConfigLoading
|
|
4312
4357
|
}) === "available";
|
|
4313
4358
|
});
|
|
4314
|
-
}, [
|
|
4359
|
+
}, [
|
|
4360
|
+
disabledVenues,
|
|
4361
|
+
geoBlockedLimitVenues,
|
|
4362
|
+
isAppConfigLoading,
|
|
4363
|
+
isSell,
|
|
4364
|
+
sellableSharesByVenue,
|
|
4365
|
+
visibleLimitVenueOptions
|
|
4366
|
+
]);
|
|
4315
4367
|
const automaticLimitVenueOption = useMemo(
|
|
4316
4368
|
() => resolveAutomaticLimitOrderVenueOption(availableLimitVenueOptions, internalTab),
|
|
4317
4369
|
[availableLimitVenueOptions, internalTab]
|
|
@@ -4413,39 +4465,15 @@ var PlaceOrder = ({
|
|
|
4413
4465
|
refreshContext: smartRouteRefreshContext
|
|
4414
4466
|
});
|
|
4415
4467
|
const currentSellableShares = useMemo(() => {
|
|
4416
|
-
var _a2, _b2
|
|
4468
|
+
var _a2, _b2;
|
|
4417
4469
|
const sharesFromQuote = (_b2 = (_a2 = smartRoute.data) == null ? void 0 : _a2.positionAvailability) == null ? void 0 : _b2.totalSellableShares;
|
|
4418
4470
|
if (typeof sharesFromQuote === "number" && Number.isFinite(sharesFromQuote)) {
|
|
4419
4471
|
return Math.max(0, sharesFromQuote);
|
|
4420
4472
|
}
|
|
4421
|
-
if (!isSell || !scopedSelectedOutcome || !scopedSelectedMarket) return 0;
|
|
4422
|
-
const normalizedSelectedOutcomeLabel = scopedSelectedOutcome.label.trim().toLowerCase();
|
|
4423
|
-
const selectedMarketIds = [
|
|
4424
|
-
scopedSelectedMarket.id,
|
|
4425
|
-
(_c2 = scopedSelectedMarket.marketId) != null ? _c2 : void 0,
|
|
4426
|
-
(_d2 = scopedSelectedMarket.externalIdentifier) != null ? _d2 : void 0
|
|
4427
|
-
].filter((value) => Boolean(value));
|
|
4428
|
-
const selectedMarketIdSet = new Set(selectedMarketIds);
|
|
4429
4473
|
let resolvedShares = 0;
|
|
4430
|
-
for (const
|
|
4431
|
-
const groupOutcomes = (_f2 = (_e2 = group.venueMarket) == null ? void 0 : _e2.venueMarketOutcomes) != null ? _f2 : [];
|
|
4432
|
-
for (const outcome of groupOutcomes) {
|
|
4433
|
-
if (outcome.label.trim().toLowerCase() !== normalizedSelectedOutcomeLabel) continue;
|
|
4434
|
-
for (const breakdown of (_g2 = outcome.venueBreakdown) != null ? _g2 : []) {
|
|
4435
|
-
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
4436
|
-
if (!matchesMarketId) continue;
|
|
4437
|
-
resolvedShares += Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
4438
|
-
}
|
|
4439
|
-
}
|
|
4440
|
-
}
|
|
4474
|
+
for (const size of sellableSharesByVenue.values()) resolvedShares += size;
|
|
4441
4475
|
return Math.max(0, resolvedShares);
|
|
4442
|
-
}, [
|
|
4443
|
-
executionPositions,
|
|
4444
|
-
isSell,
|
|
4445
|
-
scopedSelectedMarket,
|
|
4446
|
-
scopedSelectedOutcome,
|
|
4447
|
-
(_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares
|
|
4448
|
-
]);
|
|
4476
|
+
}, [sellableSharesByVenue, (_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares]);
|
|
4449
4477
|
const maxSellableShares = useMemo(
|
|
4450
4478
|
() => floorToDecimals(currentSellableShares, SELL_SHARE_INPUT_DECIMALS),
|
|
4451
4479
|
[currentSellableShares]
|
package/dist/index.js
CHANGED
|
@@ -20744,6 +20744,37 @@ var findMatchingVenueOutcome = (market, selectedOutcome) => {
|
|
|
20744
20744
|
return normalizedLabel !== "" && selectedNames.has(normalizedLabel);
|
|
20745
20745
|
})) != null ? _b : null;
|
|
20746
20746
|
};
|
|
20747
|
+
var resolveSellableSharesByVenue = ({
|
|
20748
|
+
positions,
|
|
20749
|
+
market,
|
|
20750
|
+
selectedOutcome
|
|
20751
|
+
}) => {
|
|
20752
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
20753
|
+
const sharesByVenue = /* @__PURE__ */ new Map();
|
|
20754
|
+
if (!market || !selectedOutcome) return sharesByVenue;
|
|
20755
|
+
const normalizedSelectedOutcomeLabel = normalizeOutcomeName(selectedOutcome.label);
|
|
20756
|
+
const selectedMarketIdSet = new Set(
|
|
20757
|
+
[
|
|
20758
|
+
market.id,
|
|
20759
|
+
(_a = market.marketId) != null ? _a : void 0,
|
|
20760
|
+
(_b = market.externalIdentifier) != null ? _b : void 0,
|
|
20761
|
+
...((_c = market.matchedVenueMarkets) != null ? _c : []).map((matched) => matched.id)
|
|
20762
|
+
].filter((value) => Boolean(value))
|
|
20763
|
+
);
|
|
20764
|
+
for (const group of positions) {
|
|
20765
|
+
for (const outcome of (_e = (_d = group.venueMarket) == null ? void 0 : _d.venueMarketOutcomes) != null ? _e : []) {
|
|
20766
|
+
if (normalizeOutcomeName(outcome.label) !== normalizedSelectedOutcomeLabel) continue;
|
|
20767
|
+
for (const breakdown of (_f = outcome.venueBreakdown) != null ? _f : []) {
|
|
20768
|
+
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
20769
|
+
if (!matchesMarketId) continue;
|
|
20770
|
+
const size = Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
20771
|
+
if (size <= 0) continue;
|
|
20772
|
+
sharesByVenue.set(breakdown.venue, ((_g = sharesByVenue.get(breakdown.venue)) != null ? _g : 0) + size);
|
|
20773
|
+
}
|
|
20774
|
+
}
|
|
20775
|
+
}
|
|
20776
|
+
return sharesByVenue;
|
|
20777
|
+
};
|
|
20747
20778
|
var buildLimitOrderVenueOptions = ({
|
|
20748
20779
|
currentPrices,
|
|
20749
20780
|
livePrices,
|
|
@@ -24006,6 +24037,14 @@ var PlaceOrder = ({
|
|
|
24006
24037
|
enabled: Boolean(isAuthenticated && isSell),
|
|
24007
24038
|
mode: isPaperMode ? "paper" : void 0
|
|
24008
24039
|
});
|
|
24040
|
+
const sellableSharesByVenue = (0, import_react38.useMemo)(
|
|
24041
|
+
() => isSell ? resolveSellableSharesByVenue({
|
|
24042
|
+
positions: executionPositions,
|
|
24043
|
+
market: scopedSelectedMarket,
|
|
24044
|
+
selectedOutcome: scopedSelectedOutcome
|
|
24045
|
+
}) : /* @__PURE__ */ new Map(),
|
|
24046
|
+
[executionPositions, isSell, scopedSelectedMarket, scopedSelectedOutcome]
|
|
24047
|
+
);
|
|
24009
24048
|
const isSmartRouteEnabled = !isLimitOrder && isQuotePanelActive && !isEndedWithoutKnownWinner && !submissionProgressState && !isBeforeActionPending && !executeManaged.isPending && debouncedAmount > 0 && orderEligibility.canPlaceOrder && // On the sell tab, hold the quote until the amount has been initialized
|
|
24010
24049
|
// from the user's position for THIS outcome AND the debounced value has
|
|
24011
24050
|
// caught up to it. The amount input is shared with the buy tab, so right
|
|
@@ -24056,13 +24095,26 @@ var PlaceOrder = ({
|
|
|
24056
24095
|
}, [limitVenueQuotes.quotes]);
|
|
24057
24096
|
const availableLimitVenueOptions = (0, import_react38.useMemo)(() => {
|
|
24058
24097
|
return visibleLimitVenueOptions.filter((option) => {
|
|
24059
|
-
|
|
24098
|
+
var _a2;
|
|
24099
|
+
return !geoBlockedLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
|
|
24100
|
+
// venue the user has no position on is a guaranteed 409 from the
|
|
24101
|
+
// server's reservation check — and the automatic pick, which sorts on
|
|
24102
|
+
// price alone, would happily choose one. Only narrow once we know
|
|
24103
|
+
// where the shares are; an empty map means positions haven't resolved.
|
|
24104
|
+
(!isSell || sellableSharesByVenue.size === 0 || ((_a2 = sellableSharesByVenue.get(option.venue)) != null ? _a2 : 0) > 0) && (0, import_hooks66.getVenueAvailabilityState)({
|
|
24060
24105
|
venueId: option.venue,
|
|
24061
24106
|
disabledVenues,
|
|
24062
24107
|
isConfigLoading: isAppConfigLoading
|
|
24063
24108
|
}) === "available";
|
|
24064
24109
|
});
|
|
24065
|
-
}, [
|
|
24110
|
+
}, [
|
|
24111
|
+
disabledVenues,
|
|
24112
|
+
geoBlockedLimitVenues,
|
|
24113
|
+
isAppConfigLoading,
|
|
24114
|
+
isSell,
|
|
24115
|
+
sellableSharesByVenue,
|
|
24116
|
+
visibleLimitVenueOptions
|
|
24117
|
+
]);
|
|
24066
24118
|
const automaticLimitVenueOption = (0, import_react38.useMemo)(
|
|
24067
24119
|
() => resolveAutomaticLimitOrderVenueOption(availableLimitVenueOptions, internalTab),
|
|
24068
24120
|
[availableLimitVenueOptions, internalTab]
|
|
@@ -24164,39 +24216,15 @@ var PlaceOrder = ({
|
|
|
24164
24216
|
refreshContext: smartRouteRefreshContext
|
|
24165
24217
|
});
|
|
24166
24218
|
const currentSellableShares = (0, import_react38.useMemo)(() => {
|
|
24167
|
-
var _a2, _b2
|
|
24219
|
+
var _a2, _b2;
|
|
24168
24220
|
const sharesFromQuote = (_b2 = (_a2 = smartRoute.data) == null ? void 0 : _a2.positionAvailability) == null ? void 0 : _b2.totalSellableShares;
|
|
24169
24221
|
if (typeof sharesFromQuote === "number" && Number.isFinite(sharesFromQuote)) {
|
|
24170
24222
|
return Math.max(0, sharesFromQuote);
|
|
24171
24223
|
}
|
|
24172
|
-
if (!isSell || !scopedSelectedOutcome || !scopedSelectedMarket) return 0;
|
|
24173
|
-
const normalizedSelectedOutcomeLabel = scopedSelectedOutcome.label.trim().toLowerCase();
|
|
24174
|
-
const selectedMarketIds = [
|
|
24175
|
-
scopedSelectedMarket.id,
|
|
24176
|
-
(_c2 = scopedSelectedMarket.marketId) != null ? _c2 : void 0,
|
|
24177
|
-
(_d2 = scopedSelectedMarket.externalIdentifier) != null ? _d2 : void 0
|
|
24178
|
-
].filter((value) => Boolean(value));
|
|
24179
|
-
const selectedMarketIdSet = new Set(selectedMarketIds);
|
|
24180
24224
|
let resolvedShares = 0;
|
|
24181
|
-
for (const
|
|
24182
|
-
const groupOutcomes = (_f2 = (_e2 = group.venueMarket) == null ? void 0 : _e2.venueMarketOutcomes) != null ? _f2 : [];
|
|
24183
|
-
for (const outcome of groupOutcomes) {
|
|
24184
|
-
if (outcome.label.trim().toLowerCase() !== normalizedSelectedOutcomeLabel) continue;
|
|
24185
|
-
for (const breakdown of (_g2 = outcome.venueBreakdown) != null ? _g2 : []) {
|
|
24186
|
-
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
24187
|
-
if (!matchesMarketId) continue;
|
|
24188
|
-
resolvedShares += Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
24189
|
-
}
|
|
24190
|
-
}
|
|
24191
|
-
}
|
|
24225
|
+
for (const size of sellableSharesByVenue.values()) resolvedShares += size;
|
|
24192
24226
|
return Math.max(0, resolvedShares);
|
|
24193
|
-
}, [
|
|
24194
|
-
executionPositions,
|
|
24195
|
-
isSell,
|
|
24196
|
-
scopedSelectedMarket,
|
|
24197
|
-
scopedSelectedOutcome,
|
|
24198
|
-
(_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares
|
|
24199
|
-
]);
|
|
24227
|
+
}, [sellableSharesByVenue, (_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares]);
|
|
24200
24228
|
const maxSellableShares = (0, import_react38.useMemo)(
|
|
24201
24229
|
() => floorToDecimals(currentSellableShares, SELL_SHARE_INPUT_DECIMALS),
|
|
24202
24230
|
[currentSellableShares]
|
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
formatRecurringCountdown,
|
|
15
15
|
formatShareAmount,
|
|
16
16
|
useHomePageModals
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-3UBMK2YH.mjs";
|
|
18
18
|
import {
|
|
19
19
|
EventList,
|
|
20
20
|
EventListItem,
|
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
requestAggWithdrawModalOpen,
|
|
62
62
|
useClaimWinnings,
|
|
63
63
|
useResolvedMarketClaim
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-KDBKKJ7W.mjs";
|
|
65
65
|
import {
|
|
66
66
|
SETTLEMENT_SECTION_ID,
|
|
67
67
|
Settlement,
|
package/dist/pages.js
CHANGED
|
@@ -18519,6 +18519,37 @@ var findMatchingVenueOutcome = (market, selectedOutcome) => {
|
|
|
18519
18519
|
return normalizedLabel !== "" && selectedNames.has(normalizedLabel);
|
|
18520
18520
|
})) != null ? _b : null;
|
|
18521
18521
|
};
|
|
18522
|
+
var resolveSellableSharesByVenue = ({
|
|
18523
|
+
positions,
|
|
18524
|
+
market,
|
|
18525
|
+
selectedOutcome
|
|
18526
|
+
}) => {
|
|
18527
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
18528
|
+
const sharesByVenue = /* @__PURE__ */ new Map();
|
|
18529
|
+
if (!market || !selectedOutcome) return sharesByVenue;
|
|
18530
|
+
const normalizedSelectedOutcomeLabel = normalizeOutcomeName(selectedOutcome.label);
|
|
18531
|
+
const selectedMarketIdSet = new Set(
|
|
18532
|
+
[
|
|
18533
|
+
market.id,
|
|
18534
|
+
(_a = market.marketId) != null ? _a : void 0,
|
|
18535
|
+
(_b = market.externalIdentifier) != null ? _b : void 0,
|
|
18536
|
+
...((_c = market.matchedVenueMarkets) != null ? _c : []).map((matched) => matched.id)
|
|
18537
|
+
].filter((value) => Boolean(value))
|
|
18538
|
+
);
|
|
18539
|
+
for (const group of positions) {
|
|
18540
|
+
for (const outcome of (_e = (_d = group.venueMarket) == null ? void 0 : _d.venueMarketOutcomes) != null ? _e : []) {
|
|
18541
|
+
if (normalizeOutcomeName(outcome.label) !== normalizedSelectedOutcomeLabel) continue;
|
|
18542
|
+
for (const breakdown of (_f = outcome.venueBreakdown) != null ? _f : []) {
|
|
18543
|
+
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
18544
|
+
if (!matchesMarketId) continue;
|
|
18545
|
+
const size = Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
18546
|
+
if (size <= 0) continue;
|
|
18547
|
+
sharesByVenue.set(breakdown.venue, ((_g = sharesByVenue.get(breakdown.venue)) != null ? _g : 0) + size);
|
|
18548
|
+
}
|
|
18549
|
+
}
|
|
18550
|
+
}
|
|
18551
|
+
return sharesByVenue;
|
|
18552
|
+
};
|
|
18522
18553
|
var buildLimitOrderVenueOptions = ({
|
|
18523
18554
|
currentPrices,
|
|
18524
18555
|
livePrices,
|
|
@@ -21781,6 +21812,14 @@ var PlaceOrder = ({
|
|
|
21781
21812
|
enabled: Boolean(isAuthenticated && isSell),
|
|
21782
21813
|
mode: isPaperMode ? "paper" : void 0
|
|
21783
21814
|
});
|
|
21815
|
+
const sellableSharesByVenue = (0, import_react35.useMemo)(
|
|
21816
|
+
() => isSell ? resolveSellableSharesByVenue({
|
|
21817
|
+
positions: executionPositions,
|
|
21818
|
+
market: scopedSelectedMarket,
|
|
21819
|
+
selectedOutcome: scopedSelectedOutcome
|
|
21820
|
+
}) : /* @__PURE__ */ new Map(),
|
|
21821
|
+
[executionPositions, isSell, scopedSelectedMarket, scopedSelectedOutcome]
|
|
21822
|
+
);
|
|
21784
21823
|
const isSmartRouteEnabled = !isLimitOrder && isQuotePanelActive && !isEndedWithoutKnownWinner && !submissionProgressState && !isBeforeActionPending && !executeManaged.isPending && debouncedAmount > 0 && orderEligibility.canPlaceOrder && // On the sell tab, hold the quote until the amount has been initialized
|
|
21785
21824
|
// from the user's position for THIS outcome AND the debounced value has
|
|
21786
21825
|
// caught up to it. The amount input is shared with the buy tab, so right
|
|
@@ -21831,13 +21870,26 @@ var PlaceOrder = ({
|
|
|
21831
21870
|
}, [limitVenueQuotes.quotes]);
|
|
21832
21871
|
const availableLimitVenueOptions = (0, import_react35.useMemo)(() => {
|
|
21833
21872
|
return visibleLimitVenueOptions.filter((option) => {
|
|
21834
|
-
|
|
21873
|
+
var _a2;
|
|
21874
|
+
return !geoBlockedLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
|
|
21875
|
+
// venue the user has no position on is a guaranteed 409 from the
|
|
21876
|
+
// server's reservation check — and the automatic pick, which sorts on
|
|
21877
|
+
// price alone, would happily choose one. Only narrow once we know
|
|
21878
|
+
// where the shares are; an empty map means positions haven't resolved.
|
|
21879
|
+
(!isSell || sellableSharesByVenue.size === 0 || ((_a2 = sellableSharesByVenue.get(option.venue)) != null ? _a2 : 0) > 0) && (0, import_hooks63.getVenueAvailabilityState)({
|
|
21835
21880
|
venueId: option.venue,
|
|
21836
21881
|
disabledVenues,
|
|
21837
21882
|
isConfigLoading: isAppConfigLoading
|
|
21838
21883
|
}) === "available";
|
|
21839
21884
|
});
|
|
21840
|
-
}, [
|
|
21885
|
+
}, [
|
|
21886
|
+
disabledVenues,
|
|
21887
|
+
geoBlockedLimitVenues,
|
|
21888
|
+
isAppConfigLoading,
|
|
21889
|
+
isSell,
|
|
21890
|
+
sellableSharesByVenue,
|
|
21891
|
+
visibleLimitVenueOptions
|
|
21892
|
+
]);
|
|
21841
21893
|
const automaticLimitVenueOption = (0, import_react35.useMemo)(
|
|
21842
21894
|
() => resolveAutomaticLimitOrderVenueOption(availableLimitVenueOptions, internalTab),
|
|
21843
21895
|
[availableLimitVenueOptions, internalTab]
|
|
@@ -21939,39 +21991,15 @@ var PlaceOrder = ({
|
|
|
21939
21991
|
refreshContext: smartRouteRefreshContext
|
|
21940
21992
|
});
|
|
21941
21993
|
const currentSellableShares = (0, import_react35.useMemo)(() => {
|
|
21942
|
-
var _a2, _b2
|
|
21994
|
+
var _a2, _b2;
|
|
21943
21995
|
const sharesFromQuote = (_b2 = (_a2 = smartRoute.data) == null ? void 0 : _a2.positionAvailability) == null ? void 0 : _b2.totalSellableShares;
|
|
21944
21996
|
if (typeof sharesFromQuote === "number" && Number.isFinite(sharesFromQuote)) {
|
|
21945
21997
|
return Math.max(0, sharesFromQuote);
|
|
21946
21998
|
}
|
|
21947
|
-
if (!isSell || !scopedSelectedOutcome || !scopedSelectedMarket) return 0;
|
|
21948
|
-
const normalizedSelectedOutcomeLabel = scopedSelectedOutcome.label.trim().toLowerCase();
|
|
21949
|
-
const selectedMarketIds = [
|
|
21950
|
-
scopedSelectedMarket.id,
|
|
21951
|
-
(_c2 = scopedSelectedMarket.marketId) != null ? _c2 : void 0,
|
|
21952
|
-
(_d2 = scopedSelectedMarket.externalIdentifier) != null ? _d2 : void 0
|
|
21953
|
-
].filter((value) => Boolean(value));
|
|
21954
|
-
const selectedMarketIdSet = new Set(selectedMarketIds);
|
|
21955
21999
|
let resolvedShares = 0;
|
|
21956
|
-
for (const
|
|
21957
|
-
const groupOutcomes = (_f2 = (_e2 = group.venueMarket) == null ? void 0 : _e2.venueMarketOutcomes) != null ? _f2 : [];
|
|
21958
|
-
for (const outcome of groupOutcomes) {
|
|
21959
|
-
if (outcome.label.trim().toLowerCase() !== normalizedSelectedOutcomeLabel) continue;
|
|
21960
|
-
for (const breakdown of (_g2 = outcome.venueBreakdown) != null ? _g2 : []) {
|
|
21961
|
-
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
21962
|
-
if (!matchesMarketId) continue;
|
|
21963
|
-
resolvedShares += Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
21964
|
-
}
|
|
21965
|
-
}
|
|
21966
|
-
}
|
|
22000
|
+
for (const size of sellableSharesByVenue.values()) resolvedShares += size;
|
|
21967
22001
|
return Math.max(0, resolvedShares);
|
|
21968
|
-
}, [
|
|
21969
|
-
executionPositions,
|
|
21970
|
-
isSell,
|
|
21971
|
-
scopedSelectedMarket,
|
|
21972
|
-
scopedSelectedOutcome,
|
|
21973
|
-
(_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares
|
|
21974
|
-
]);
|
|
22002
|
+
}, [sellableSharesByVenue, (_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares]);
|
|
21975
22003
|
const maxSellableShares = (0, import_react35.useMemo)(
|
|
21976
22004
|
() => floorToDecimals(currentSellableShares, SELL_SHARE_INPUT_DECIMALS),
|
|
21977
22005
|
[currentSellableShares]
|
package/dist/pages.mjs
CHANGED
|
@@ -11,14 +11,14 @@ import {
|
|
|
11
11
|
formatRecurringCountdown,
|
|
12
12
|
formatShareAmount,
|
|
13
13
|
useHomePageModals
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-3UBMK2YH.mjs";
|
|
15
15
|
import "./chunk-C4GFVJ62.mjs";
|
|
16
16
|
import {
|
|
17
17
|
DEPOSIT_MODAL_OPEN_EVENT,
|
|
18
18
|
WITHDRAW_MODAL_OPEN_EVENT,
|
|
19
19
|
requestAggDepositModalOpen,
|
|
20
20
|
requestAggWithdrawModalOpen
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-KDBKKJ7W.mjs";
|
|
22
22
|
import "./chunk-WYCSTAN7.mjs";
|
|
23
23
|
import "./chunk-XN2NB2NP.mjs";
|
|
24
24
|
import "./chunk-RDBMHBR2.mjs";
|
package/dist/trading.js
CHANGED
|
@@ -8444,6 +8444,37 @@ var findMatchingVenueOutcome = (market, selectedOutcome) => {
|
|
|
8444
8444
|
return normalizedLabel !== "" && selectedNames.has(normalizedLabel);
|
|
8445
8445
|
})) != null ? _b : null;
|
|
8446
8446
|
};
|
|
8447
|
+
var resolveSellableSharesByVenue = ({
|
|
8448
|
+
positions,
|
|
8449
|
+
market,
|
|
8450
|
+
selectedOutcome
|
|
8451
|
+
}) => {
|
|
8452
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
8453
|
+
const sharesByVenue = /* @__PURE__ */ new Map();
|
|
8454
|
+
if (!market || !selectedOutcome) return sharesByVenue;
|
|
8455
|
+
const normalizedSelectedOutcomeLabel = normalizeOutcomeName(selectedOutcome.label);
|
|
8456
|
+
const selectedMarketIdSet = new Set(
|
|
8457
|
+
[
|
|
8458
|
+
market.id,
|
|
8459
|
+
(_a = market.marketId) != null ? _a : void 0,
|
|
8460
|
+
(_b = market.externalIdentifier) != null ? _b : void 0,
|
|
8461
|
+
...((_c = market.matchedVenueMarkets) != null ? _c : []).map((matched) => matched.id)
|
|
8462
|
+
].filter((value) => Boolean(value))
|
|
8463
|
+
);
|
|
8464
|
+
for (const group of positions) {
|
|
8465
|
+
for (const outcome of (_e = (_d = group.venueMarket) == null ? void 0 : _d.venueMarketOutcomes) != null ? _e : []) {
|
|
8466
|
+
if (normalizeOutcomeName(outcome.label) !== normalizedSelectedOutcomeLabel) continue;
|
|
8467
|
+
for (const breakdown of (_f = outcome.venueBreakdown) != null ? _f : []) {
|
|
8468
|
+
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
8469
|
+
if (!matchesMarketId) continue;
|
|
8470
|
+
const size = Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
8471
|
+
if (size <= 0) continue;
|
|
8472
|
+
sharesByVenue.set(breakdown.venue, ((_g = sharesByVenue.get(breakdown.venue)) != null ? _g : 0) + size);
|
|
8473
|
+
}
|
|
8474
|
+
}
|
|
8475
|
+
}
|
|
8476
|
+
return sharesByVenue;
|
|
8477
|
+
};
|
|
8447
8478
|
var buildLimitOrderVenueOptions = ({
|
|
8448
8479
|
currentPrices,
|
|
8449
8480
|
livePrices,
|
|
@@ -11706,6 +11737,14 @@ var PlaceOrder = ({
|
|
|
11706
11737
|
enabled: Boolean(isAuthenticated && isSell),
|
|
11707
11738
|
mode: isPaperMode ? "paper" : void 0
|
|
11708
11739
|
});
|
|
11740
|
+
const sellableSharesByVenue = (0, import_react15.useMemo)(
|
|
11741
|
+
() => isSell ? resolveSellableSharesByVenue({
|
|
11742
|
+
positions: executionPositions,
|
|
11743
|
+
market: scopedSelectedMarket,
|
|
11744
|
+
selectedOutcome: scopedSelectedOutcome
|
|
11745
|
+
}) : /* @__PURE__ */ new Map(),
|
|
11746
|
+
[executionPositions, isSell, scopedSelectedMarket, scopedSelectedOutcome]
|
|
11747
|
+
);
|
|
11709
11748
|
const isSmartRouteEnabled = !isLimitOrder && isQuotePanelActive && !isEndedWithoutKnownWinner && !submissionProgressState && !isBeforeActionPending && !executeManaged.isPending && debouncedAmount > 0 && orderEligibility.canPlaceOrder && // On the sell tab, hold the quote until the amount has been initialized
|
|
11710
11749
|
// from the user's position for THIS outcome AND the debounced value has
|
|
11711
11750
|
// caught up to it. The amount input is shared with the buy tab, so right
|
|
@@ -11756,13 +11795,26 @@ var PlaceOrder = ({
|
|
|
11756
11795
|
}, [limitVenueQuotes.quotes]);
|
|
11757
11796
|
const availableLimitVenueOptions = (0, import_react15.useMemo)(() => {
|
|
11758
11797
|
return visibleLimitVenueOptions.filter((option) => {
|
|
11759
|
-
|
|
11798
|
+
var _a2;
|
|
11799
|
+
return !geoBlockedLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
|
|
11800
|
+
// venue the user has no position on is a guaranteed 409 from the
|
|
11801
|
+
// server's reservation check — and the automatic pick, which sorts on
|
|
11802
|
+
// price alone, would happily choose one. Only narrow once we know
|
|
11803
|
+
// where the shares are; an empty map means positions haven't resolved.
|
|
11804
|
+
(!isSell || sellableSharesByVenue.size === 0 || ((_a2 = sellableSharesByVenue.get(option.venue)) != null ? _a2 : 0) > 0) && (0, import_hooks38.getVenueAvailabilityState)({
|
|
11760
11805
|
venueId: option.venue,
|
|
11761
11806
|
disabledVenues,
|
|
11762
11807
|
isConfigLoading: isAppConfigLoading
|
|
11763
11808
|
}) === "available";
|
|
11764
11809
|
});
|
|
11765
|
-
}, [
|
|
11810
|
+
}, [
|
|
11811
|
+
disabledVenues,
|
|
11812
|
+
geoBlockedLimitVenues,
|
|
11813
|
+
isAppConfigLoading,
|
|
11814
|
+
isSell,
|
|
11815
|
+
sellableSharesByVenue,
|
|
11816
|
+
visibleLimitVenueOptions
|
|
11817
|
+
]);
|
|
11766
11818
|
const automaticLimitVenueOption = (0, import_react15.useMemo)(
|
|
11767
11819
|
() => resolveAutomaticLimitOrderVenueOption(availableLimitVenueOptions, internalTab),
|
|
11768
11820
|
[availableLimitVenueOptions, internalTab]
|
|
@@ -11864,39 +11916,15 @@ var PlaceOrder = ({
|
|
|
11864
11916
|
refreshContext: smartRouteRefreshContext
|
|
11865
11917
|
});
|
|
11866
11918
|
const currentSellableShares = (0, import_react15.useMemo)(() => {
|
|
11867
|
-
var _a2, _b2
|
|
11919
|
+
var _a2, _b2;
|
|
11868
11920
|
const sharesFromQuote = (_b2 = (_a2 = smartRoute.data) == null ? void 0 : _a2.positionAvailability) == null ? void 0 : _b2.totalSellableShares;
|
|
11869
11921
|
if (typeof sharesFromQuote === "number" && Number.isFinite(sharesFromQuote)) {
|
|
11870
11922
|
return Math.max(0, sharesFromQuote);
|
|
11871
11923
|
}
|
|
11872
|
-
if (!isSell || !scopedSelectedOutcome || !scopedSelectedMarket) return 0;
|
|
11873
|
-
const normalizedSelectedOutcomeLabel = scopedSelectedOutcome.label.trim().toLowerCase();
|
|
11874
|
-
const selectedMarketIds = [
|
|
11875
|
-
scopedSelectedMarket.id,
|
|
11876
|
-
(_c2 = scopedSelectedMarket.marketId) != null ? _c2 : void 0,
|
|
11877
|
-
(_d2 = scopedSelectedMarket.externalIdentifier) != null ? _d2 : void 0
|
|
11878
|
-
].filter((value) => Boolean(value));
|
|
11879
|
-
const selectedMarketIdSet = new Set(selectedMarketIds);
|
|
11880
11924
|
let resolvedShares = 0;
|
|
11881
|
-
for (const
|
|
11882
|
-
const groupOutcomes = (_f2 = (_e2 = group.venueMarket) == null ? void 0 : _e2.venueMarketOutcomes) != null ? _f2 : [];
|
|
11883
|
-
for (const outcome of groupOutcomes) {
|
|
11884
|
-
if (outcome.label.trim().toLowerCase() !== normalizedSelectedOutcomeLabel) continue;
|
|
11885
|
-
for (const breakdown of (_g2 = outcome.venueBreakdown) != null ? _g2 : []) {
|
|
11886
|
-
const matchesMarketId = selectedMarketIdSet.size === 0 || selectedMarketIdSet.has(group.targetMarketId) || selectedMarketIdSet.has(breakdown.venueMarketId);
|
|
11887
|
-
if (!matchesMarketId) continue;
|
|
11888
|
-
resolvedShares += Number.isFinite(breakdown.size) ? breakdown.size : 0;
|
|
11889
|
-
}
|
|
11890
|
-
}
|
|
11891
|
-
}
|
|
11925
|
+
for (const size of sellableSharesByVenue.values()) resolvedShares += size;
|
|
11892
11926
|
return Math.max(0, resolvedShares);
|
|
11893
|
-
}, [
|
|
11894
|
-
executionPositions,
|
|
11895
|
-
isSell,
|
|
11896
|
-
scopedSelectedMarket,
|
|
11897
|
-
scopedSelectedOutcome,
|
|
11898
|
-
(_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares
|
|
11899
|
-
]);
|
|
11927
|
+
}, [sellableSharesByVenue, (_q = (_p = smartRoute.data) == null ? void 0 : _p.positionAvailability) == null ? void 0 : _q.totalSellableShares]);
|
|
11900
11928
|
const maxSellableShares = (0, import_react15.useMemo)(
|
|
11901
11929
|
() => floorToDecimals(currentSellableShares, SELL_SHARE_INPUT_DECIMALS),
|
|
11902
11930
|
[currentSellableShares]
|
package/dist/trading.mjs
CHANGED
|
@@ -10,6 +10,32 @@ export declare const isPlaceOrderAveragePriceWorse: ({ averageExecutionPrice, di
|
|
|
10
10
|
}) => boolean;
|
|
11
11
|
export declare const floorToDecimals: (value: number, decimals: number) => number;
|
|
12
12
|
export declare const formatFlooredShareAmount: (value: number, decimals: number) => string;
|
|
13
|
+
/** Minimal structural view of `useExecutionPositions` rows this module reads. */
|
|
14
|
+
export interface SellablePositionGroup {
|
|
15
|
+
targetMarketId: string;
|
|
16
|
+
venueMarket?: {
|
|
17
|
+
venueMarketOutcomes?: {
|
|
18
|
+
label: string;
|
|
19
|
+
venueBreakdown?: {
|
|
20
|
+
venue: string;
|
|
21
|
+
venueMarketId: string;
|
|
22
|
+
size: number;
|
|
23
|
+
}[];
|
|
24
|
+
}[];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gross held shares for `selectedOutcome`, keyed by the venue holding them.
|
|
29
|
+
*
|
|
30
|
+
* Positions sit on ONE venue market of a matched cluster, so the accepted id
|
|
31
|
+
* set spans `matchedVenueMarkets` as well — scoping it to the selected market
|
|
32
|
+
* alone reads a cluster position held on another venue as zero.
|
|
33
|
+
*/
|
|
34
|
+
export declare const resolveSellableSharesByVenue: ({ positions, market, selectedOutcome, }: {
|
|
35
|
+
positions: readonly SellablePositionGroup[];
|
|
36
|
+
market: VenueMarket | null | undefined;
|
|
37
|
+
selectedOutcome: VenueMarket["venueMarketOutcomes"][number] | null | undefined;
|
|
38
|
+
}) => Map<string, number>;
|
|
13
39
|
export declare const buildLimitOrderVenueOptions: ({ currentPrices, livePrices, market, selectedOutcomeId, }: {
|
|
14
40
|
currentPrices: ReadonlyMap<string, number>;
|
|
15
41
|
livePrices?: ReadonlyMap<string, number>;
|
|
@@ -10,6 +10,32 @@ export declare const isPlaceOrderAveragePriceWorse: ({ averageExecutionPrice, di
|
|
|
10
10
|
}) => boolean;
|
|
11
11
|
export declare const floorToDecimals: (value: number, decimals: number) => number;
|
|
12
12
|
export declare const formatFlooredShareAmount: (value: number, decimals: number) => string;
|
|
13
|
+
/** Minimal structural view of `useExecutionPositions` rows this module reads. */
|
|
14
|
+
export interface SellablePositionGroup {
|
|
15
|
+
targetMarketId: string;
|
|
16
|
+
venueMarket?: {
|
|
17
|
+
venueMarketOutcomes?: {
|
|
18
|
+
label: string;
|
|
19
|
+
venueBreakdown?: {
|
|
20
|
+
venue: string;
|
|
21
|
+
venueMarketId: string;
|
|
22
|
+
size: number;
|
|
23
|
+
}[];
|
|
24
|
+
}[];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gross held shares for `selectedOutcome`, keyed by the venue holding them.
|
|
29
|
+
*
|
|
30
|
+
* Positions sit on ONE venue market of a matched cluster, so the accepted id
|
|
31
|
+
* set spans `matchedVenueMarkets` as well — scoping it to the selected market
|
|
32
|
+
* alone reads a cluster position held on another venue as zero.
|
|
33
|
+
*/
|
|
34
|
+
export declare const resolveSellableSharesByVenue: ({ positions, market, selectedOutcome, }: {
|
|
35
|
+
positions: readonly SellablePositionGroup[];
|
|
36
|
+
market: VenueMarket | null | undefined;
|
|
37
|
+
selectedOutcome: VenueMarket["venueMarketOutcomes"][number] | null | undefined;
|
|
38
|
+
}) => Map<string, number>;
|
|
13
39
|
export declare const buildLimitOrderVenueOptions: ({ currentPrices, livePrices, market, selectedOutcomeId, }: {
|
|
14
40
|
currentPrices: ReadonlyMap<string, number>;
|
|
15
41
|
livePrices?: ReadonlyMap<string, number>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agg-build/ui",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.2",
|
|
4
4
|
"description": "Pre-built React component library for the AGG prediction market aggregator. Tailwind-based, themeable, with primitives, event surfaces, trading flows, full pages, and modals.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"liveline": "^0.0.7",
|
|
101
101
|
"react": "^18.0.0 || ^19.0.0",
|
|
102
102
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
103
|
-
"@agg-build/
|
|
104
|
-
"@agg-build/
|
|
103
|
+
"@agg-build/hooks": "^4.7.0",
|
|
104
|
+
"@agg-build/sdk": "^4.7.0"
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
107
|
"@number-flow/react": "^0.6.0",
|