@agg-build/ui 4.24.0 → 4.26.1

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/trading.js CHANGED
@@ -11428,13 +11428,16 @@ var getPlaceOrderBuyPayout = (quoteData) => {
11428
11428
  var _a;
11429
11429
  return (_a = quoteData.estimatedPayout) != null ? _a : quoteData.totalFilled;
11430
11430
  };
11431
- var getPlaceOrderSellProceeds = (quoteData) => Math.max(
11432
- 0,
11433
- quoteData.rawExecCost - quoteData.fills.reduce((sum, fill) => {
11434
- var _a, _b;
11435
- return sum + ((_a = fill.venueFee) != null ? _a : 0) + ((_b = fill.builderFee) != null ? _b : 0);
11436
- }, 0)
11437
- );
11431
+ var getPlaceOrderSellProceeds = (quoteData) => {
11432
+ var _a;
11433
+ return (_a = quoteData.estimatedNetProceeds) != null ? _a : Math.max(
11434
+ 0,
11435
+ quoteData.rawExecCost - quoteData.fills.reduce((sum, fill) => {
11436
+ var _a2, _b;
11437
+ return sum + ((_a2 = fill.venueFee) != null ? _a2 : 0) + ((_b = fill.builderFee) != null ? _b : 0);
11438
+ }, 0)
11439
+ );
11440
+ };
11438
11441
  var getPlaceOrderQuoteValue = (quoteData, tradeSide) => tradeSide === "sell" ? getPlaceOrderSellProceeds(quoteData) : getPlaceOrderBuyPayout(quoteData);
