@agg-build/sdk 4.1.0 → 4.5.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/index.js CHANGED
@@ -78,9 +78,12 @@ __export(index_exports, {
78
78
  CONFIRMED_MATCH_STATUSES: () => CONFIRMED_MATCH_STATUSES,
79
79
  CandleBuilder: () => CandleBuilder,
80
80
  Chain: () => Chain,
81
+ DEFAULT_BALANCE_REFILL_DAILY_CAP_RAW: () => DEFAULT_BALANCE_REFILL_DAILY_CAP_RAW,
82
+ DEFAULT_BALANCE_REFILL_MAX_FEE_RAW: () => DEFAULT_BALANCE_REFILL_MAX_FEE_RAW,
81
83
  IMAGE_SIZES: () => IMAGE_SIZES,
82
84
  INACTIVE_VENUES: () => INACTIVE_VENUES,
83
85
  ImageSize: () => ImageSize,
86
+ LIMIT_PRICE_RAW_SCALE: () => LIMIT_PRICE_RAW_SCALE,
84
87
  MarketStatus: () => MarketStatus,
85
88
  MatchStatus: () => MatchStatus,
86
89
  MatchType: () => MatchType,
@@ -91,7 +94,9 @@ __export(index_exports, {
91
94
  TradeSide: () => TradeSide,
92
95
  TurnstileChallengeError: () => TurnstileChallengeError,
93
96
  VENUES: () => VENUES,
97
+ VENUE_CHAIN_IDS: () => VENUE_CHAIN_IDS,
94
98
  Venue: () => Venue,
99
+ adjustLimitPriceRawToTick: () => adjustLimitPriceRawToTick,
95
100
  aggregateMidpoint: () => aggregateMidpoint,
96
101
  applyOrderbookDelta: () => applyOrderbookDelta,
97
102
  buildVenueUrl: () => buildVenueUrl,
@@ -102,10 +107,12 @@ __export(index_exports, {
102
107
  formatMarketQuestion: () => formatMarketQuestion,
103
108
  formatOutcomeLabel: () => formatOutcomeLabel,
104
109
  formatOutcomeTitle: () => formatOutcomeTitle,
110
+ getBalanceRefillMaximumRaw: () => getBalanceRefillMaximumRaw,
105
111
  getEffectiveDisabledVenues: () => getEffectiveDisabledVenues,
106
112
  getWalletAddressFromUserProfile: () => getWalletAddressFromUserProfile,
107
113
  hasShape: () => hasShape,
108
114
  isAggApiError: () => isAggApiError,
115
+ isBalanceRefillWithinDailyCap: () => isBalanceRefillWithinDailyCap,
109
116
  isEmail: () => isEmail,
110
117
  isEnum: () => isEnum,
111
118
  isFiniteNonNeg: () => isFiniteNonNeg,
@@ -136,6 +143,7 @@ var Venue = /* @__PURE__ */ ((Venue3) => {
136
143
  Venue3["probable"] = "probable";
137
144
  Venue3["myriad"] = "myriad";
138
145
  Venue3["hyperliquid"] = "hyperliquid";
146
+ Venue3["novig"] = "novig";
139
147
  return Venue3;
140
148
  })(Venue || {});
141
149
  var VENUES = [
@@ -146,9 +154,19 @@ var VENUES = [
146
154
  "predict" /* predict */,
147
155
  "probable" /* probable */,
148
156
  "myriad" /* myriad */,
149
- "hyperliquid" /* hyperliquid */
157
+ "hyperliquid" /* hyperliquid */,
158
+ "novig" /* novig */
150
159
  ];
160
+ var VENUE_CHAIN_IDS = {
161
+ ["kalshi" /* kalshi */]: 792703809,
162
+ ["polymarket" /* polymarket */]: 137,
163
+ ["limitless" /* limitless */]: 8453,
164
+ ["predict" /* predict */]: 56,
165
+ ["myriad" /* myriad */]: 56,
166
+ ["hyperliquid" /* hyperliquid */]: 1337
167
+ };
151
168
  var ACTIVE_VENUES = [
169
+ "kalshi" /* kalshi */,
152
170
  "polymarket" /* polymarket */,
153
171
  "limitless" /* limitless */,
154
172
  "opinion" /* opinion */,
@@ -157,7 +175,8 @@ var ACTIVE_VENUES = [
157
175
  "myriad" /* myriad */,
158
176
  "hyperliquid" /* hyperliquid */
159
177
  ];
160
- var INACTIVE_VENUES = ["kalshi" /* kalshi */];
178
+ var INACTIVE_VENUES = ["novig" /* novig */];
179
+ var DEFAULT_DISABLED_VENUES = ["novig" /* novig */];
161
180
  var ACTIVE_VENUE_SET = new Set(ACTIVE_VENUES);
162
181
  var INACTIVE_VENUE_SET = new Set(INACTIVE_VENUES);
163
182
  function normalizeVenue(venue) {
@@ -178,11 +197,13 @@ function isVenueDataVisible(venue, dataVisibleOverride = []) {
178
197
  const n = normalizeVenue(venue);
179
198
  return dataVisibleOverride.some((v) => normalizeVenue(v) === n);
180
199
  }
181
- function getEffectiveDisabledVenues(disabledVenues = [], dataVisibleVenues = []) {
182
- if (disabledVenues.length === 0 && dataVisibleVenues.length === 0) return [...INACTIVE_VENUES];
200
+ function getEffectiveDisabledVenues(disabledVenues, dataVisibleVenues = []) {
201
+ if (disabledVenues === void 0) {
202
+ const disabled2 = new Set(DEFAULT_DISABLED_VENUES);
203
+ for (const venue of dataVisibleVenues) disabled2.delete(normalizeVenue(venue));
204
+ return VENUES.filter((venue) => disabled2.has(venue));
205
+ }
183
206
  const disabled = new Set(disabledVenues.map(normalizeVenue));
184
- for (const venue of INACTIVE_VENUES) disabled.add(venue);
185
- for (const venue of dataVisibleVenues) disabled.delete(normalizeVenue(venue));
186
207
  return VENUES.filter((venue) => disabled.has(venue));
187
208
  }
188
209
 
@@ -705,11 +726,75 @@ function buildVenueUrl(venue, opts) {
705
726
  if (opts.eventSlug) return `https://probable.markets/event/${opts.eventSlug}`;
706
727
  return null;
707
728
  }
729
+ case "novig": {
730
+ if (opts.outcomeExternalId && opts.partnerId) {
731
+ return opts.platform === "native" ? `novigapp://events/${opts.outcomeExternalId}/${opts.partnerId}` : `https://novig.com/events/${opts.outcomeExternalId}/${opts.partnerId}`;
732
+ }
733
+ return null;
734
+ }
708
735
  default:
709
736
  return null;
710
737
  }
711
738
  }
712
739
 
740
+ // ../common/src/utils/limit-price-ticks.ts
741
+ var LIMIT_PRICE_RAW_SCALE = BigInt(1e6);
742
+ var resolveTickSizeRaw = (tickSize) => {
743
+ const scaledTick = tickSize * Number(LIMIT_PRICE_RAW_SCALE);
744
+ const roundedTick = Math.round(scaledTick);
745
+ if (!Number.isFinite(scaledTick) || roundedTick <= 0 || Math.abs(scaledTick - roundedTick) > 1e-6) {
746
+ throw new RangeError(`Unsupported limit-order tick size: ${tickSize}`);
747
+ }
748
+ return BigInt(roundedTick);
749
+ };
750
+ var adjustLimitPriceRawToTick = ({
751
+ limitPriceRaw,
752
+ side,
753
+ tickSize
754
+ }) => {
755
+ const originalPrice = BigInt(limitPriceRaw);
756
+ const originalPriceRaw = originalPrice.toString();
757
+ if (tickSize == null) {
758
+ return {
759
+ adjusted: false,
760
+ adjustedPriceRaw: originalPriceRaw,
761
+ originalPriceRaw,
762
+ tickSizeRaw: null
763
+ };
764
+ }
765
+ const tickSizeRaw = resolveTickSizeRaw(tickSize);
766
+ const remainder = originalPrice % tickSizeRaw;
767
+ if (remainder === BigInt(0)) {
768
+ return {
769
+ adjusted: false,
770
+ adjustedPriceRaw: originalPriceRaw,
771
+ originalPriceRaw,
772
+ tickSizeRaw: tickSizeRaw.toString()
773
+ };
774
+ }
775
+ const adjustedPrice = side === "buy" ? originalPrice - remainder : originalPrice + (tickSizeRaw - remainder);
776
+ return {
777
+ adjusted: true,
778
+ adjustedPriceRaw: adjustedPrice.toString(),
779
+ originalPriceRaw,
780
+ tickSizeRaw: tickSizeRaw.toString()
781
+ };
782
+ };
783
+
784
+ // ../common/src/utils/balance-refill.ts
785
+ var DEFAULT_BALANCE_REFILL_DAILY_CAP_RAW = "1002000000";
786
+ var DEFAULT_BALANCE_REFILL_MAX_FEE_RAW = "2000000";
787
+ var getBalanceRefillMaximumRaw = (dailyCapRaw, maxFeeRaw) => {
788
+ const dailyCap = BigInt(dailyCapRaw);
789
+ const maximumFee = BigInt(maxFeeRaw);
790
+ if (dailyCap <= maximumFee) return "0";
791
+ return (dailyCap - maximumFee).toString();
792
+ };
793
+ var isBalanceRefillWithinDailyCap = (minimumRaw, refillAmountRaw, dailyCapRaw, maxFeeRaw) => {
794
+ const maximum = BigInt(getBalanceRefillMaximumRaw(dailyCapRaw, maxFeeRaw));
795
+ return BigInt(minimumRaw) <= maximum && BigInt(refillAmountRaw) <= maximum;
796
+ };
797
+
713
798
  // src/errors.ts
714
799
  var TurnstileChallengeError = class extends Error {
715
800
  constructor(siteKey) {
@@ -1662,6 +1747,7 @@ var AggWebSocket = class {
1662
1747
  var COOKIE_REFRESH_DELIVERY = "cookie-refresh";
1663
1748
  var DEFAULT_MIDPOINT_IDS_PER_REQUEST = 75;
1664
1749
  var MAX_MIDPOINT_IDS_PER_REQUEST = 75;
1750
+ var MAX_SPORTS_EVENT_IDS_PER_REQUEST = 25;
1665
1751
  var isUserProfile = (user) => {
1666
1752
  return "accounts" in user && "wallets" in user && "avatarUrl" in user;
1667
1753
  };
@@ -2172,13 +2258,13 @@ Issued At: ${issuedAt}`;
2172
2258
  * the bearer automatically. Response shape:
2173
2259
  * - OAuth providers → `{ type: "redirect", url }`; redirect the browser to `url`.
2174
2260
  * - Email → `{ type: "magic_link", success: true }`; check the destination inbox.
2261
+ * - Wallet providers (siwe/siws) → `{ type: "wallet_challenge", message }`; have the
2262
+ * user sign `message` VERBATIM, then submit it to `linkAccountConfirm()` as
2263
+ * `{ kind: "wallet_signature", message, signature }`.
2175
2264
  *
2176
- * After the provider callback runs, the browser lands back on the app's `redirectUrl`
2265
+ * After the OAuth/email callback runs, the browser lands back on the app's `redirectUrl`
2177
2266
  * with a `link_confirm_token` query param. Feed that token to `linkAccountConfirm()`
2178
2267
  * to persist the Account row.
2179
- *
2180
- * Wallet linking (siwe/siws) is not supported yet — it requires a different message
2181
- * binding protocol than sign-in to be safe against signature phishing.
2182
2268
  */
2183
2269
  linkAccount(body) {
2184
2270
  return __async(this, null, function* () {
@@ -2193,18 +2279,27 @@ Issued At: ${issuedAt}`;
2193
2279
  });
2194
2280
  }
2195
2281
  /**
2196
- * Exchange a `link_confirm_token` for a linked `Account` row. The server matches
2197
- * the current bearer's `principalId` to the token's `principalId` before writing —
2198
- * this is the final ownership check.
2282
+ * Finalize an account link.
2283
+ *
2284
+ * - Pass a `link_confirm_token` string (OAuth/email) to exchange it for a linked
2285
+ * `Account` row.
2286
+ * - Pass `{ kind: "wallet_signature", message, signature }` (wallet providers) to
2287
+ * verify the signature over the `wallet_challenge` `message` returned by
2288
+ * `linkAccount()`.
2289
+ *
2290
+ * The server matches the current bearer's `principalId` to the challenge/token's
2291
+ * `principalId` before writing — this is the final ownership check. A wallet already
2292
+ * linked to a DIFFERENT principal rejects with HTTP 409.
2199
2293
  */
2200
- linkAccountConfirm(token) {
2294
+ linkAccountConfirm(input) {
2201
2295
  return __async(this, null, function* () {
2202
2296
  if (!this.accessToken) {
2203
2297
  yield this.refreshWithDedup();
2204
2298
  }
2299
+ const body = typeof input === "string" ? { token: input } : input;
2205
2300
  return this.request(
2206
2301
  "/users/me/link-account/confirm",
2207
- this.buildAuthRequestInit({ method: "POST", body: JSON.stringify({ token }) })
2302
+ this.buildAuthRequestInit({ method: "POST", body: JSON.stringify(body) })
2208
2303
  );
2209
2304
  });
2210
2305
  }
@@ -2375,7 +2470,9 @@ Issued At: ${issuedAt}`;
2375
2470
  const query = {};
2376
2471
  if (params.orderId) query.orderId = params.orderId;
2377
2472
  if (params.quoteId) query.quoteId = params.quoteId;
2473
+ if (params.externalId) query.externalId = params.externalId;
2378
2474
  if (params.status) query.status = params.status;
2475
+ if (params.orderType) query.orderType = params.orderType;
2379
2476
  if (params.mode) query.mode = params.mode;
2380
2477
  if (params.cursor) query.cursor = params.cursor;
2381
2478
  if (params.limit != null) query.limit = String(params.limit);
@@ -2576,6 +2673,7 @@ Issued At: ${issuedAt}`;
2576
2673
  if ((options == null ? void 0 : options.status) && options.status.length > 0) query.status = options.status;
2577
2674
  if (options == null ? void 0 : options.sortBy) query.sortBy = options.sortBy;
2578
2675
  if (options == null ? void 0 : options.sortDir) query.sortDir = options.sortDir;
2676
+ if (options == null ? void 0 : options.aggKey) query.aggKey = options.aggKey;
2579
2677
  if (options == null ? void 0 : options.recurrence) query.recurrence = options.recurrence;
2580
2678
  if ((options == null ? void 0 : options.limit) != null) query.limit = String(options.limit);
2581
2679
  if (options == null ? void 0 : options.cursor) query.cursor = options.cursor;
@@ -2584,7 +2682,8 @@ Issued At: ${issuedAt}`;
2584
2682
  if (options == null ? void 0 : options.endDateFrom) query.endDateFrom = options.endDateFrom;
2585
2683
  if (options == null ? void 0 : options.grouped) query.grouped = "true";
2586
2684
  return this.request("/venue-events", {
2587
- query: Object.keys(query).length > 0 ? query : void 0
2685
+ query: Object.keys(query).length > 0 ? query : void 0,
2686
+ signal: options == null ? void 0 : options.signal
2588
2687
  });
2589
2688
  });
2590
2689
  }
@@ -2600,6 +2699,27 @@ Issued At: ${issuedAt}`;
2600
2699
  });
2601
2700
  });
2602
2701
  }
2702
+ /** Get normalized live score state for sports events. Requires appId or admin auth. */
2703
+ getSportsLive(eventIds, options) {
2704
+ return __async(this, null, function* () {
2705
+ const normalizedEventIds = normalizeRequestedVenueMarketIds(eventIds);
2706
+ if (normalizedEventIds.length === 0) {
2707
+ return { data: [], missingEventIds: [] };
2708
+ }
2709
+ const responses = yield Promise.all(
2710
+ chunkArray(normalizedEventIds, MAX_SPORTS_EVENT_IDS_PER_REQUEST).map(
2711
+ (eventIdChunk) => this.request("/sports/live", {
2712
+ query: { eventIds: eventIdChunk },
2713
+ signal: options == null ? void 0 : options.signal
2714
+ })
2715
+ )
2716
+ );
2717
+ return {
2718
+ data: responses.flatMap((response) => response.data),
2719
+ missingEventIds: [...new Set(responses.flatMap((response) => response.missingEventIds))]
2720
+ };
2721
+ });
2722
+ }
2603
2723
  /** List deterministic recurring crypto window markets across venues. Requires appId or admin auth. */
2604
2724
  listRecurringCryptoMarkets(options) {
2605
2725
  return __async(this, null, function* () {
@@ -3040,6 +3160,20 @@ Issued At: ${issuedAt}`;
3040
3160
  });
3041
3161
  });
3042
3162
  }
3163
+ /**
3164
+ * Place a market order directly on a named venue — no prior quote needed.
3165
+ * Always produces exactly one order. `externalId` is required and unique
3166
+ * within your app — two different users of the same app cannot share one —
3167
+ * so retrying a timed-out call with the same value is safe.
3168
+ */
3169
+ placeOrder(params) {
3170
+ return __async(this, null, function* () {
3171
+ return this.request("/execution/orders", {
3172
+ method: "POST",
3173
+ body: JSON.stringify(params)
3174
+ });
3175
+ });
3176
+ }
3043
3177
  /** Redeem resolved winning positions by venue market outcome ids. */
3044
3178
  redeem(body) {
3045
3179
  return __async(this, null, function* () {
@@ -3416,9 +3550,12 @@ function createAggClient(options) {
3416
3550
  CONFIRMED_MATCH_STATUSES,
3417
3551
  CandleBuilder,
3418
3552
  Chain,
3553
+ DEFAULT_BALANCE_REFILL_DAILY_CAP_RAW,
3554
+ DEFAULT_BALANCE_REFILL_MAX_FEE_RAW,
3419
3555
  IMAGE_SIZES,
3420
3556
  INACTIVE_VENUES,
3421
3557
  ImageSize,
3558
+ LIMIT_PRICE_RAW_SCALE,
3422
3559
  MarketStatus,
3423
3560
  MatchStatus,
3424
3561
  MatchType,
@@ -3429,7 +3566,9 @@ function createAggClient(options) {
3429
3566
  TradeSide,
3430
3567
  TurnstileChallengeError,
3431
3568
  VENUES,
3569
+ VENUE_CHAIN_IDS,
3432
3570
  Venue,
3571
+ adjustLimitPriceRawToTick,
3433
3572
  aggregateMidpoint,
3434
3573
  applyOrderbookDelta,
3435
3574
  buildVenueUrl,
@@ -3440,10 +3579,12 @@ function createAggClient(options) {
3440
3579
  formatMarketQuestion,
3441
3580
  formatOutcomeLabel,
3442
3581
  formatOutcomeTitle,
3582
+ getBalanceRefillMaximumRaw,
3443
3583
  getEffectiveDisabledVenues,
3444
3584
  getWalletAddressFromUserProfile,
3445
3585
  hasShape,
3446
3586
  isAggApiError,
3587
+ isBalanceRefillWithinDailyCap,
3447
3588
  isEmail,
3448
3589
  isEnum,
3449
3590
  isFiniteNonNeg,
package/dist/index.mjs CHANGED
@@ -15,6 +15,7 @@ var Venue = /* @__PURE__ */ ((Venue3) => {
15
15
  Venue3["probable"] = "probable";
16
16
  Venue3["myriad"] = "myriad";
17
17
  Venue3["hyperliquid"] = "hyperliquid";
18
+ Venue3["novig"] = "novig";
18
19
  return Venue3;
19
20
  })(Venue || {});
20
21
  var VENUES = [
@@ -25,9 +26,19 @@ var VENUES = [
25
26
  "predict" /* predict */,
26
27
  "probable" /* probable */,
27
28
  "myriad" /* myriad */,
28
- "hyperliquid" /* hyperliquid */
29
+ "hyperliquid" /* hyperliquid */,
30
+ "novig" /* novig */
29
31
  ];
32
+ var VENUE_CHAIN_IDS = {
33
+ ["kalshi" /* kalshi */]: 792703809,
34
+ ["polymarket" /* polymarket */]: 137,
35
+ ["limitless" /* limitless */]: 8453,
36
+ ["predict" /* predict */]: 56,
37
+ ["myriad" /* myriad */]: 56,
38
+ ["hyperliquid" /* hyperliquid */]: 1337
39
+ };
30
40
  var ACTIVE_VENUES = [
41
+ "kalshi" /* kalshi */,
31
42
  "polymarket" /* polymarket */,
32
43
  "limitless" /* limitless */,
33
44
  "opinion" /* opinion */,
@@ -36,7 +47,8 @@ var ACTIVE_VENUES = [
36
47
  "myriad" /* myriad */,
37
48
  "hyperliquid" /* hyperliquid */
38
49
  ];
39
- var INACTIVE_VENUES = ["kalshi" /* kalshi */];
50
+ var INACTIVE_VENUES = ["novig" /* novig */];
51
+ var DEFAULT_DISABLED_VENUES = ["novig" /* novig */];
40
52
  var ACTIVE_VENUE_SET = new Set(ACTIVE_VENUES);
41
53
  var INACTIVE_VENUE_SET = new Set(INACTIVE_VENUES);
42
54
  function normalizeVenue(venue) {
@@ -57,11 +69,13 @@ function isVenueDataVisible(venue, dataVisibleOverride = []) {
57
69
  const n = normalizeVenue(venue);
58
70
  return dataVisibleOverride.some((v) => normalizeVenue(v) === n);
59
71
  }
60
- function getEffectiveDisabledVenues(disabledVenues = [], dataVisibleVenues = []) {
61
- if (disabledVenues.length === 0 && dataVisibleVenues.length === 0) return [...INACTIVE_VENUES];
72
+ function getEffectiveDisabledVenues(disabledVenues, dataVisibleVenues = []) {
73
+ if (disabledVenues === void 0) {
74
+ const disabled2 = new Set(DEFAULT_DISABLED_VENUES);
75
+ for (const venue of dataVisibleVenues) disabled2.delete(normalizeVenue(venue));
76
+ return VENUES.filter((venue) => disabled2.has(venue));
77
+ }
62
78
  const disabled = new Set(disabledVenues.map(normalizeVenue));
63
- for (const venue of INACTIVE_VENUES) disabled.add(venue);
64
- for (const venue of dataVisibleVenues) disabled.delete(normalizeVenue(venue));
65
79
  return VENUES.filter((venue) => disabled.has(venue));
66
80
  }
67
81
 
@@ -584,11 +598,75 @@ function buildVenueUrl(venue, opts) {
584
598
  if (opts.eventSlug) return `https://probable.markets/event/${opts.eventSlug}`;
585
599
  return null;
586
600
  }
601
+ case "novig": {
602
+ if (opts.outcomeExternalId && opts.partnerId) {
603
+ return opts.platform === "native" ? `novigapp://events/${opts.outcomeExternalId}/${opts.partnerId}` : `https://novig.com/events/${opts.outcomeExternalId}/${opts.partnerId}`;
604
+ }
605
+ return null;
606
+ }
587
607
  default:
588
608
  return null;
589
609
  }
590
610
  }
591
611
 
612
+ // ../common/src/utils/limit-price-ticks.ts
613
+ var LIMIT_PRICE_RAW_SCALE = BigInt(1e6);
614
+ var resolveTickSizeRaw = (tickSize) => {
615
+ const scaledTick = tickSize * Number(LIMIT_PRICE_RAW_SCALE);
616
+ const roundedTick = Math.round(scaledTick);
617
+ if (!Number.isFinite(scaledTick) || roundedTick <= 0 || Math.abs(scaledTick - roundedTick) > 1e-6) {
618
+ throw new RangeError(`Unsupported limit-order tick size: ${tickSize}`);
619
+ }
620
+ return BigInt(roundedTick);
621
+ };
622
+ var adjustLimitPriceRawToTick = ({
623
+ limitPriceRaw,
624
+ side,
625
+ tickSize
626
+ }) => {
627
+ const originalPrice = BigInt(limitPriceRaw);
628
+ const originalPriceRaw = originalPrice.toString();
629
+ if (tickSize == null) {
630
+ return {
631
+ adjusted: false,
632
+ adjustedPriceRaw: originalPriceRaw,
633
+ originalPriceRaw,
634
+ tickSizeRaw: null
635
+ };
636
+ }
637
+ const tickSizeRaw = resolveTickSizeRaw(tickSize);
638
+ const remainder = originalPrice % tickSizeRaw;
639
+ if (remainder === BigInt(0)) {
640
+ return {
641
+ adjusted: false,
642
+ adjustedPriceRaw: originalPriceRaw,
643
+ originalPriceRaw,
644
+ tickSizeRaw: tickSizeRaw.toString()
645
+ };
646
+ }
647
+ const adjustedPrice = side === "buy" ? originalPrice - remainder : originalPrice + (tickSizeRaw - remainder);
648
+ return {
649
+ adjusted: true,
650
+ adjustedPriceRaw: adjustedPrice.toString(),
651
+ originalPriceRaw,
652
+ tickSizeRaw: tickSizeRaw.toString()
653
+ };
654
+ };
655
+
656
+ // ../common/src/utils/balance-refill.ts
657
+ var DEFAULT_BALANCE_REFILL_DAILY_CAP_RAW = "1002000000";
658
+ var DEFAULT_BALANCE_REFILL_MAX_FEE_RAW = "2000000";
659
+ var getBalanceRefillMaximumRaw = (dailyCapRaw, maxFeeRaw) => {
660
+ const dailyCap = BigInt(dailyCapRaw);
661
+ const maximumFee = BigInt(maxFeeRaw);
662
+ if (dailyCap <= maximumFee) return "0";
663
+ return (dailyCap - maximumFee).toString();
664
+ };
665
+ var isBalanceRefillWithinDailyCap = (minimumRaw, refillAmountRaw, dailyCapRaw, maxFeeRaw) => {
666
+ const maximum = BigInt(getBalanceRefillMaximumRaw(dailyCapRaw, maxFeeRaw));
667
+ return BigInt(minimumRaw) <= maximum && BigInt(refillAmountRaw) <= maximum;
668
+ };
669
+
592
670
  // src/errors.ts
593
671
  var TurnstileChallengeError = class extends Error {
594
672
  constructor(siteKey) {
@@ -1541,6 +1619,7 @@ var AggWebSocket = class {
1541
1619
  var COOKIE_REFRESH_DELIVERY = "cookie-refresh";
1542
1620
  var DEFAULT_MIDPOINT_IDS_PER_REQUEST = 75;
1543
1621
  var MAX_MIDPOINT_IDS_PER_REQUEST = 75;
1622
+ var MAX_SPORTS_EVENT_IDS_PER_REQUEST = 25;
1544
1623
  var isUserProfile = (user) => {
1545
1624
  return "accounts" in user && "wallets" in user && "avatarUrl" in user;
1546
1625
  };
@@ -2051,13 +2130,13 @@ Issued At: ${issuedAt}`;
2051
2130
  * the bearer automatically. Response shape:
2052
2131
  * - OAuth providers → `{ type: "redirect", url }`; redirect the browser to `url`.
2053
2132
  * - Email → `{ type: "magic_link", success: true }`; check the destination inbox.
2133
+ * - Wallet providers (siwe/siws) → `{ type: "wallet_challenge", message }`; have the
2134
+ * user sign `message` VERBATIM, then submit it to `linkAccountConfirm()` as
2135
+ * `{ kind: "wallet_signature", message, signature }`.
2054
2136
  *
2055
- * After the provider callback runs, the browser lands back on the app's `redirectUrl`
2137
+ * After the OAuth/email callback runs, the browser lands back on the app's `redirectUrl`
2056
2138
  * with a `link_confirm_token` query param. Feed that token to `linkAccountConfirm()`
2057
2139
  * to persist the Account row.
2058
- *
2059
- * Wallet linking (siwe/siws) is not supported yet — it requires a different message
2060
- * binding protocol than sign-in to be safe against signature phishing.
2061
2140
  */
2062
2141
  linkAccount(body) {
2063
2142
  return __async(this, null, function* () {
@@ -2072,18 +2151,27 @@ Issued At: ${issuedAt}`;
2072
2151
  });
2073
2152
  }
2074
2153
  /**
2075
- * Exchange a `link_confirm_token` for a linked `Account` row. The server matches
2076
- * the current bearer's `principalId` to the token's `principalId` before writing —
2077
- * this is the final ownership check.
2154
+ * Finalize an account link.
2155
+ *
2156
+ * - Pass a `link_confirm_token` string (OAuth/email) to exchange it for a linked
2157
+ * `Account` row.
2158
+ * - Pass `{ kind: "wallet_signature", message, signature }` (wallet providers) to
2159
+ * verify the signature over the `wallet_challenge` `message` returned by
2160
+ * `linkAccount()`.
2161
+ *
2162
+ * The server matches the current bearer's `principalId` to the challenge/token's
2163
+ * `principalId` before writing — this is the final ownership check. A wallet already
2164
+ * linked to a DIFFERENT principal rejects with HTTP 409.
2078
2165
  */
2079
- linkAccountConfirm(token) {
2166
+ linkAccountConfirm(input) {
2080
2167
  return __async(this, null, function* () {
2081
2168
  if (!this.accessToken) {
2082
2169
  yield this.refreshWithDedup();
2083
2170
  }
2171
+ const body = typeof input === "string" ? { token: input } : input;
2084
2172
  return this.request(
2085
2173
  "/users/me/link-account/confirm",
2086
- this.buildAuthRequestInit({ method: "POST", body: JSON.stringify({ token }) })
2174
+ this.buildAuthRequestInit({ method: "POST", body: JSON.stringify(body) })
2087
2175
  );
2088
2176
  });
2089
2177
  }
@@ -2254,7 +2342,9 @@ Issued At: ${issuedAt}`;
2254
2342
  const query = {};
2255
2343
  if (params.orderId) query.orderId = params.orderId;
2256
2344
  if (params.quoteId) query.quoteId = params.quoteId;
2345
+ if (params.externalId) query.externalId = params.externalId;
2257
2346
  if (params.status) query.status = params.status;
2347
+ if (params.orderType) query.orderType = params.orderType;
2258
2348
  if (params.mode) query.mode = params.mode;
2259
2349
  if (params.cursor) query.cursor = params.cursor;
2260
2350
  if (params.limit != null) query.limit = String(params.limit);
@@ -2455,6 +2545,7 @@ Issued At: ${issuedAt}`;
2455
2545
  if ((options == null ? void 0 : options.status) && options.status.length > 0) query.status = options.status;
2456
2546
  if (options == null ? void 0 : options.sortBy) query.sortBy = options.sortBy;
2457
2547
  if (options == null ? void 0 : options.sortDir) query.sortDir = options.sortDir;
2548
+ if (options == null ? void 0 : options.aggKey) query.aggKey = options.aggKey;
2458
2549
  if (options == null ? void 0 : options.recurrence) query.recurrence = options.recurrence;
2459
2550
  if ((options == null ? void 0 : options.limit) != null) query.limit = String(options.limit);
2460
2551
  if (options == null ? void 0 : options.cursor) query.cursor = options.cursor;
@@ -2463,7 +2554,8 @@ Issued At: ${issuedAt}`;
2463
2554
  if (options == null ? void 0 : options.endDateFrom) query.endDateFrom = options.endDateFrom;
2464
2555
  if (options == null ? void 0 : options.grouped) query.grouped = "true";
2465
2556
  return this.request("/venue-events", {
2466
- query: Object.keys(query).length > 0 ? query : void 0
2557
+ query: Object.keys(query).length > 0 ? query : void 0,
2558
+ signal: options == null ? void 0 : options.signal
2467
2559
  });
2468
2560
  });
2469
2561
  }
@@ -2479,6 +2571,27 @@ Issued At: ${issuedAt}`;
2479
2571
  });
2480
2572
  });
2481
2573
  }
