@agg-build/ui 4.23.0 → 4.26.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/pages.js CHANGED
@@ -19319,7 +19319,8 @@ var init_market_details = __esm({
19319
19319
  var _a, _b, _c;
19320
19320
  const labels = (0, import_hooks63.useLabels)();
19321
19321
  const {
19322
- features: { enableLiveUpdates }
19322
+ features: { enableLiveUpdates },
19323
+ market: { minVolume }
19323
19324
  } = (0, import_hooks63.useSdkUiConfig)();
19324
19325
  const tradingContext = (0, import_hooks63.useEventTradingContext)();
19325
19326
  const selectedMarketId = (_a = tradingContext == null ? void 0 : tradingContext.selectedMarketId) != null ? _a : null;
@@ -19339,7 +19340,9 @@ var init_market_details = __esm({
19339
19340
  // fetchAll drains every page — events can exceed any single-page limit
19340
19341
  // (e.g. 80 open markets on one staging event).
19341
19342
  limit: 100,
19342
- fetchAll: true
19343
+ fetchAll: true,
19344
+ // Same minVolume as useEnrichedVenueEvent's open query (also in the key).
19345
+ minVolume
19343
19346
  // No explicit sortBy: event-scoped /venue-markets sorts by the event's
19344
19347
  // type-aware order (structureOrderBy), matching the home-card top-3 and the
19345
19348
  // markets-under-an-event ordering. Passing sortBy here would override it.
@@ -23437,7 +23440,7 @@ function lookupRevertSelectorMessage(message) {
23437
23440
  if (!selector) return null;
23438
23441
  return (_b = REVERT_SELECTOR_MESSAGES[selector]) != null ? _b : null;
23439
23442
  }
23440
- var import_sdk27, ATOMIC_UNITS, ATOMIC_UNITS_BIGINT, getPlaceOrderBalanceCacheKey, routePriceLabelFormatter, GEO_BLOCK_WARNING_PREFIX, isFiniteNonNegativePrice, getPlaceOrderAverageExecutionPrice, floorToDecimals, formatFlooredShareAmount, normalizeOutcomeName, findMatchingVenueOutcome, resolveSellableSharesByVenue, buildLimitOrderVenueOptions, resolveAutomaticLimitOrderVenueOption, isGeoBlockWarningReason, extractGeoBlockedVenues, getSmartRouteTotalFees, getPlaceOrderContainerClassName, resolveIsPositiveOutcome, getOutcomeButtonClassName, sortOutcomesYesFirst, mapVenueMarketOutcomesToPlaceOrderOutcomes, mapQuoteDataToRoutingRows, deriveAggregateOrderStatus, parseFilledAmountRawDollars, parseDecimalString, getPlaceOrderBuyPayout, getPlaceOrderSellProceeds, getPlaceOrderQuoteValue, resolvePlaceOrderNetResult, resolvePlaceOrderQuoteResult, getTradingRoutePriceLabel, isQuoteBelowVenueMinimum, resolvePlaceOrderQuoteStatus, buildLiveRouteCards, routeCardRequiresKalshi, resolveDefaultRouteCardId, getPlaceOrderRouteCardIdentity, sellSharesToAtomicUnits, atomicUnitsToSellShares, clampSellSharesToAvailability, hasInsufficientVenueInventory, getRemainingVenueSellShares, buildVenueSellQuoteRequests, buildLiveSellRouteCards, resolveExecutionVenueFromQuote, routeCardsHaveSameVenueIdentity, getPlaceOrderPotentialReturn, resolvePrimarySubmittedOrderId, normalizeOrderIdLabelInput, buildPlaceOrderExecutionStepGroups, groupPlaceOrderFailureSteps, buildPlaceOrderExecutionStepGroupsFromFailureSummary, MARKET_RESOLVED_ERROR_PATTERN, VENUE_UNAVAILABLE_ERROR_PATTERN, ALCHEMY_SPONSORSHIP_ERROR_PATTERN, ALCHEMY_PREPARE_CALLS_ERROR_PATTERN, DAG_CHECK_BALANCE_SHORTFALL_PATTERN, VENUE_CONNECTOR_UNREACHABLE_PATTERN, POLYMARKET_DEADLINE_TOO_SOON_PATTERN, SELL_NO_ONCHAIN_POSITION_PATTERN, VENUE_QUOTE_UNFILLABLE_PATTERN, QUOTED_PRICE_UNAVAILABLE_PATTERN, VENUE_MIN_ORDER_SIZE_PATTERN, SOURCE_BALANCE_CHANGED_PATTERN, VENUE_MARKET_RESOLVED_PATTERN, DFLOW_WALLET_UNVERIFIED_PATTERN, VENUE_NO_QUOTE_PATH_PATTERN, SOLANA_BLOCKHASH_EXPIRED_PATTERN, VENUE_RATE_LIMITED_PATTERN, SERVICE_BLOCKED_ORDER_PATTERN, ALCHEMY_BALANCE_REVERT_PATTERN, ALCHEMY_REVERT_DATA_SELECTOR_PATTERN, REVERT_SELECTOR_MESSAGES, ALCHEMY_SPONSORSHIP_POLICY_PATTERN, ALCHEMY_POLICY_MAX_COUNT_PATTERN, ORDER_FAILED_PREFIX_PATTERN, VENUE_TERMINATED_STATUS_PATTERN, friendlyTerminatedStatusMessage, tryParseJsonErrorValue, extractPlaceOrderErrorMessage, normalizePlaceOrderErrorMessage, resolvePlaceOrderFailureKind, resolveFailedVenueStep, resolvePlaceOrderFailureActions, resolveEventExecutionPrice, resolveActualExecutionEconomics, getPlaceOrderUnfilledRemaining, getCanonicalPlaceOrderUnfilledRemaining, buildPlaceOrderFailureSummary, buildPlaceOrderShareText, resolveNextTabFromKey, sanitizePercentageInput, finalizePercentageValue, parsePercentageValue, formatPercentageValue, isPercentageBelowMinimum;
23443
+ var import_sdk27, ATOMIC_UNITS, ATOMIC_UNITS_BIGINT, getPlaceOrderBalanceCacheKey, routePriceLabelFormatter, GEO_BLOCK_WARNING_PREFIX, isFiniteNonNegativePrice, getPlaceOrderAverageExecutionPrice, floorToDecimals, formatFlooredShareAmount, normalizeOutcomeName, findMatchingVenueOutcome, resolveSellableSharesByVenue, buildLimitOrderVenueOptions, resolveAutomaticLimitOrderVenueOption, isGeoBlockWarningReason, extractGeoBlockedVenues, getSmartRouteTotalFees, getPlaceOrderContainerClassName, resolveIsPositiveOutcome, getOutcomeButtonClassName, sortOutcomesYesFirst, mapVenueMarketOutcomesToPlaceOrderOutcomes, mapQuoteDataToRoutingRows, deriveAggregateOrderStatus, parseFilledAmountRawDollars, parseDecimalString, getPlaceOrderBuyPayout, getPlaceOrderSellProceeds, getPlaceOrderQuoteValue, resolvePlaceOrderNetResult, resolvePlaceOrderQuoteResult, getTradingRoutePriceLabel, isQuoteBelowVenueMinimum, resolvePlaceOrderQuoteStatus, buildLiveRouteCards, routeCardRequiresKalshi, resolveDefaultRouteCardId, getPlaceOrderRouteCardIdentity, sellSharesToAtomicUnits, atomicUnitsToSellShares, clampSellSharesToAvailability, hasInsufficientVenueInventory, getRemainingVenueSellShares, buildVenueSellQuoteRequests, buildLiveSellRouteCards, resolveExecutionVenueFromQuote, routeCardsHaveSameVenueIdentity, getPlaceOrderPotentialReturn, resolvePrimarySubmittedOrderId, normalizeOrderIdLabelInput, buildPlaceOrderExecutionStepGroups, groupPlaceOrderFailureSteps, buildPlaceOrderExecutionStepGroupsFromFailureSummary, MARKET_RESOLVED_ERROR_PATTERN, VENUE_UNAVAILABLE_ERROR_PATTERN, ALCHEMY_SPONSORSHIP_ERROR_PATTERN, ALCHEMY_PREPARE_CALLS_ERROR_PATTERN, DAG_CHECK_BALANCE_SHORTFALL_PATTERN, VENUE_CONNECTOR_UNREACHABLE_PATTERN, POLYMARKET_DEADLINE_TOO_SOON_PATTERN, SELL_NO_ONCHAIN_POSITION_PATTERN, VENUE_QUOTE_UNFILLABLE_PATTERN, QUOTED_PRICE_UNAVAILABLE_PATTERN, VENUE_MIN_ORDER_SIZE_PATTERN, SOURCE_BALANCE_CHANGED_PATTERN, VENUE_MARKET_RESOLVED_PATTERN, DFLOW_WALLET_UNVERIFIED_PATTERN, VENUE_NO_QUOTE_PATH_PATTERN, SOLANA_BLOCKHASH_EXPIRED_PATTERN, VENUE_RATE_LIMITED_PATTERN, SERVICE_BLOCKED_ORDER_PATTERN, ALCHEMY_BALANCE_REVERT_PATTERN, ALCHEMY_REVERT_DATA_SELECTOR_PATTERN, REVERT_SELECTOR_MESSAGES, ALCHEMY_SPONSORSHIP_POLICY_PATTERN, ALCHEMY_POLICY_MAX_COUNT_PATTERN, ORDER_FAILED_PREFIX_PATTERN, VENUE_TERMINATED_STATUS_PATTERN, friendlyTerminatedStatusMessage, tryParseJsonErrorValue, extractPlaceOrderErrorMessage, normalizePlaceOrderErrorMessage, resolvePlaceOrderFailureKind, resolveFailedVenueStep, resolvePlaceOrderFailureActions, resolveEventExecutionPrice, resolveActualExecutionEconomics, getPlaceOrderUnfilledRemaining, getCanonicalPlaceOrderUnfilledRemaining, buildPlaceOrderFailureSummary, buildPlaceOrderShareText, resolveNextTabFromKey, sanitizePercentageInput, finalizePercentageValue, parsePercentageValue, formatPercentageValue, isPercentageBelowMinimum, ceilDiv, toRaw6, parseSizeStepRaw, toLimitSizeRaw, isLimitSizeBelowMinimum;
23441
23444
  var init_index_place_order_utils = __esm({
23442
23445
  "src/trading/place-order/index.place-order.utils.ts"() {
23443
23446
  "use strict";
@@ -23764,13 +23767,16 @@ var init_index_place_order_utils = __esm({
23764
23767
  var _a;
23765
23768
  return (_a = quoteData.estimatedPayout) != null ? _a : quoteData.totalFilled;
23766
23769
  };
23767
- getPlaceOrderSellProceeds = (quoteData) => Math.max(
23768
- 0,
23769
- quoteData.rawExecCost - quoteData.fills.reduce((sum, fill) => {
23770
- var _a, _b;
23771
- return sum + ((_a = fill.venueFee) != null ? _a : 0) + ((_b = fill.builderFee) != null ? _b : 0);
23772
- }, 0)
23773
- );
23770
+ getPlaceOrderSellProceeds = (quoteData) => {
23771
+ var _a;
23772
+ return (_a = quoteData.estimatedNetProceeds) != null ? _a : Math.max(
23773
+ 0,
23774
+ quoteData.rawExecCost - quoteData.fills.reduce((sum, fill) => {
23775
+ var _a2, _b;
23776
+ return sum + ((_a2 = fill.venueFee) != null ? _a2 : 0) + ((_b = fill.builderFee) != null ? _b : 0);
23777
+ }, 0)
23778
+ );
23779
+ };
23774
23780
  getPlaceOrderQuoteValue = (quoteData, tradeSide) => tradeSide === "sell" ? getPlaceOrderSellProceeds(quoteData) : getPlaceOrderBuyPayout(quoteData);
23775
23781
  resolvePlaceOrderNetResult = ({
23776
23782
  quoteData,
@@ -25118,6 +25124,38 @@ var init_index_place_order_utils = __esm({
25118
25124
  if (parsedValue === null) return false;
25119
25125
  return parsedValue < minimumValue;
25120
25126
  };
25127
+ ceilDiv = (numerator, denominator) => {
25128
+ return (numerator + denominator - BigInt(1)) / denominator;
25129
+ };
25130
+ toRaw6 = (value) => {
25131
+ const normalizedValue = Number.isFinite(value) ? Math.max(0, value) : 0;
25132
+ return Math.ceil(normalizedValue * Number(import_sdk27.LIMIT_PRICE_RAW_SCALE)).toString();
25133
+ };
25134
+ parseSizeStepRaw = (sizeStepRaw) => {
25135
+ if (!sizeStepRaw || !/^[1-9]\d*$/.test(sizeStepRaw)) return BigInt(1);
25136
+ return BigInt(sizeStepRaw);
25137
+ };
25138
+ toLimitSizeRaw = ({
25139
+ amount: amount2,
25140
+ limitPriceRaw,
25141
+ side,
25142
+ sizeStepRaw
25143
+ }) => {
25144
+ const step = parseSizeStepRaw(sizeStepRaw);
25145
+ if (step <= BigInt(1)) {
25146
+ if (side === "sell") return toRaw6(amount2);
25147
+ const spendRaw = BigInt(toRaw6(amount2));
25148
+ const priceRaw = BigInt(limitPriceRaw);
25149
+ return ceilDiv(spendRaw * import_sdk27.LIMIT_PRICE_RAW_SCALE, priceRaw).toString();
25150
+ }
25151
+ const rawSize = side === "sell" ? BigInt(toRaw6(amount2)) : BigInt(toRaw6(amount2)) * import_sdk27.LIMIT_PRICE_RAW_SCALE / BigInt(limitPriceRaw);
25152
+ return (rawSize / step * step).toString();
25153
+ };
25154
+ isLimitSizeBelowMinimum = (sizeRaw, minSizeRaw) => {
25155
+ const size = BigInt(sizeRaw);
25156
+ if (size <= BigInt(0)) return true;
25157
+ return !!minSizeRaw && /^\d+$/.test(minSizeRaw) && size < BigInt(minSizeRaw);
25158
+ };
25121
25159
  }
25122
25160
  });
25123
25161
 
@@ -26212,7 +26250,7 @@ var init_index_place_order_success = __esm({
26212
26250
  });
26213
26251
 
26214
26252
  // src/trading/place-order/index.tsx
26215
- var import_hooks86, import_sdk28, import_react58, Popover, import_dayjs8, import_timezone2, import_utc2, import_react59, import_jsx_runtime192, SELL_SHARE_INPUT_DECIMALS, SELL_SHARE_DISPLAY_DECIMALS, resolvePlaceOrderPortalContainer, LIMIT_EXPIRATION_OPTION_COUNT, LIMIT_PRICE_STEP, LIMIT_PRICE_MIN, LIMIT_PRICE_MAX, ceilDiv, toRaw6, toLimitPriceRaw, toLimitSizeRaw, formatLimitPriceLabel, formatLimitPriceRawLabel, LIMIT_ORDER_SUBMITTING_PROGRESS, buildLimitOrderExecutionGroup, getLimitOrderToWinValue, normalizeLimitPrice, formatLimitPriceInputValue, parseLimitPriceInputValue, resolveEndOfDayEastern, resolveLimitExpirationDate, serializeLimitOrderExpiration, isFutureLimitExpiration, resolveRefetchedQuoteData, isFillRejection400, PlaceOrderSlippageControl, renderCardHeader, PlaceOrderResolvedView, renderRouteBreakdownRow, SIDE_NAMED_MONEYLINE_QUESTION_RE, shouldUseRawResolvedPlaceOrderOutcomeLabel, renderRouteCard, PlaceOrder;
26253
+ var import_hooks86, import_sdk28, import_react58, Popover, import_dayjs8, import_timezone2, import_utc2, import_react59, import_jsx_runtime192, SELL_SHARE_INPUT_DECIMALS, SELL_SHARE_DISPLAY_DECIMALS, resolvePlaceOrderPortalContainer, LIMIT_EXPIRATION_OPTION_COUNT, LIMIT_SIZE_STEP_VENUES, LIMIT_PRICE_STEP, LIMIT_PRICE_MIN, LIMIT_PRICE_MAX, toLimitPriceRaw, formatLimitPriceLabel, formatLimitPriceRawLabel, LIMIT_ORDER_SUBMITTING_PROGRESS, buildLimitOrderExecutionGroup, getLimitOrderToWinValue, normalizeLimitPrice, formatLimitPriceInputValue, parseLimitPriceInputValue, resolveEndOfDayEastern, resolveLimitExpirationDate, serializeLimitOrderExpiration, isFutureLimitExpiration, resolveRefetchedQuoteData, isFillRejection400, PlaceOrderSlippageControl, renderCardHeader, PlaceOrderResolvedView, renderRouteBreakdownRow, SIDE_NAMED_MONEYLINE_QUESTION_RE, shouldUseRawResolvedPlaceOrderOutcomeLabel, renderRouteCard, PlaceOrder;
26216
26254
  var init_place_order = __esm({
26217
26255
  "src/trading/place-order/index.tsx"() {
26218
26256
  "use strict";
@@ -26267,32 +26305,21 @@ var init_place_order = __esm({
26267
26305
  return (_a = triggerElement == null ? void 0 : triggerElement.closest(".agg-modal-center")) != null ? _a : void 0;
26268
26306
  };
26269
26307
  LIMIT_EXPIRATION_OPTION_COUNT = 5;
26308
+ LIMIT_SIZE_STEP_VENUES = /* @__PURE__ */ new Set([
26309
+ import_sdk28.Venue.tiprun,
26310
+ import_sdk28.Venue.hyperliquid,
26311
+ import_sdk28.Venue.pred,
26312
+ import_sdk28.Venue.polymarket
26313
+ ]);
26270
26314
  import_dayjs8.default.extend(import_utc2.default);
26271
26315
  import_dayjs8.default.extend(import_timezone2.default);
26272
26316
  LIMIT_PRICE_STEP = 1e-3;
26273
26317
  LIMIT_PRICE_MIN = 1e-3;
26274
26318
  LIMIT_PRICE_MAX = 0.999;
26275
- ceilDiv = (numerator, denominator) => {
26276
- return (numerator + denominator - BigInt(1)) / denominator;
26277
- };
26278
- toRaw6 = (value) => {
26279
- const normalizedValue = Number.isFinite(value) ? Math.max(0, value) : 0;
26280
- return Math.ceil(normalizedValue * Number(import_sdk28.LIMIT_PRICE_RAW_SCALE)).toString();
26281
- };
26282
26319
  toLimitPriceRaw = (value) => {
26283
26320
  const clampedValue = Math.min(LIMIT_PRICE_MAX, Math.max(LIMIT_PRICE_MIN, value));
26284
26321
  return Math.round(clampedValue * Number(import_sdk28.LIMIT_PRICE_RAW_SCALE)).toString();
26285
26322
  };
26286
- toLimitSizeRaw = ({
26287
- amount: amount2,
26288
- limitPriceRaw,
26289
- side
26290
- }) => {
26291
- if (side === "sell") return toRaw6(amount2);
26292
- const spendRaw = BigInt(toRaw6(amount2));
26293
- const priceRaw = BigInt(limitPriceRaw);
26294
- return ceilDiv(spendRaw * import_sdk28.LIMIT_PRICE_RAW_SCALE, priceRaw).toString();
26295
- };
26296
26323
  formatLimitPriceLabel = (value) => {
26297
26324
  return `${(value * 100).toLocaleString("en-US", {
26298
26325
  minimumFractionDigits: 0,
@@ -26332,11 +26359,12 @@ var init_place_order = __esm({
26332
26359
  getLimitOrderToWinValue = ({
26333
26360
  amount: amount2,
26334
26361
  limitPriceRaw,
26335
- side
26362
+ side,
26363
+ sizeStepRaw
26336
26364
  }) => {
26337
26365
  const priceRaw = BigInt(limitPriceRaw);
26338
26366
  if (priceRaw <= BigInt(0) || priceRaw >= import_sdk28.LIMIT_PRICE_RAW_SCALE) return 0;
26339
- const sizeRaw = BigInt(toLimitSizeRaw({ amount: amount2, limitPriceRaw, side }));
26367
+ const sizeRaw = BigInt(toLimitSizeRaw({ amount: amount2, limitPriceRaw, side, sizeStepRaw }));
26340
26368
  if (side === "buy") return Number(sizeRaw) / Number(import_sdk28.LIMIT_PRICE_RAW_SCALE);
26341
26369
  return Number(ceilDiv(priceRaw * sizeRaw, import_sdk28.LIMIT_PRICE_RAW_SCALE)) / Number(import_sdk28.LIMIT_PRICE_RAW_SCALE);
26342
26370
  };
@@ -27288,7 +27316,8 @@ var init_place_order = __esm({
27288
27316
  const limitVenueQuoteRequests = (0, import_react59.useMemo)(
27289
27317
  () => visibleLimitVenueOptions.map((option) => ({
27290
27318
  venue: option.venue,
27291
- venueMarketOutcomeId: option.venueMarketOutcomeId
27319
+ venueMarketOutcomeId: option.venueMarketOutcomeId,
27320
+ venueMarketId: option.venueMarketId
27292
27321
  })),
27293
27322
  [visibleLimitVenueOptions]
27294
27323
  );
@@ -27320,10 +27349,83 @@ var init_place_order = __esm({
27320
27349
  }
27321
27350
  return venues;
27322
27351
  }, [limitVenueQuotes.quotes]);
27352
+ const originalLimitPriceRaw = (0, import_react59.useMemo)(() => toLimitPriceRaw(limitPrice), [limitPrice]);
27353
+ const limitPriceAdjustmentByVenue = (0, import_react59.useMemo)(() => {
27354
+ var _a2;
27355
+ const adjustments = /* @__PURE__ */ new Map();
27356
+ for (const option of visibleLimitVenueOptions) {
27357
+ try {
27358
+ adjustments.set(
27359
+ option.venue,
27360
+ (0, import_sdk28.adjustLimitPriceRawToTick)({
27361
+ limitPriceRaw: originalLimitPriceRaw,
27362
+ side: internalTab,
27363
+ tickSize: (_a2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _a2.tickSize
27364
+ })
27365
+ );
27366
+ } catch (e) {
27367
+ adjustments.set(
27368
+ option.venue,
27369
+ (0, import_sdk28.adjustLimitPriceRawToTick)({
27370
+ limitPriceRaw: originalLimitPriceRaw,
27371
+ side: internalTab,
27372
+ tickSize: null
27373
+ })
27374
+ );
27375
+ }
27376
+ }
27377
+ return adjustments;
27378
+ }, [internalTab, limitVenueQuoteByVenue, originalLimitPriceRaw, visibleLimitVenueOptions]);
27379
+ const limitSizeRulesByVenue = (0, import_react59.useMemo)(() => {
27380
+ var _a2, _b2;
27381
+ const rulesByVenue = /* @__PURE__ */ new Map();
27382
+ for (const quote of limitVenueQuotes.quotes) {
27383
+ if (!quote.sizeStepRaw && !quote.minSizeRaw) continue;
27384
+ rulesByVenue.set(quote.request.venue, {
27385
+ sizeStepRaw: (_a2 = quote.sizeStepRaw) != null ? _a2 : void 0,
27386
+ minSizeRaw: (_b2 = quote.minSizeRaw) != null ? _b2 : void 0
27387
+ });
27388
+ }
27389
+ return rulesByVenue;
27390
+ }, [limitVenueQuotes.quotes]);
27391
+ const belowMinimumLimitVenues = (0, import_react59.useMemo)(() => {
27392
+ var _a2, _b2;
27393
+ const venues = /* @__PURE__ */ new Set();
27394
+ if (!isLimitOrder || internalAmount <= 0) return venues;
27395
+ for (const option of visibleLimitVenueOptions) {
27396
+ if (geoBlockedLimitVenues.has(option.venue) || (0, import_hooks86.getVenueAvailabilityState)({
27397
+ venueId: option.venue,
27398
+ disabledVenues,
27399
+ isConfigLoading: isAppConfigLoading
27400
+ }) !== "available")
27401
+ continue;
27402
+ const rules = limitSizeRulesByVenue.get(option.venue);
27403
+ if (!(rules == null ? void 0 : rules.sizeStepRaw) && !(rules == null ? void 0 : rules.minSizeRaw)) continue;
27404
+ const sizeRaw = toLimitSizeRaw({
27405
+ amount: internalAmount,
27406
+ limitPriceRaw: (_b2 = (_a2 = limitPriceAdjustmentByVenue.get(option.venue)) == null ? void 0 : _a2.adjustedPriceRaw) != null ? _b2 : originalLimitPriceRaw,
27407
+ side: internalTab,
27408
+ sizeStepRaw: rules.sizeStepRaw
27409
+ });
27410
+ if (isLimitSizeBelowMinimum(sizeRaw, rules.minSizeRaw)) venues.add(option.venue);
27411
+ }
27412
+ return venues;
27413
+ }, [
27414
+ disabledVenues,
27415
+ geoBlockedLimitVenues,
27416
+ internalAmount,
27417
+ internalTab,
27418
+ isAppConfigLoading,
27419
+ isLimitOrder,
27420
+ limitPriceAdjustmentByVenue,
27421
+ limitSizeRulesByVenue,
27422
+ originalLimitPriceRaw,
27423
+ visibleLimitVenueOptions
27424
+ ]);
27323
27425
  const availableLimitVenueOptions = (0, import_react59.useMemo)(() => {
27324
27426
  return visibleLimitVenueOptions.filter((option) => {
27325
27427
  var _a2;
27326
- return !geoBlockedLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
27428
+ return !geoBlockedLimitVenues.has(option.venue) && !belowMinimumLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
27327
27429
  // venue the user has no position on is a guaranteed 409 from the
27328
27430
  // server's reservation check — and the automatic pick, which sorts on
27329
27431
  // price alone, would happily choose one. Only narrow once we know
@@ -27335,6 +27437,7 @@ var init_place_order = __esm({
27335
27437
  }) === "available";
27336
27438
  });
27337
27439
  }, [
27440
+ belowMinimumLimitVenues,
27338
27441
  disabledVenues,
27339
27442
  geoBlockedLimitVenues,
27340
27443
  isAppConfigLoading,
@@ -28192,8 +28295,6 @@ var init_place_order = __esm({
28192
28295
  const isSelectedVenueInventoryInsufficient = isSell && (selectedRouteCard == null ? void 0 : selectedRouteCard.kind) === "venue" && selectedRouteCard.insufficientInventory === true;
28193
28296
  const isBelowClientMinimum = !isSell && hasEnteredAmount && internalAmount < MIN_BUY_ORDER_AMOUNT;
28194
28297
  const isBelowVenueMinimumFromQuote = isQuoteBelowVenueMinimum(activeQuoteData);
28195
- const isBelowMinimum = isBelowClientMinimum || isBelowVenueMinimumFromQuote;
28196
- const belowMinimumMessage = isBelowClientMinimum ? tradingLabels.minimumOrderAmount(MIN_BUY_ORDER_AMOUNT) : tradingLabels.minOrderSizeViolated;
28197
28298
  const quoteStatus = (0, import_react59.useMemo)(() => {
28198
28299
  if (!orderEligibility.canPlaceOrder) return void 0;
28199
28300
  return resolvePlaceOrderQuoteStatus({
@@ -28320,33 +28421,6 @@ var init_place_order = __esm({
28320
28421
  return averagePrice == null ? "" : tradingLabels.averagePrice(averagePrice);
28321
28422
  }, [selectedRouteCard, tradingLabels]);
28322
28423
  const displayedToWinValue = (_ea = selectedRouteCard == null ? void 0 : selectedRouteCard.numericValue) != null ? _ea : 0;
28323
- const originalLimitPriceRaw = (0, import_react59.useMemo)(() => toLimitPriceRaw(limitPrice), [limitPrice]);
28324
- const limitPriceAdjustmentByVenue = (0, import_react59.useMemo)(() => {
28325
- var _a2;
28326
- const adjustments = /* @__PURE__ */ new Map();
28327
- for (const option of visibleLimitVenueOptions) {
28328
- try {
28329
- adjustments.set(
28330
- option.venue,
28331
- (0, import_sdk28.adjustLimitPriceRawToTick)({
28332
- limitPriceRaw: originalLimitPriceRaw,
28333
- side: internalTab,
28334
- tickSize: (_a2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _a2.tickSize
28335
- })
28336
- );
28337
- } catch (e) {
28338
- adjustments.set(
28339
- option.venue,
28340
- (0, import_sdk28.adjustLimitPriceRawToTick)({
28341
- limitPriceRaw: originalLimitPriceRaw,
28342
- side: internalTab,
28343
- tickSize: null
28344
- })
28345
- );
28346
- }
28347
- }
28348
- return adjustments;
28349
- }, [internalTab, limitVenueQuoteByVenue, originalLimitPriceRaw, visibleLimitVenueOptions]);
28350
28424
  const selectedLimitPriceAdjustment = selectedLimitVenueOption ? limitPriceAdjustmentByVenue.get(selectedLimitVenueOption.venue) : void 0;
28351
28425
  const selectedLimitPriceRaw = (_fa = selectedLimitPriceAdjustment == null ? void 0 : selectedLimitPriceAdjustment.adjustedPriceRaw) != null ? _fa : originalLimitPriceRaw;
28352
28426
  const limitPriceAdjustmentMessage = (0, import_react59.useMemo)(() => {
@@ -28367,6 +28441,8 @@ var init_place_order = __esm({
28367
28441
  selectedLimitVenueOption,
28368
28442
  tradingLabels
28369
28443
  ]);
28444
+ const selectedLimitSizeRules = selectedLimitVenueOption ? limitSizeRulesByVenue.get(selectedLimitVenueOption.venue) : void 0;
28445
+ const isLimitSizeRulesPending = isLimitOrder && selectedLimitVenueOption != null && LIMIT_SIZE_STEP_VENUES.has(selectedLimitVenueOption.venue) && limitVenueQuotes.isMetadataPending;
28370
28446
  const limitOrderPayload = (0, import_react59.useMemo)(() => {
28371
28447
  if (!selectedLimitVenueOption || internalAmount <= 0) return null;
28372
28448
  if (limitPriceInputError) return null;
@@ -28382,7 +28458,8 @@ var init_place_order = __esm({
28382
28458
  const sizeRaw = toLimitSizeRaw({
28383
28459
  amount: internalAmount,
28384
28460
  limitPriceRaw,
28385
- side: internalTab
28461
+ side: internalTab,
28462
+ sizeStepRaw: selectedLimitSizeRules == null ? void 0 : selectedLimitSizeRules.sizeStepRaw
28386
28463
  });
28387
28464
  const expiresAt = expirationDate ? serializeLimitOrderExpiration(expirationDate) : void 0;
28388
28465
  return __spreadValues({
@@ -28401,8 +28478,12 @@ var init_place_order = __esm({
28401
28478
  limitExpirationType,
28402
28479
  limitPriceInputError,
28403
28480
  selectedLimitVenueOption,
28404
- selectedLimitPriceRaw
28481
+ selectedLimitPriceRaw,
28482
+ selectedLimitSizeRules == null ? void 0 : selectedLimitSizeRules.sizeStepRaw
28405
28483
  ]);
28484
+ const isLimitSizeBelowVenueMinimum = isLimitOrder && (limitOrderPayload != null && isLimitSizeBelowMinimum(limitOrderPayload.sizeRaw, selectedLimitSizeRules == null ? void 0 : selectedLimitSizeRules.minSizeRaw) || selectedLimitVenueOption == null && belowMinimumLimitVenues.size > 0);
28485
+ const isBelowMinimum = isBelowClientMinimum || isBelowVenueMinimumFromQuote || isLimitSizeBelowVenueMinimum;
28486
+ const belowMinimumMessage = isBelowClientMinimum ? tradingLabels.minimumOrderAmount(MIN_BUY_ORDER_AMOUNT) : isSell ? tradingLabels.venueMinOrderSize : tradingLabels.minOrderSizeViolated;
28406
28487
  const resolvedLimitExpirationDraftDate = (0, import_react59.useMemo)(() => {
28407
28488
  return resolveLimitExpirationDate({
28408
28489
  expirationType: "CUSTOM",
@@ -28446,12 +28527,13 @@ var init_place_order = __esm({
28446
28527
  }, [internalTab, limitOrderPayload]);
28447
28528
  const limitRouteCards = (0, import_react59.useMemo)(() => {
28448
28529
  return visibleLimitVenueOptions.map((option) => {
28449
- var _a2, _b2, _c2, _d2;
28530
+ var _a2, _b2, _c2, _d2, _e2;
28450
28531
  const effectiveLimitPriceRaw = (_b2 = (_a2 = limitPriceAdjustmentByVenue.get(option.venue)) == null ? void 0 : _a2.adjustedPriceRaw) != null ? _b2 : originalLimitPriceRaw;
28451
28532
  const venueToWinValue = getLimitOrderToWinValue({
28452
28533
  amount: internalAmount,
28453
28534
  limitPriceRaw: effectiveLimitPriceRaw,
28454
- side: internalTab
28535
+ side: internalTab,
28536
+ sizeStepRaw: (_c2 = limitSizeRulesByVenue.get(option.venue)) == null ? void 0 : _c2.sizeStepRaw
28455
28537
  });
28456
28538
  const availabilityState = (0, import_hooks86.getVenueAvailabilityState)({
28457
28539
  venueId: option.venue,
@@ -28459,10 +28541,10 @@ var init_place_order = __esm({
28459
28541
  isConfigLoading: isAppConfigLoading
28460
28542
  });
28461
28543
  const isGeoBlocked = geoBlockedLimitVenues.has(option.venue);
28462
- const isUnavailable = isTradingBlocked || isGeoBlocked || availabilityState !== "available";
28544
+ const isUnavailable = isTradingBlocked || isGeoBlocked || belowMinimumLimitVenues.has(option.venue) || availabilityState !== "available";
28463
28545
  const currentPriceLabel = option.currentPrice == null ? "\u2014" : formatProbabilityCents(option.currentPrice, formatPrice);
28464
28546
  const totalFees = getSmartRouteTotalFees(
28465
- (_d2 = (_c2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _c2.data) == null ? void 0 : _d2.feeBreakdown
28547
+ (_e2 = (_d2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _d2.data) == null ? void 0 : _e2.feeBreakdown
28466
28548
  );
28467
28549
  const feeLabel = totalFees == null ? void 0 : formatUsd(totalFees, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
28468
28550
  return {
@@ -28481,6 +28563,7 @@ var init_place_order = __esm({
28481
28563
  };
28482
28564
  });
28483
28565
  }, [
28566
+ belowMinimumLimitVenues,
28484
28567
  disabledVenues,
28485
28568
  formatPrice,
28486
28569
  geoBlockedLimitVenues,
@@ -28489,6 +28572,7 @@ var init_place_order = __esm({
28489
28572
  isAppConfigLoading,
28490
28573
  isTradingBlocked,
28491
28574
  limitPriceAdjustmentByVenue,
28575
+ limitSizeRulesByVenue,
28492
28576
  limitVenueQuoteByVenue,
28493
28577
  originalLimitPriceRaw,
28494
28578
  tradingLabels,
@@ -28587,10 +28671,10 @@ var init_place_order = __esm({
28587
28671
  const fills = (_b2 = (_a2 = selectedRouteCard.quoteData) == null ? void 0 : _a2.fills) != null ? _b2 : [];
28588
28672
  return fills.length > 0 && fills.every((f) => geoBlockedVenuesFromWarnings.has(f.venue));
28589
28673
  }, [selectedRouteCard, geoBlockedVenuesFromWarnings]);
28590
- const shouldShowGeoBlockBanner = isTradingBlocked || selectedRouteGeoBlocked || isPrimaryVenueGeoBlocked || isLimitOrder && limitRouteCards.length > 0 && limitRouteCards.every((card) => card.isUnavailable);
28674
+ const shouldShowGeoBlockBanner = isTradingBlocked || selectedRouteGeoBlocked || isPrimaryVenueGeoBlocked || isLimitOrder && limitRouteCards.length > 0 && limitRouteCards.every((card) => card.isUnavailable) && limitRouteCards.some((card) => !card.venue || !belowMinimumLimitVenues.has(card.venue));
28591
28675
  const actionLabel = `${internalTab === "buy" ? tradingLabels.buy : tradingLabels.sell} ${selectedOutcomeLabel}`.trim();
28592
- const isActionDisabled = isPrimaryActionDisabled || !orderEligibility.canPlaceOrder || isActionLoading || !hasEnteredAmount || !scopedSelectedMarket || isInsufficientBalance || isBetdexBalanceUnavailable && !canExecuteBetdexQuote || isQuoteInsufficientBalance && !canExecuteBetdexQuote || isSell && isQuoteInputEditing || isSellAmountAboveAvailability || isBelowMinimum || !isLimitOrder && isQuoteLoading || isSelectedVenueInventoryInsufficient || (isLimitOrder ? !limitOrderPayload : !selectedRouteCard || !selectedRouteCard.quoteData.quoteId && !canExecuteBetdexQuote) || selectedRouteGeoBlocked || !isAuthenticated || !isLimitOrder && quoteStatus !== void 0 && !canExecuteBetdexQuote;
28593
- const shouldShowSmartRouting = orderEligibility.canPlaceOrder && hasEnteredAmount && !isBelowMinimum && (isLimitOrder ? limitRouteCards.length > 0 : displayedRouteCards.length > 0 || smartRoute.isFetching || smartRoute.isLoading || isSell && (venueSellQuotes.isFetching || venueSellQuotes.isLoading));
28676
+ const isActionDisabled = isPrimaryActionDisabled || !orderEligibility.canPlaceOrder || isActionLoading || !hasEnteredAmount || !scopedSelectedMarket || isInsufficientBalance || isBetdexBalanceUnavailable && !canExecuteBetdexQuote || isQuoteInsufficientBalance && !canExecuteBetdexQuote || isSell && isQuoteInputEditing || isSellAmountAboveAvailability || isBelowMinimum || isLimitSizeRulesPending || !isLimitOrder && isQuoteLoading || isSelectedVenueInventoryInsufficient || (isLimitOrder ? !limitOrderPayload : !selectedRouteCard || !selectedRouteCard.quoteData.quoteId && !canExecuteBetdexQuote) || selectedRouteGeoBlocked || !isAuthenticated || !isLimitOrder && quoteStatus !== void 0 && !canExecuteBetdexQuote;
28677
+ const shouldShowSmartRouting = orderEligibility.canPlaceOrder && hasEnteredAmount && !isBelowClientMinimum && !isBelowVenueMinimumFromQuote && (isLimitOrder ? limitRouteCards.length > 0 : displayedRouteCards.length > 0 || smartRoute.isFetching || smartRoute.isLoading || isSell && (venueSellQuotes.isFetching || venueSellQuotes.isLoading));
28594
28678
  const shouldShowRouteToggle = !isLimitOrder && !isQuoteLoading && displayedRouteCards.length > PLACE_ORDER_ROUTE_COLLAPSED_CARD_COUNT;
28595
28679
  const handleReturnToOrderForm = (0, import_react59.useCallback)(() => {
28596
28680
  const submittedSelection = submittedSelectionRef.current;
@@ -33268,7 +33352,8 @@ var init_sports_markets = __esm({
33268
33352
  onSectionMarketsChange,
33269
33353
  onOutcomeSelect,
33270
33354
  live,
33271
- midpointsResult
33355
+ midpointsResult,
33356
+ minVolume
33272
33357
  }) => {
33273
33358
  var _a, _b;
33274
33359
  const labels = (0, import_hooks95.useLabels)();
@@ -33278,6 +33363,7 @@ var init_sports_markets = __esm({
33278
33363
  aggKey: event.aggKey ? [event.aggKey] : void 0,
33279
33364
  limit: 100,
33280
33365
  status: import_hooks95.MarketStatus.open,
33366
+ minVolume,
33281
33367
  enabled: hasAggKey
33282
33368
  });
33283
33369
  const {
@@ -33324,6 +33410,7 @@ var init_sports_markets = __esm({
33324
33410
  // completion — hundreds of markets on prop-rich events) from ~15 calls to 1-3.
33325
33411
  limit: 100,
33326
33412
  status: import_hooks95.MarketStatus.open,
33413
+ minVolume,
33327
33414
  enabled: hasAggKey
33328
33415
  });
33329
33416
  const {
@@ -33537,6 +33624,9 @@ var init_sports_event_market_page = __esm({
33537
33624
  onBeforePrimaryAction,
33538
33625
  sharedKyc
33539
33626
  }) => {
33627
+ const {
33628
+ market: { minVolume }
33629
+ } = (0, import_hooks96.useSdkUiConfig)();
33540
33630
  const [sectionMarketsByKey, setSectionMarketsByKey] = (0, import_react68.useState)({});
33541
33631
  const composedEvent = (0, import_react68.useMemo)(() => {
33542
33632
  return mergeSportsSectionMarketsIntoEvent({
@@ -33644,6 +33734,7 @@ var init_sports_event_market_page = __esm({
33644
33734
  {
33645
33735
  event,
33646
33736
  onSectionMarketsChange: handleSectionMarketsChange,
33737
+ minVolume: defaultMarketId ? void 0 : minVolume,
33647
33738
  midpointsResult,
33648
33739
  onOutcomeSelect: isMobileViewport ? () => {
33649
33740
  setIsMobileTradeOpen(true);
@@ -34074,7 +34165,8 @@ var init_event_market = __esm({
34074
34165
  EventMarketPage = (props) => {
34075
34166
  var _a;
34076
34167
  const {
34077
- features: { showSportsMarkets }
34168
+ features: { showSportsMarkets },
34169
+ market: { minVolume }
34078
34170
  } = (0, import_hooks97.useSdkUiConfig)();
34079
34171
  const labels = (0, import_hooks97.useLabels)();
34080
34172
  const hasEventProp = "event" in props && !!props.event;
@@ -34089,7 +34181,10 @@ var init_event_market = __esm({
34089
34181
  } = (0, import_hooks97.useEnrichedVenueEvent)({
34090
34182
  progressive: props.progressiveMarkets,
34091
34183
  eventId: hasEventProp ? "" : (_a = props.eventId) != null ? _a : "",
34092
- enabled: !props.isLoading && !hasEventProp && !!props.eventId
34184
+ enabled: !props.isLoading && !hasEventProp && !!props.eventId,
34185
+ // A deep-linked market may sit below the floor; filtering it out would make the
34186
+ // page silently select a different market, so the floor only applies to browsing.
34187
+ minVolume: props.defaultMarketId ? void 0 : minVolume
34093
34188
  });
34094
34189
  const renderEventContent = (event) => {
34095
34190
  const contentProps = __spreadProps(__spreadValues({}, props), {
@@ -34594,7 +34689,8 @@ var EventListItemContent = ({
34594
34689
  // the volume-sorted top-3 (the detail page omits context and keeps the
34595
34690
  // structured threshold/date order).
34596
34691
  context: "list",
34597
- status: marketStatus
34692
+ status: marketStatus,
34693
+ minVolume: config.market.minVolume
34598
34694
  });
34599
34695
  const resolvedOutcomeMarkets = (0, import_react21.useMemo)(() => {
34600
34696
  if (!isLazyMarketsQueryEnabled || lazyLoadedMarkets.length === 0) return allVenueMarkets;
@@ -35970,7 +36066,8 @@ var EventList = ({
35970
36066
  const labels = (0, import_hooks44.useLabels)();
35971
36067
  const { disabledVenues } = (0, import_hooks44.useAppConfig)();
35972
36068
  const {
35973
- features: { enableVenueEventDiscoveryFilters, showSportsMarkets }
36069
+ features: { enableVenueEventDiscoveryFilters, showSportsMarkets },
36070
+ market: { minVolume }
35974
36071
  } = (0, import_hooks44.useSdkUiConfig)();
35975
36072
  const isDiscoveryFiltersEnabled = enableVenueEventDiscoveryFilters && !search;
35976
36073
  const resolvedTabs = useEventListTabs();
@@ -36213,6 +36310,7 @@ var EventList = ({
36213
36310
  // markets experience is enabled (the sports event-detail view loads the
36214
36311
  // folded companions via aggKey). Gated on the same flag as that view.
36215
36312
  grouped: showSportsMarkets,
36313
+ minVolume,
36216
36314
  initialPages: initialLoadedPageCount,
36217
36315
  enabled: controlledCategoryPath == null || validatedCategoryPathKey === controlledCategoryPathValidationKey
36218
36316
  });
package/dist/pages.mjs CHANGED
@@ -13,22 +13,22 @@ import {
13
13
  buildAggTxExplorerHref,
14
14
  formatShareAmount,
15
15
  useHomePageModals
16
- } from "./chunk-J75RLLP2.mjs";
17
- import "./chunk-H54RU7NF.mjs";
16
+ } from "./chunk-PHT5VLGB.mjs";
17
+ import "./chunk-MDCFCGA3.mjs";
18
18
  import {
19
19
  EventMarketPage,
20
20
  EventOpenOrders,
21
21
  EventOpenOrdersCard,
22
22
  formatRecurringCountdown,
23
23
  useEventOpenOrders
24
- } from "./chunk-5ET2M3XX.mjs";
25
- import "./chunk-JR2XAAK6.mjs";
24
+ } from "./chunk-4X7OLBO6.mjs";
25
+ import "./chunk-YYGS6S7N.mjs";
26
26
  import {
27
27
  DEPOSIT_MODAL_OPEN_EVENT,
28
28
  WITHDRAW_MODAL_OPEN_EVENT,
29
29
  requestAggDepositModalOpen,
30
30
  requestAggWithdrawModalOpen
31
- } from "./chunk-HZXHDH6G.mjs";
31
+ } from "./chunk-KN7JN7F5.mjs";
32
32
  import "./chunk-WOCZ4TVT.mjs";
33
33
  import "./chunk-7ORC3TUJ.mjs";
34
34
  import "./chunk-XZVGHKMW.mjs";