11439
11442
  var resolvePlaceOrderNetResult = ({
11440
11443
  quoteData,
@@ -12790,6 +12793,38 @@ var isPercentageBelowMinimum = (value, minimumValue) => {
12790
12793
  if (parsedValue === null) return false;
12791
12794
  return parsedValue < minimumValue;
12792
12795
  };
12796
+ var ceilDiv = (numerator, denominator) => {
12797
+ return (numerator + denominator - BigInt(1)) / denominator;
12798
+ };
12799
+ var toRaw6 = (value) => {
12800
+ const normalizedValue = Number.isFinite(value) ? Math.max(0, value) : 0;
12801
+ return Math.ceil(normalizedValue * Number(import_sdk22.LIMIT_PRICE_RAW_SCALE)).toString();
12802
+ };
12803
+ var parseSizeStepRaw = (sizeStepRaw) => {
12804
+ if (!sizeStepRaw || !/^[1-9]\d*$/.test(sizeStepRaw)) return BigInt(1);
12805
+ return BigInt(sizeStepRaw);
12806
+ };
12807
+ var toLimitSizeRaw = ({
12808
+ amount: amount2,
12809
+ limitPriceRaw,
12810
+ side,
12811
+ sizeStepRaw
12812
+ }) => {
12813
+ const step = parseSizeStepRaw(sizeStepRaw);
12814
+ if (step <= BigInt(1)) {
12815
+ if (side === "sell") return toRaw6(amount2);
12816
+ const spendRaw = BigInt(toRaw6(amount2));
12817
+ const priceRaw = BigInt(limitPriceRaw);
12818
+ return ceilDiv(spendRaw * import_sdk22.LIMIT_PRICE_RAW_SCALE, priceRaw).toString();
12819
+ }
12820
+ const rawSize = side === "sell" ? BigInt(toRaw6(amount2)) : BigInt(toRaw6(amount2)) * import_sdk22.LIMIT_PRICE_RAW_SCALE / BigInt(limitPriceRaw);
12821
+ return (rawSize / step * step).toString();
12822
+ };
12823
+ var isLimitSizeBelowMinimum = (sizeRaw, minSizeRaw) => {
12824
+ const size = BigInt(sizeRaw);
12825
+ if (size <= BigInt(0)) return true;
12826
+ return !!minSizeRaw && /^\d+$/.test(minSizeRaw) && size < BigInt(minSizeRaw);
12827
+ };
12793
12828
 
12794
12829
  // src/trading/place-order/index.place-order.execution-steps.ts
12795
12830
  var COMPLETED_RAW_STATUSES = /* @__PURE__ */ new Set([
@@ -13840,32 +13875,21 @@ var resolvePlaceOrderPortalContainer = (triggerElement) => {
13840
13875
  return (_a = triggerElement == null ? void 0 : triggerElement.closest(".agg-modal-center")) != null ? _a : void 0;
13841
13876
  };
13842
13877
  var LIMIT_EXPIRATION_OPTION_COUNT = 5;
13878
+ var LIMIT_SIZE_STEP_VENUES = /* @__PURE__ */ new Set([
13879
+ import_sdk23.Venue.tiprun,
13880
+ import_sdk23.Venue.hyperliquid,
13881
+ import_sdk23.Venue.pred,
13882
+ import_sdk23.Venue.polymarket
13883
+ ]);
13843
13884
  import_dayjs5.default.extend(import_utc2.default);
13844
13885
  import_dayjs5.default.extend(import_timezone2.default);
13845
13886
  var LIMIT_PRICE_STEP = 1e-3;
13846
13887
  var LIMIT_PRICE_MIN = 1e-3;
13847
13888
  var LIMIT_PRICE_MAX = 0.999;
13848
- var ceilDiv = (numerator, denominator) => {
13849
- return (numerator + denominator - BigInt(1)) / denominator;
13850
- };
13851
- var toRaw6 = (value) => {
13852
- const normalizedValue = Number.isFinite(value) ? Math.max(0, value) : 0;
13853
- return Math.ceil(normalizedValue * Number(import_sdk23.LIMIT_PRICE_RAW_SCALE)).toString();
13854
- };
13855
13889
  var toLimitPriceRaw = (value) => {
13856
13890
  const clampedValue = Math.min(LIMIT_PRICE_MAX, Math.max(LIMIT_PRICE_MIN, value));
13857
13891
  return Math.round(clampedValue * Number(import_sdk23.LIMIT_PRICE_RAW_SCALE)).toString();
13858
13892
  };
13859
- var toLimitSizeRaw = ({
13860
- amount: amount2,
13861
- limitPriceRaw,
13862
- side
13863
- }) => {
13864
- if (side === "sell") return toRaw6(amount2);
13865
- const spendRaw = BigInt(toRaw6(amount2));
13866
- const priceRaw = BigInt(limitPriceRaw);
13867
- return ceilDiv(spendRaw * import_sdk23.LIMIT_PRICE_RAW_SCALE, priceRaw).toString();
13868
- };
13869
13893
  var formatLimitPriceLabel = (value) => {
13870
13894
  return `${(value * 100).toLocaleString("en-US", {
13871
13895
  minimumFractionDigits: 0,
@@ -13905,11 +13929,12 @@ var buildLimitOrderExecutionGroup = ({
13905
13929
  var getLimitOrderToWinValue = ({
13906
13930
  amount: amount2,
13907
13931
  limitPriceRaw,
13908
- side
13932
+ side,
13933
+ sizeStepRaw
13909
13934
  }) => {
13910
13935
  const priceRaw = BigInt(limitPriceRaw);
13911
13936
  if (priceRaw <= BigInt(0) || priceRaw >= import_sdk23.LIMIT_PRICE_RAW_SCALE) return 0;
13912
- const sizeRaw = BigInt(toLimitSizeRaw({ amount: amount2, limitPriceRaw, side }));
13937
+ const sizeRaw = BigInt(toLimitSizeRaw({ amount: amount2, limitPriceRaw, side, sizeStepRaw }));
13913
13938
  if (side === "buy") return Number(sizeRaw) / Number(import_sdk23.LIMIT_PRICE_RAW_SCALE);
13914
13939
  return Number(ceilDiv(priceRaw * sizeRaw, import_sdk23.LIMIT_PRICE_RAW_SCALE)) / Number(import_sdk23.LIMIT_PRICE_RAW_SCALE);
13915
13940
  };
@@ -14861,7 +14886,8 @@ var PlaceOrder = ({
14861
14886
  const limitVenueQuoteRequests = (0, import_react27.useMemo)(
14862
14887
  () => visibleLimitVenueOptions.map((option) => ({
14863
14888
  venue: option.venue,
14864
- venueMarketOutcomeId: option.venueMarketOutcomeId
14889
+ venueMarketOutcomeId: option.venueMarketOutcomeId,
14890
+ venueMarketId: option.venueMarketId
14865
14891
  })),
14866
14892
  [visibleLimitVenueOptions]
14867
14893
  );
@@ -14893,10 +14919,83 @@ var PlaceOrder = ({
14893
14919
  }
14894
14920
  return venues;
14895
14921
  }, [limitVenueQuotes.quotes]);
14922
+ const originalLimitPriceRaw = (0, import_react27.useMemo)(() => toLimitPriceRaw(limitPrice), [limitPrice]);
14923
+ const limitPriceAdjustmentByVenue = (0, import_react27.useMemo)(() => {
14924
+ var _a2;
14925
+ const adjustments = /* @__PURE__ */ new Map();
14926
+ for (const option of visibleLimitVenueOptions) {
14927
+ try {
14928
+ adjustments.set(
14929
+ option.venue,
14930
+ (0, import_sdk23.adjustLimitPriceRawToTick)({
14931
+ limitPriceRaw: originalLimitPriceRaw,
14932
+ side: internalTab,
14933
+ tickSize: (_a2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _a2.tickSize
14934
+ })
14935
+ );
14936
+ } catch (e) {
14937
+ adjustments.set(
14938
+ option.venue,
14939
+ (0, import_sdk23.adjustLimitPriceRawToTick)({
14940
+ limitPriceRaw: originalLimitPriceRaw,
14941
+ side: internalTab,
14942
+ tickSize: null
14943
+ })
14944
+ );
14945
+ }
14946
+ }
14947
+ return adjustments;
14948
+ }, [internalTab, limitVenueQuoteByVenue, originalLimitPriceRaw, visibleLimitVenueOptions]);
14949
+ const limitSizeRulesByVenue = (0, import_react27.useMemo)(() => {
14950
+ var _a2, _b2;
14951
+ const rulesByVenue = /* @__PURE__ */ new Map();
14952
+ for (const quote of limitVenueQuotes.quotes) {
14953
+ if (!quote.sizeStepRaw && !quote.minSizeRaw) continue;
14954
+ rulesByVenue.set(quote.request.venue, {
14955
+ sizeStepRaw: (_a2 = quote.sizeStepRaw) != null ? _a2 : void 0,
14956
+ minSizeRaw: (_b2 = quote.minSizeRaw) != null ? _b2 : void 0
14957
+ });
14958
+ }
14959
+ return rulesByVenue;
14960
+ }, [limitVenueQuotes.quotes]);
14961
+ const belowMinimumLimitVenues = (0, import_react27.useMemo)(() => {
14962
+ var _a2, _b2;
14963
+ const venues = /* @__PURE__ */ new Set();
14964
+ if (!isLimitOrder || internalAmount <= 0) return venues;
14965
+ for (const option of visibleLimitVenueOptions) {
14966
+ if (geoBlockedLimitVenues.has(option.venue) || (0, import_hooks52.getVenueAvailabilityState)({
14967
+ venueId: option.venue,
14968
+ disabledVenues,
14969
+ isConfigLoading: isAppConfigLoading
14970
+ }) !== "available")
14971
+ continue;
14972
+ const rules = limitSizeRulesByVenue.get(option.venue);
14973
+ if (!(rules == null ? void 0 : rules.sizeStepRaw) && !(rules == null ? void 0 : rules.minSizeRaw)) continue;
14974
+ const sizeRaw = toLimitSizeRaw({
14975
+ amount: internalAmount,
14976
+ limitPriceRaw: (_b2 = (_a2 = limitPriceAdjustmentByVenue.get(option.venue)) == null ? void 0 : _a2.adjustedPriceRaw) != null ? _b2 : originalLimitPriceRaw,
14977
+ side: internalTab,
14978
+ sizeStepRaw: rules.sizeStepRaw
14979
+ });
14980
+ if (isLimitSizeBelowMinimum(sizeRaw, rules.minSizeRaw)) venues.add(option.venue);
14981
+ }
14982
+ return venues;
14983
+ }, [
14984
+ disabledVenues,
14985
+ geoBlockedLimitVenues,
14986
+ internalAmount,
14987
+ internalTab,
14988
+ isAppConfigLoading,
14989
+ isLimitOrder,
14990
+ limitPriceAdjustmentByVenue,
14991
+ limitSizeRulesByVenue,
14992
+ originalLimitPriceRaw,
14993
+ visibleLimitVenueOptions
14994
+ ]);
14896
14995
  const availableLimitVenueOptions = (0, import_react27.useMemo)(() => {
14897
14996
  return visibleLimitVenueOptions.filter((option) => {
14898
14997
  var _a2;
14899
- return !geoBlockedLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
14998
+ return !geoBlockedLimitVenues.has(option.venue) && !belowMinimumLimitVenues.has(option.venue) && // A limit SELL rests against shares held at that specific venue, so a
14900
14999
  // venue the user has no position on is a guaranteed 409 from the
14901
15000
  // server's reservation check — and the automatic pick, which sorts on
14902
15001
  // price alone, would happily choose one. Only narrow once we know
@@ -14908,6 +15007,7 @@ var PlaceOrder = ({
14908
15007
  }) === "available";
14909
15008
  });
14910
15009
  }, [
15010
+ belowMinimumLimitVenues,
14911
15011
  disabledVenues,
14912
15012
  geoBlockedLimitVenues,
14913
15013
  isAppConfigLoading,
@@ -15765,8 +15865,6 @@ var PlaceOrder = ({
15765
15865
  const isSelectedVenueInventoryInsufficient = isSell && (selectedRouteCard == null ? void 0 : selectedRouteCard.kind) === "venue" && selectedRouteCard.insufficientInventory === true;
15766
15866
  const isBelowClientMinimum = !isSell && hasEnteredAmount && internalAmount < MIN_BUY_ORDER_AMOUNT;
15767
15867
  const isBelowVenueMinimumFromQuote = isQuoteBelowVenueMinimum(activeQuoteData);
15768
- const isBelowMinimum = isBelowClientMinimum || isBelowVenueMinimumFromQuote;
15769
- const belowMinimumMessage = isBelowClientMinimum ? tradingLabels.minimumOrderAmount(MIN_BUY_ORDER_AMOUNT) : tradingLabels.minOrderSizeViolated;
15770
15868
  const quoteStatus = (0, import_react27.useMemo)(() => {
15771
15869
  if (!orderEligibility.canPlaceOrder) return void 0;
15772
15870
  return resolvePlaceOrderQuoteStatus({
@@ -15893,33 +15991,6 @@ var PlaceOrder = ({
15893
15991
  return averagePrice == null ? "" : tradingLabels.averagePrice(averagePrice);
15894
15992
  }, [selectedRouteCard, tradingLabels]);
15895
15993
  const displayedToWinValue = (_ea = selectedRouteCard == null ? void 0 : selectedRouteCard.numericValue) != null ? _ea : 0;
15896
- const originalLimitPriceRaw = (0, import_react27.useMemo)(() => toLimitPriceRaw(limitPrice), [limitPrice]);
15897
- const limitPriceAdjustmentByVenue = (0, import_react27.useMemo)(() => {
15898
- var _a2;
15899
- const adjustments = /* @__PURE__ */ new Map();
15900
- for (const option of visibleLimitVenueOptions) {
15901
- try {
15902
- adjustments.set(
15903
- option.venue,
15904
- (0, import_sdk23.adjustLimitPriceRawToTick)({
15905
- limitPriceRaw: originalLimitPriceRaw,
15906
- side: internalTab,
15907
- tickSize: (_a2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _a2.tickSize
15908
- })
15909
- );
15910
- } catch (e) {
15911
- adjustments.set(
15912
- option.venue,
15913
- (0, import_sdk23.adjustLimitPriceRawToTick)({
15914
- limitPriceRaw: originalLimitPriceRaw,
15915
- side: internalTab,
15916
- tickSize: null
15917
- })
15918
- );
15919
- }
15920
- }
15921
- return adjustments;
15922
- }, [internalTab, limitVenueQuoteByVenue, originalLimitPriceRaw, visibleLimitVenueOptions]);
15923
15994
  const selectedLimitPriceAdjustment = selectedLimitVenueOption ? limitPriceAdjustmentByVenue.get(selectedLimitVenueOption.venue) : void 0;
15924
15995
  const selectedLimitPriceRaw = (_fa = selectedLimitPriceAdjustment == null ? void 0 : selectedLimitPriceAdjustment.adjustedPriceRaw) != null ? _fa : originalLimitPriceRaw;
15925
15996
  const limitPriceAdjustmentMessage = (0, import_react27.useMemo)(() => {
@@ -15940,6 +16011,8 @@ var PlaceOrder = ({
15940
16011
  selectedLimitVenueOption,
15941
16012
  tradingLabels
15942
16013
  ]);
16014
+ const selectedLimitSizeRules = selectedLimitVenueOption ? limitSizeRulesByVenue.get(selectedLimitVenueOption.venue) : void 0;
16015
+ const isLimitSizeRulesPending = isLimitOrder && selectedLimitVenueOption != null && LIMIT_SIZE_STEP_VENUES.has(selectedLimitVenueOption.venue) && limitVenueQuotes.isMetadataPending;
15943
16016
  const limitOrderPayload = (0, import_react27.useMemo)(() => {
15944
16017
  if (!selectedLimitVenueOption || internalAmount <= 0) return null;
15945
16018
  if (limitPriceInputError) return null;
@@ -15955,7 +16028,8 @@ var PlaceOrder = ({
15955
16028
  const sizeRaw = toLimitSizeRaw({
15956
16029
  amount: internalAmount,
15957
16030
  limitPriceRaw,
15958
- side: internalTab
16031
+ side: internalTab,
16032
+ sizeStepRaw: selectedLimitSizeRules == null ? void 0 : selectedLimitSizeRules.sizeStepRaw
15959
16033
  });
15960
16034
  const expiresAt = expirationDate ? serializeLimitOrderExpiration(expirationDate) : void 0;
15961
16035
  return __spreadValues({
@@ -15974,8 +16048,12 @@ var PlaceOrder = ({
15974
16048
  limitExpirationType,
15975
16049
  limitPriceInputError,
15976
16050
  selectedLimitVenueOption,
15977
- selectedLimitPriceRaw
16051
+ selectedLimitPriceRaw,
16052
+ selectedLimitSizeRules == null ? void 0 : selectedLimitSizeRules.sizeStepRaw
15978
16053
  ]);
16054
+ const isLimitSizeBelowVenueMinimum = isLimitOrder && (limitOrderPayload != null && isLimitSizeBelowMinimum(limitOrderPayload.sizeRaw, selectedLimitSizeRules == null ? void 0 : selectedLimitSizeRules.minSizeRaw) || selectedLimitVenueOption == null && belowMinimumLimitVenues.size > 0);
16055
+ const isBelowMinimum = isBelowClientMinimum || isBelowVenueMinimumFromQuote || isLimitSizeBelowVenueMinimum;
16056
+ const belowMinimumMessage = isBelowClientMinimum ? tradingLabels.minimumOrderAmount(MIN_BUY_ORDER_AMOUNT) : isSell ? tradingLabels.venueMinOrderSize : tradingLabels.minOrderSizeViolated;
15979
16057
  const resolvedLimitExpirationDraftDate = (0, import_react27.useMemo)(() => {
15980
16058
  return resolveLimitExpirationDate({
15981
16059
  expirationType: "CUSTOM",
@@ -16019,12 +16097,13 @@ var PlaceOrder = ({
16019
16097
  }, [internalTab, limitOrderPayload]);
16020
16098
  const limitRouteCards = (0, import_react27.useMemo)(() => {
16021
16099
  return visibleLimitVenueOptions.map((option) => {
16022
- var _a2, _b2, _c2, _d2;
16100
+ var _a2, _b2, _c2, _d2, _e2;
16023
16101
  const effectiveLimitPriceRaw = (_b2 = (_a2 = limitPriceAdjustmentByVenue.get(option.venue)) == null ? void 0 : _a2.adjustedPriceRaw) != null ? _b2 : originalLimitPriceRaw;
16024
16102
  const venueToWinValue = getLimitOrderToWinValue({
16025
16103
  amount: internalAmount,
16026
16104
  limitPriceRaw: effectiveLimitPriceRaw,
16027
- side: internalTab
16105
+ side: internalTab,
16106
+ sizeStepRaw: (_c2 = limitSizeRulesByVenue.get(option.venue)) == null ? void 0 : _c2.sizeStepRaw
16028
16107
  });
16029
16108
  const availabilityState = (0, import_hooks52.getVenueAvailabilityState)({
16030
16109
  venueId: option.venue,
@@ -16032,10 +16111,10 @@ var PlaceOrder = ({
16032
16111
  isConfigLoading: isAppConfigLoading
16033
16112
  });
16034
16113
  const isGeoBlocked = geoBlockedLimitVenues.has(option.venue);
16035
- const isUnavailable = isTradingBlocked || isGeoBlocked || availabilityState !== "available";
16114
+ const isUnavailable = isTradingBlocked || isGeoBlocked || belowMinimumLimitVenues.has(option.venue) || availabilityState !== "available";
16036
16115
  const currentPriceLabel = option.currentPrice == null ? "\u2014" : formatProbabilityCents(option.currentPrice, formatPrice);
16037
16116
  const totalFees = getSmartRouteTotalFees(
16038
- (_d2 = (_c2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _c2.data) == null ? void 0 : _d2.feeBreakdown
16117
+ (_e2 = (_d2 = limitVenueQuoteByVenue.get(option.venue)) == null ? void 0 : _d2.data) == null ? void 0 : _e2.feeBreakdown
16039
16118
  );
16040
16119
  const feeLabel = totalFees == null ? void 0 : formatUsd(totalFees, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
16041
16120
  return {
@@ -16054,6 +16133,7 @@ var PlaceOrder = ({
16054
16133
  };
16055
16134
  });
16056
16135
  }, [
16136
+ belowMinimumLimitVenues,
16057
16137
  disabledVenues,
16058
16138
  formatPrice,
16059
16139
  geoBlockedLimitVenues,
@@ -16062,6 +16142,7 @@ var PlaceOrder = ({
16062
16142
  isAppConfigLoading,
16063
16143
  isTradingBlocked,
16064
16144
  limitPriceAdjustmentByVenue,
16145
+ limitSizeRulesByVenue,
16065
16146
  limitVenueQuoteByVenue,
16066
16147
  originalLimitPriceRaw,
16067
16148
  tradingLabels,
@@ -16160,10 +16241,10 @@ var PlaceOrder = ({
16160
16241
  const fills = (_b2 = (_a2 = selectedRouteCard.quoteData) == null ? void 0 : _a2.fills) != null ? _b2 : [];
16161
16242
  return fills.length > 0 && fills.every((f) => geoBlockedVenuesFromWarnings.has(f.venue));
16162
16243
  }, [selectedRouteCard, geoBlockedVenuesFromWarnings]);
16163
- const shouldShowGeoBlockBanner = isTradingBlocked || selectedRouteGeoBlocked || isPrimaryVenueGeoBlocked || isLimitOrder && limitRouteCards.length > 0 && limitRouteCards.every((card) => card.isUnavailable);
16244
+ const shouldShowGeoBlockBanner = isTradingBlocked || selectedRouteGeoBlocked || isPrimaryVenueGeoBlocked || isLimitOrder && limitRouteCards.length > 0 && limitRouteCards.every((card) => card.isUnavailable) && limitRouteCards.some((card) => !card.venue || !belowMinimumLimitVenues.has(card.venue));
16164
16245
  const actionLabel = `${internalTab === "buy" ? tradingLabels.buy : tradingLabels.sell} ${selectedOutcomeLabel}`.trim();
16165
- 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;
16166
- const shouldShowSmartRouting = orderEligibility.canPlaceOrder && hasEnteredAmount && !isBelowMinimum && (isLimitOrder ? limitRouteCards.length > 0 : displayedRouteCards.length > 0 || smartRoute.isFetching || smartRoute.isLoading || isSell && (venueSellQuotes.isFetching || venueSellQuotes.isLoading));
16246
+ 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;
16247
+ const shouldShowSmartRouting = orderEligibility.canPlaceOrder && hasEnteredAmount && !isBelowClientMinimum && !isBelowVenueMinimumFromQuote && (isLimitOrder ? limitRouteCards.length > 0 : displayedRouteCards.length > 0 || smartRoute.isFetching || smartRoute.isLoading || isSell && (venueSellQuotes.isFetching || venueSellQuotes.isLoading));
16167
16248
  const shouldShowRouteToggle = !isLimitOrder && !isQuoteLoading && displayedRouteCards.length > PLACE_ORDER_ROUTE_COLLAPSED_CARD_COUNT;
16168
16249
  const handleReturnToOrderForm = (0, import_react27.useCallback)(() => {
16169
16250
  const submittedSelection = submittedSelectionRef.current;
package/dist/trading.mjs CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  useClaimWinnings,
15
15
  useResolvedMarketClaim,
16
16
  venueRequiresSharedKyc
17
- } from "./chunk-HZXHDH6G.mjs";
17
+ } from "./chunk-KN7JN7F5.mjs";
18
18
  import {
19
19
  SETTLEMENT_SECTION_ID,
20
20
  Settlement,
@@ -93,11 +93,12 @@ export declare const deriveAggregateOrderStatus: (orderIds: string[], terminalEv
93
93
  */
94
94
  export declare const getPlaceOrderBuyPayout: (quoteData: Pick<SmartRouteResponse, "estimatedPayout" | "totalFilled">) => number;
95
95
  /**
96
- * Dollars a SELL quote returns after the fees charged at fill. `rawExecCost` is
97
- * gross proceeds on a sell (redeem legs at $1 plus router revenue), so subtract
98
- * each fill's venue and builder fee. Sell fills carry no execution reserve.
96
+ * Dollars a SELL quote returns after every fee charged at fill. The API's
97
+ * `estimatedNetProceeds` includes partner app and referral fees; older
98
+ * responses omit it, so fall back to gross (`rawExecCost`: redeem legs at $1
99
+ * plus router revenue) minus each fill's venue and builder fee.
99
100
  */
100
- export declare const getPlaceOrderSellProceeds: (quoteData: Pick<SmartRouteResponse, "rawExecCost" | "fills">) => number;
101
+ export declare const getPlaceOrderSellProceeds: (quoteData: Pick<SmartRouteResponse, "rawExecCost" | "fills" | "estimatedNetProceeds">) => number;
101
102
  /** The dollar figure a route card shows and is ranked by. */
102
103
  export declare const getPlaceOrderQuoteValue: (quoteData: SmartRouteResponse, tradeSide: PlaceOrderTab) => number;
103
104
  /**
@@ -265,3 +266,18 @@ export declare const finalizePercentageValue: (value: string | undefined) => str
265
266
  export declare const parsePercentageValue: (value: string | undefined) => number | null;
266
267
  export declare const formatPercentageValue: (value: string | undefined) => string;
267
268
  export declare const isPercentageBelowMinimum: (value: string | undefined, minimumValue: number | null) => boolean;
269
+ export declare const ceilDiv: (numerator: bigint, denominator: bigint) => bigint;
270
+ /**
271
+ * Limit-order `sizeRaw` (6-dec shares). Buy `amount` is USD spend, sell is
272
+ * shares. With no venue step (or a 1-raw step) this is the original 1-raw
273
+ * math. With a coarser step the size is floored to the venue grid, so a buy
274
+ * never costs more than the entered spend.
275
+ */
276
+ export declare const toLimitSizeRaw: ({ amount, limitPriceRaw, side, sizeStepRaw, }: {
277
+ amount: number;
278
+ limitPriceRaw: string;
279
+ side: PlaceOrderTab;
280
+ sizeStepRaw?: string | null;
281
+ }) => string;
282
+ /** A floored limit size of zero, or under the venue minimum, cannot be placed. */
283
+ export declare const isLimitSizeBelowMinimum: (sizeRaw: string, minSizeRaw: string | null | undefined) => boolean;
@@ -93,11 +93,12 @@ export declare const deriveAggregateOrderStatus: (orderIds: string[], terminalEv
93
93
  */
94
94
  export declare const getPlaceOrderBuyPayout: (quoteData: Pick<SmartRouteResponse, "estimatedPayout" | "totalFilled">) => number;
95
95
  /**
96
- * Dollars a SELL quote returns after the fees charged at fill. `rawExecCost` is
97
- * gross proceeds on a sell (redeem legs at $1 plus router revenue), so subtract
98
- * each fill's venue and builder fee. Sell fills carry no execution reserve.
96
+ * Dollars a SELL quote returns after every fee charged at fill. The API's
97
+ * `estimatedNetProceeds` includes partner app and referral fees; older
98
+ * responses omit it, so fall back to gross (`rawExecCost`: redeem legs at $1
99
+ * plus router revenue) minus each fill's venue and builder fee.
99
100
  */
100
- export declare const getPlaceOrderSellProceeds: (quoteData: Pick<SmartRouteResponse, "rawExecCost" | "fills">) => number;
101
+ export declare const getPlaceOrderSellProceeds: (quoteData: Pick<SmartRouteResponse, "rawExecCost" | "fills" | "estimatedNetProceeds">) => number;
101
102
  /** The dollar figure a route card shows and is ranked by. */
102
103
  export declare const getPlaceOrderQuoteValue: (quoteData: SmartRouteResponse, tradeSide: PlaceOrderTab) => number;
103
104
  /**
@@ -265,3 +266,18 @@ export declare const finalizePercentageValue: (value: string | undefined) => str
265
266
  export declare const parsePercentageValue: (value: string | undefined) => number | null;
266
267
  export declare const formatPercentageValue: (value: string | undefined) => string;
267
268
  export declare const isPercentageBelowMinimum: (value: string | undefined, minimumValue: number | null) => boolean;
269
+ export declare const ceilDiv: (numerator: bigint, denominator: bigint) => bigint;
270
+ /**
271
+ * Limit-order `sizeRaw` (6-dec shares). Buy `amount` is USD spend, sell is
272
+ * shares. With no venue step (or a 1-raw step) this is the original 1-raw
273
+ * math. With a coarser step the size is floored to the venue grid, so a buy
274
+ * never costs more than the entered spend.
275
+ */
276
+ export declare const toLimitSizeRaw: ({ amount, limitPriceRaw, side, sizeStepRaw, }: {
277
+ amount: number;
278
+ limitPriceRaw: string;
279
+ side: PlaceOrderTab;
280
+ sizeStepRaw?: string | null;
281
+ }) => string;
282
+ /** A floored limit size of zero, or under the venue minimum, cannot be placed. */
283
+ export declare const isLimitSizeBelowMinimum: (sizeRaw: string, minSizeRaw: string | null | undefined) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/ui",
3
- "version": "4.24.0",
3
+ "version": "4.26.1",
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/hooks": "^4.24.0",
104
- "@agg-build/sdk": "^4.24.0"
103
+ "@agg-build/hooks": "^4.26.1",
104
+ "@agg-build/sdk": "^4.26.0"
105
105
  },
106
106
  "dependencies": {
107
107
  "@number-flow/react": "^0.6.0",