2574
+ /** Get normalized live score state for sports events. Requires appId or admin auth. */
2575
+ getSportsLive(eventIds, options) {
2576
+ return __async(this, null, function* () {
2577
+ const normalizedEventIds = normalizeRequestedVenueMarketIds(eventIds);
2578
+ if (normalizedEventIds.length === 0) {
2579
+ return { data: [], missingEventIds: [] };
2580
+ }
2581
+ const responses = yield Promise.all(
2582
+ chunkArray(normalizedEventIds, MAX_SPORTS_EVENT_IDS_PER_REQUEST).map(
2583
+ (eventIdChunk) => this.request("/sports/live", {
2584
+ query: { eventIds: eventIdChunk },
2585
+ signal: options == null ? void 0 : options.signal
2586
+ })
2587
+ )
2588
+ );
2589
+ return {
2590
+ data: responses.flatMap((response) => response.data),
2591
+ missingEventIds: [...new Set(responses.flatMap((response) => response.missingEventIds))]
2592
+ };
2593
+ });
2594
+ }
2482
2595
  /** List deterministic recurring crypto window markets across venues. Requires appId or admin auth. */
2483
2596
  listRecurringCryptoMarkets(options) {
2484
2597
  return __async(this, null, function* () {
@@ -2919,6 +3032,20 @@ Issued At: ${issuedAt}`;
2919
3032
  });
2920
3033
  });
2921
3034
  }
3035
+ /**
3036
+ * Place a market order directly on a named venue — no prior quote needed.
3037
+ * Always produces exactly one order. `externalId` is required and unique
3038
+ * within your app — two different users of the same app cannot share one —
3039
+ * so retrying a timed-out call with the same value is safe.
3040
+ */
3041
+ placeOrder(params) {
3042
+ return __async(this, null, function* () {
3043
+ return this.request("/execution/orders", {
3044
+ method: "POST",
3045
+ body: JSON.stringify(params)
3046
+ });
3047
+ });
3048
+ }
2922
3049
  /** Redeem resolved winning positions by venue market outcome ids. */
2923
3050
  redeem(body) {
2924
3051
  return __async(this, null, function* () {
@@ -3294,9 +3421,12 @@ export {
3294
3421
  CONFIRMED_MATCH_STATUSES,
3295
3422
  CandleBuilder,
3296
3423
  Chain,
3424
+ DEFAULT_BALANCE_REFILL_DAILY_CAP_RAW,
3425
+ DEFAULT_BALANCE_REFILL_MAX_FEE_RAW,
3297
3426
  IMAGE_SIZES,
3298
3427
  INACTIVE_VENUES,
3299
3428
  ImageSize,
3429
+ LIMIT_PRICE_RAW_SCALE,
3300
3430
  MarketStatus,
3301
3431
  MatchStatus,
3302
3432
  MatchType,
@@ -3307,7 +3437,9 @@ export {
3307
3437
  TradeSide,
3308
3438
  TurnstileChallengeError,
3309
3439
  VENUES,
3440
+ VENUE_CHAIN_IDS,
3310
3441
  Venue,
3442
+ adjustLimitPriceRawToTick,
3311
3443
  aggregateMidpoint,
3312
3444
  applyOrderbookDelta,
3313
3445
  buildVenueUrl,
@@ -3318,10 +3450,12 @@ export {
3318
3450
  formatMarketQuestion,
3319
3451
  formatOutcomeLabel,
3320
3452
  formatOutcomeTitle,
3453
+ getBalanceRefillMaximumRaw,
3321
3454
  getEffectiveDisabledVenues,
3322
3455
  getWalletAddressFromUserProfile,
3323
3456
  hasShape,
3324
3457
  isAggApiError,
3458
+ isBalanceRefillWithinDailyCap,
3325
3459
  isEmail,
3326
3460
  isEnum,
3327
3461
  isFiniteNonNeg,
package/dist/server.d.mts CHANGED
@@ -59,6 +59,8 @@ interface TradesPlacedEvent extends WebhookEventBase {
59
59
  userId: string;
60
60
  side: string;
61
61
  timestamp: string;
62
+ /** Your trade id from `POST /execution/orders`, or `null` if the trade did not carry one. */
63
+ externalId: string | null;
62
64
  /**
63
65
  * @deprecated Never emitted by the server in 1.x — the SDK type lied
64
66
  * here for several releases. Reads always return `undefined`. The field
@@ -77,6 +79,8 @@ interface TradesFilledEvent extends WebhookEventBase {
77
79
  userId: string;
78
80
  status: string;
79
81
  timestamp: string;
82
+ /** Your trade id from `POST /execution/orders`, or `null` if the trade did not carry one. */
83
+ externalId: string | null;
80
84
  /**
81
85
  * Post-execution accuracy data. All `*Raw` values are decimal strings in
82
86
  * 6-decimal atomic units. `*PriceRaw` are decimal strings (e.g. "0.5").
package/dist/server.d.ts CHANGED
@@ -59,6 +59,8 @@ interface TradesPlacedEvent extends WebhookEventBase {
59
59
  userId: string;
60
60
  side: string;
61
61
  timestamp: string;
62
+ /** Your trade id from `POST /execution/orders`, or `null` if the trade did not carry one. */
63
+ externalId: string | null;
62
64
  /**
63
65
  * @deprecated Never emitted by the server in 1.x — the SDK type lied
64
66
  * here for several releases. Reads always return `undefined`. The field
@@ -77,6 +79,8 @@ interface TradesFilledEvent extends WebhookEventBase {
77
79
  userId: string;
78
80
  status: string;
79
81
  timestamp: string;
82
+ /** Your trade id from `POST /execution/orders`, or `null` if the trade did not carry one. */
83
+ externalId: string | null;
80
84
  /**
81
85
  * Post-execution accuracy data. All `*Raw` values are decimal strings in
82
86
  * 6-decimal atomic units. `*PriceRaw` are decimal strings (e.g. "0.5").
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/sdk",
3
- "version": "4.1.0",
3
+ "version": "4.5.0",
4
4
  "description": "Vanilla TypeScript client for the AGG prediction market aggregator (auth, markets, orderbooks, charts, trading, managed execution, WebSockets). Works in browsers, Node.js, and React Native.",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",