@agg-build/sdk 1.2.11 → 1.3.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.mjs CHANGED
@@ -727,7 +727,14 @@ var AggWebSocket = class {
727
727
  this.pendingFlushUnsubs = /* @__PURE__ */ new Set();
728
728
  this.pendingFlushTradeSubs = /* @__PURE__ */ new Set();
729
729
  this.pendingFlushTradeUnsubs = /* @__PURE__ */ new Set();
730
+ this.pendingFlushArbSubs = /* @__PURE__ */ new Set();
731
+ this.pendingFlushArbUnsubs = /* @__PURE__ */ new Set();
730
732
  this.flushScheduled = false;
733
+ // ── Arb subscriptions ──
734
+ this.arbSubs = /* @__PURE__ */ new Map();
735
+ this.arbFeedCbs = /* @__PURE__ */ new Set();
736
+ /** Latest arb market update per marketId (last-value-wins, loss-tolerant). */
737
+ this.latestArb = /* @__PURE__ */ new Map();
731
738
  // ── Orderbook state per market ──
732
739
  this.books = /* @__PURE__ */ new Map();
733
740
  /** Markets currently resyncing (awaiting snapshot after seq gap / checksum mismatch). */
@@ -759,6 +766,69 @@ var AggWebSocket = class {
759
766
  isResyncing(outcomeId) {
760
767
  return this.resyncing.has(outcomeId);
761
768
  }
769
+ /** Get the latest arb update for a market (or null if none received yet). */
770
+ getArb(marketId) {
771
+ var _a;
772
+ return (_a = this.latestArb.get(marketId)) != null ? _a : null;
773
+ }
774
+ /**
775
+ * Subscribe to per-market arb updates for a given marketId.
776
+ * Ref-counted: multiple callers for the same marketId share one server subscription.
777
+ * Returns an unsubscribe function.
778
+ */
779
+ subscribeArb(marketId, cb) {
780
+ let entry = this.arbSubs.get(marketId);
781
+ if (!entry) {
782
+ entry = { refCount: 0, cbs: /* @__PURE__ */ new Set() };
783
+ this.arbSubs.set(marketId, entry);
784
+ this.ensureConnected();
785
+ if (this._connected) {
786
+ this.pendingFlushArbUnsubs.delete(marketId);
787
+ this.pendingFlushArbSubs.add(marketId);
788
+ this.scheduleFlush();
789
+ }
790
+ }
791
+ entry.cbs.add(cb);
792
+ entry.refCount++;
793
+ return () => {
794
+ const e = this.arbSubs.get(marketId);
795
+ if (!e) return;
796
+ e.cbs.delete(cb);
797
+ e.refCount--;
798
+ if (e.refCount <= 0) {
799
+ this.arbSubs.delete(marketId);
800
+ if (this._connected) {
801
+ if (this.pendingFlushArbSubs.has(marketId)) {
802
+ this.pendingFlushArbSubs.delete(marketId);
803
+ } else {
804
+ this.pendingFlushArbUnsubs.add(marketId);
805
+ this.scheduleFlush();
806
+ }
807
+ }
808
+ }
809
+ };
810
+ }
811
+ /**
812
+ * Subscribe to the global arb-feed batches.
813
+ * Only one server subscription is maintained regardless of how many callers.
814
+ * Returns an unsubscribe function.
815
+ */
816
+ subscribeArbFeed(cb) {
817
+ const wasEmpty = this.arbFeedCbs.size === 0;
818
+ this.arbFeedCbs.add(cb);
819
+ if (wasEmpty) {
820
+ this.ensureConnected();
821
+ if (this._connected) {
822
+ this.send({ action: "subscribe", channel: "arb-feed" });
823
+ }
824
+ }
825
+ return () => {
826
+ this.arbFeedCbs.delete(cb);
827
+ if (this.arbFeedCbs.size === 0 && this._connected) {
828
+ this.send({ action: "unsubscribe", channel: "arb-feed" });
829
+ }
830
+ };
831
+ }
762
832
  /**
763
833
  * Subscribe to a feed by outcome ID.
764
834
  * @param outcomeId The venueMarketOutcomeId to subscribe to.
@@ -896,6 +966,11 @@ var AggWebSocket = class {
896
966
  this.pendingFlushUnsubs.clear();
897
967
  this.pendingFlushTradeSubs.clear();
898
968
  this.pendingFlushTradeUnsubs.clear();
969
+ this.arbSubs.clear();
970
+ this.arbFeedCbs.clear();
971
+ this.latestArb.clear();
972
+ this.pendingFlushArbSubs.clear();
973
+ this.pendingFlushArbUnsubs.clear();
899
974
  this.flushScheduled = false;
900
975
  }
901
976
  /** Update callbacks (e.g., after React re-render). */
@@ -941,7 +1016,7 @@ var AggWebSocket = class {
941
1016
  if (wasConnected) {
942
1017
  (_b = (_a = this.callbacks).onConnectionStateChange) == null ? void 0 : _b.call(_a, false);
943
1018
  }
944
- if (!this.destroyed && this.subs.size > 0) {
1019
+ if (!this.destroyed && (this.subs.size > 0 || this.arbSubs.size > 0 || this.arbFeedCbs.size > 0)) {
945
1020
  this.scheduleReconnect();
946
1021
  }
947
1022
  };
@@ -986,7 +1061,7 @@ var AggWebSocket = class {
986
1061
  }
987
1062
  // ── Message handling ──
988
1063
  handleMessage(raw) {
989
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1064
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
990
1065
  const type = raw.type;
991
1066
  switch (type) {
992
1067
  case "orderbook_snapshot":
@@ -1034,6 +1109,22 @@ var AggWebSocket = class {
1034
1109
  case "withdrawal_lifecycle":
1035
1110
  (_l = (_k = this.callbacks).onWithdrawalLifecycle) == null ? void 0 : _l.call(_k, raw);
1036
1111
  break;
1112
+ case "arb_market_update": {
1113
+ const arbMsg = raw;
1114
+ this.latestArb.set(arbMsg.marketId, arbMsg);
1115
+ const arbEntry = this.arbSubs.get(arbMsg.marketId);
1116
+ if (arbEntry) {
1117
+ for (const cb of arbEntry.cbs) cb(arbMsg);
1118
+ }
1119
+ (_n = (_m = this.callbacks).onArbMarket) == null ? void 0 : _n.call(_m, arbMsg);
1120
+ break;
1121
+ }
1122
+ case "arb_feed_batch": {
1123
+ const feedMsg = raw;
1124
+ for (const cb of this.arbFeedCbs) cb(feedMsg);
1125
+ (_p = (_o = this.callbacks).onArbFeed) == null ? void 0 : _p.call(_o, feedMsg);
1126
+ break;
1127
+ }
1037
1128
  }
1038
1129
  }
1039
1130
  /**
@@ -1070,6 +1161,17 @@ var AggWebSocket = class {
1070
1161
  this.send({ action: "resnapshot", channel: "orderbook", outcomeIds: resnapshotIds });
1071
1162
  }
1072
1163
  this.pendingResnapshots.clear();
1164
+ const arbSet = new Set(this.activeArbMarkets());
1165
+ this.pendingFlushArbSubs.forEach((id) => arbSet.add(id));
1166
+ const arbIds = Array.from(arbSet);
1167
+ if (arbIds.length > 0) {
1168
+ this.send({ action: "subscribe", channel: "arb", marketIds: arbIds });
1169
+ }
1170
+ this.pendingFlushArbSubs.clear();
1171
+ this.pendingFlushArbUnsubs.clear();
1172
+ if (this.arbFeedCbs.size > 0) {
1173
+ this.send({ action: "subscribe", channel: "arb-feed" });
1174
+ }
1073
1175
  }
1074
1176
  handleSnapshot(raw) {
1075
1177
  var _a, _b;
@@ -1241,6 +1343,8 @@ var AggWebSocket = class {
1241
1343
  this.pendingFlushUnsubs.clear();
1242
1344
  this.pendingFlushTradeSubs.clear();
1243
1345
  this.pendingFlushTradeUnsubs.clear();
1346
+ this.pendingFlushArbSubs.clear();
1347
+ this.pendingFlushArbUnsubs.clear();
1244
1348
  return;
1245
1349
  }
1246
1350
  this.flushPending();
@@ -1287,6 +1391,28 @@ var AggWebSocket = class {
1287
1391
  });
1288
1392
  this.pendingFlushTradeUnsubs.clear();
1289
1393
  }
1394
+ for (const id of [...this.pendingFlushArbSubs]) {
1395
+ if (this.pendingFlushArbUnsubs.has(id)) {
1396
+ this.pendingFlushArbSubs.delete(id);
1397
+ this.pendingFlushArbUnsubs.delete(id);
1398
+ }
1399
+ }
1400
+ if (this.pendingFlushArbSubs.size > 0) {
1401
+ this.send({
1402
+ action: "subscribe",
1403
+ channel: "arb",
1404
+ marketIds: Array.from(this.pendingFlushArbSubs)
1405
+ });
1406
+ this.pendingFlushArbSubs.clear();
1407
+ }
1408
+ if (this.pendingFlushArbUnsubs.size > 0) {
1409
+ this.send({
1410
+ action: "unsubscribe",
1411
+ channel: "arb",
1412
+ marketIds: Array.from(this.pendingFlushArbUnsubs)
1413
+ });
1414
+ this.pendingFlushArbUnsubs.clear();
1415
+ }
1290
1416
  }
1291
1417
  sendSubscribe(outcomeIds) {
1292
1418
  this.send({ action: "subscribe", channel: "orderbook", outcomeIds });
@@ -1311,6 +1437,9 @@ var AggWebSocket = class {
1311
1437
  });
1312
1438
  return markets;
1313
1439
  }
1440
+ activeArbMarkets() {
1441
+ return Array.from(this.arbSubs.keys());
1442
+ }
1314
1443
  emitDiagnostic(event) {
1315
1444
  var _a, _b;
1316
1445
  (_b = (_a = this.callbacks).onDiagnostics) == null ? void 0 : _b.call(_a, event);
@@ -1992,6 +2121,7 @@ Issued At: ${issuedAt}`;
1992
2121
  if (params.orderId) query.orderId = params.orderId;
1993
2122
  if (params.quoteId) query.quoteId = params.quoteId;
1994
2123
  if (params.status) query.status = params.status;
2124
+ if (params.mode) query.mode = params.mode;
1995
2125
  if (params.cursor) query.cursor = params.cursor;
1996
2126
  if (params.limit != null) query.limit = String(params.limit);
1997
2127
  return this.request("/execution/orders", {
@@ -2018,6 +2148,7 @@ Issued At: ${issuedAt}`;
2018
2148
  if (params.cursor) query.cursor = params.cursor;
2019
2149
  if (params.limit != null) query.limit = String(params.limit);
2020
2150
  if (params.status) query.status = params.status;
2151
+ if (params.mode) query.mode = params.mode;
2021
2152
  return this.request("/execution/positions", {
2022
2153
  query: Object.keys(query).length ? query : void 0
2023
2154
  });
@@ -2025,8 +2156,12 @@ Issued At: ${issuedAt}`;
2025
2156
  }
2026
2157
  /** Get managed wallet balances, including per-chain cash balances and per-venue position balances. */
2027
2158
  getManagedBalances() {
2028
- return __async(this, null, function* () {
2029
- return this.request("/execution/balances");
2159
+ return __async(this, arguments, function* (params = {}) {
2160
+ const query = {};
2161
+ if (params.mode) query.mode = params.mode;
2162
+ return this.request("/execution/balances", {
2163
+ query: Object.keys(query).length ? query : void 0
2164
+ });
2030
2165
  });
2031
2166
  }
2032
2167
  /** Cancel a pending managed execution by order id. */
@@ -2057,6 +2192,7 @@ Issued At: ${issuedAt}`;
2057
2192
  if ((options == null ? void 0 : options.status) && options.status.length > 0) query.status = options.status;
2058
2193
  if (options == null ? void 0 : options.sortBy) query.sortBy = options.sortBy;
2059
2194
  if (options == null ? void 0 : options.sortDir) query.sortDir = options.sortDir;
2195
+ if (options == null ? void 0 : options.recurrence) query.recurrence = options.recurrence;
2060
2196
  if ((options == null ? void 0 : options.limit) != null) query.limit = String(options.limit);
2061
2197
  if (options == null ? void 0 : options.cursor) query.cursor = options.cursor;
2062
2198
  if ((options == null ? void 0 : options.minYesPrice) != null) query.minYesPrice = String(options.minYesPrice);
@@ -2102,6 +2238,7 @@ Issued At: ${issuedAt}`;
2102
2238
  const query = {};
2103
2239
  if ((options == null ? void 0 : options.limit) != null) query.limit = String(options.limit);
2104
2240
  if (options == null ? void 0 : options.cursor) query.cursor = options.cursor;
2241
+ if (options == null ? void 0 : options.parentId) query.parentId = options.parentId;
2105
2242
  return this.request("/categories", {
2106
2243
  query: Object.keys(query).length > 0 ? query : void 0
2107
2244
  });
@@ -2259,7 +2396,7 @@ Issued At: ${issuedAt}`;
2259
2396
  */
2260
2397
  getSmartRoute(params, options) {
2261
2398
  return __async(this, null, function* () {
2262
- var _a, _b;
2399
+ var _a, _b, _c;
2263
2400
  const venueMarketOutcomeId = (_b = (_a = params.venueMarketOutcomeId) != null ? _a : params.venueMarketId) != null ? _b : params.outcomeId;
2264
2401
  if (!venueMarketOutcomeId) {
2265
2402
  throw new Error("getSmartRoute requires venueMarketOutcomeId");
@@ -2270,7 +2407,9 @@ Issued At: ${issuedAt}`;
2270
2407
  if (params.chainBalances) query.chainBalances = JSON.stringify(params.chainBalances);
2271
2408
  if (params.slipCapBps != null) query.slipCapBps = String(params.slipCapBps);
2272
2409
  if (params.compareVenues) query.compareVenues = "true";
2410
+ if ((_c = params.allowedVenues) == null ? void 0 : _c.length) query.allowedVenues = params.allowedVenues.map(String);
2273
2411
  if (params.tradeSide) query.side = params.tradeSide;
2412
+ if (params.mode) query.mode = params.mode;
2274
2413
  if (params.deepEstimate) query.deepEstimate = "true";
2275
2414
  const response = yield this.request(
2276
2415
  `/orderbook/${encodeURIComponent(venueMarketOutcomeId)}/route`,
@@ -2372,6 +2511,7 @@ Issued At: ${issuedAt}`;
2372
2511
  if (params == null ? void 0 : params.cursor) query.cursor = params.cursor;
2373
2512
  if ((params == null ? void 0 : params.limit) != null) query.limit = String(params.limit);
2374
2513
  if (params == null ? void 0 : params.status) query.status = params.status;
2514
+ if (params == null ? void 0 : params.mode) query.mode = params.mode;
2375
2515
  return this.request("/execution/positions", {
2376
2516
  query: Object.keys(query).length > 0 ? query : void 0
2377
2517
  });
package/dist/server.d.mts CHANGED
@@ -12,6 +12,16 @@ interface VerifyWebhookOptions {
12
12
  }
13
13
  declare function verifyWebhook(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): void;
14
14
  declare function parseWebhookEvent(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): WebhookEvent;
15
+ /**
16
+ * Async, edge-runtime-friendly variant of {@link verifyWebhook}. Same
17
+ * Svix v1 signing scheme. Use this in Cloudflare Workers / Vercel Edge /
18
+ * Deno / Bun. The sync variant remains available for Node.js consumers.
19
+ */
20
+ declare function verifyWebhookAsync(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): Promise<void>;
21
+ /**
22
+ * Async, edge-runtime-friendly variant of {@link parseWebhookEvent}.
23
+ */
24
+ declare function parseWebhookEventAsync(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): Promise<WebhookEvent>;
15
25
  interface WebhookEventBase {
16
26
  id: string;
17
27
  createdAt: string;
@@ -21,6 +31,8 @@ interface AccountsCreatedEvent extends WebhookEventBase {
21
31
  data: {
22
32
  userId: string;
23
33
  appId: string;
34
+ createdAt: string;
35
+ email: string | null;
24
36
  };
25
37
  }
26
38
  interface AccountsLinkedEvent extends WebhookEventBase {
@@ -37,6 +49,7 @@ interface WalletsReadyEvent extends WebhookEventBase {
37
49
  userId: string;
38
50
  evmAddress: string;
39
51
  svmAddress: string;
52
+ createdAt: string;
40
53
  };
41
54
  }
42
55
  interface TradesPlacedEvent extends WebhookEventBase {
@@ -45,8 +58,16 @@ interface TradesPlacedEvent extends WebhookEventBase {
45
58
  orderId: string;
46
59
  userId: string;
47
60
  side: string;
48
- venue: string;
49
- venueMarketId: string;
61
+ timestamp: string;
62
+ /**
63
+ * @deprecated Never emitted by the server in 1.x — the SDK type lied
64
+ * here for several releases. Reads always return `undefined`. The field
65
+ * is retained as `undefined`-typed for one minor release so existing
66
+ * partner code that destructures it keeps compiling; remove in 2.0.
67
+ */
68
+ venue?: undefined;
69
+ /** @deprecated See `venue`. */
70
+ venueMarketId?: undefined;
50
71
  };
51
72
  }
52
73
  interface TradesFilledEvent extends WebhookEventBase {
@@ -55,16 +76,49 @@ interface TradesFilledEvent extends WebhookEventBase {
55
76
  orderId: string;
56
77
  userId: string;
57
78
  status: string;
58
- fillPrice: number;
59
- fillSize: number;
79
+ timestamp: string;
80
+ /**
81
+ * Post-execution accuracy data. All `*Raw` values are decimal strings in
82
+ * 6-decimal atomic units. `*PriceRaw` are decimal strings (e.g. "0.5").
83
+ * `partialFillReason` is set only on `status === "partial_fill"`.
84
+ */
85
+ filledAmountRaw?: string;
86
+ quotedSharesRaw?: string;
87
+ actualSharesRaw?: string;
88
+ quotedToWinRaw?: string;
89
+ actualToWinRaw?: string;
90
+ quotedPriceRaw?: string;
91
+ executionPriceRaw?: string;
92
+ partialFillReason?: string;
93
+ /** @deprecated See `executionPriceRaw` — never emitted; remove in 2.0. */
94
+ fillPrice?: undefined;
95
+ /** @deprecated See `actualSharesRaw` / `filledAmountRaw` — never emitted; remove in 2.0. */
96
+ fillSize?: undefined;
60
97
  };
61
98
  }
62
99
  interface MarketsResolvedEvent extends WebhookEventBase {
63
100
  type: "markets.resolved";
64
101
  data: {
65
102
  venueMarketId: string;
66
- outcome: string;
103
+ externalIdentifier: string;
104
+ status: string;
105
+ outcomes: Array<{
106
+ label: string;
107
+ winner?: boolean;
108
+ externalIdentifier?: string;
109
+ }>;
67
110
  affectedUsersCount: number;
111
+ /**
112
+ * Path on the AGG API where this resolution's affected users can be
113
+ * paginated. Combine with the configured base URL — e.g.
114
+ * `https://api.agg.market${detailsPath}`.
115
+ */
116
+ detailsPath: string;
117
+ /**
118
+ * @deprecated Singular `outcome` was never emitted; use `outcomes` array.
119
+ * Remove in 2.0.
120
+ */
121
+ outcome?: undefined;
68
122
  };
69
123
  }
70
124
  interface UnknownWebhookEvent extends WebhookEventBase {
@@ -118,7 +172,9 @@ declare class AggAdminClient {
118
172
  ordersByStatus: Record<string, number>;
119
173
  ordersByVenue: Record<string, number>;
120
174
  usersLast30Days: number;
175
+ usersLast7Days: number;
121
176
  ordersLast30Days: number;
177
+ ordersLast7Days: number;
122
178
  }>;
123
179
  listOrders(appId: string, query?: {
124
180
  limit?: number;
@@ -152,4 +208,4 @@ declare class AggAdminClient {
152
208
  }>;
153
209
  }
154
210
 
155
- export { type AccountsCreatedEvent, type AccountsLinkedEvent, AggAdminClient, type AggAdminClientOptions, type ExternalIdAssertion, type KnownWebhookEvent, type MarketsResolvedEvent, type TradesFilledEvent, type TradesPlacedEvent, type UnknownWebhookEvent, type VerifyWebhookOptions, type WalletsReadyEvent, type WebhookEvent, WebhookVerificationError, parseWebhookEvent, signExternalId, verifyWebhook };
211
+ export { type AccountsCreatedEvent, type AccountsLinkedEvent, AggAdminClient, type AggAdminClientOptions, type ExternalIdAssertion, type KnownWebhookEvent, type MarketsResolvedEvent, type TradesFilledEvent, type TradesPlacedEvent, type UnknownWebhookEvent, type VerifyWebhookOptions, type WalletsReadyEvent, type WebhookEvent, WebhookVerificationError, parseWebhookEvent, parseWebhookEventAsync, signExternalId, verifyWebhook, verifyWebhookAsync };
package/dist/server.d.ts CHANGED
@@ -12,6 +12,16 @@ interface VerifyWebhookOptions {
12
12
  }
13
13
  declare function verifyWebhook(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): void;
14
14
  declare function parseWebhookEvent(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): WebhookEvent;
15
+ /**
16
+ * Async, edge-runtime-friendly variant of {@link verifyWebhook}. Same
17
+ * Svix v1 signing scheme. Use this in Cloudflare Workers / Vercel Edge /
18
+ * Deno / Bun. The sync variant remains available for Node.js consumers.
19
+ */
20
+ declare function verifyWebhookAsync(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): Promise<void>;
21
+ /**
22
+ * Async, edge-runtime-friendly variant of {@link parseWebhookEvent}.
23
+ */
24
+ declare function parseWebhookEventAsync(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): Promise<WebhookEvent>;
15
25
  interface WebhookEventBase {
16
26
  id: string;
17
27
  createdAt: string;
@@ -21,6 +31,8 @@ interface AccountsCreatedEvent extends WebhookEventBase {
21
31
  data: {
22
32
  userId: string;
23
33
  appId: string;
34
+ createdAt: string;
35
+ email: string | null;
24
36
  };
25
37
  }
26
38
  interface AccountsLinkedEvent extends WebhookEventBase {
@@ -37,6 +49,7 @@ interface WalletsReadyEvent extends WebhookEventBase {
37
49
  userId: string;
38
50
  evmAddress: string;
39
51
  svmAddress: string;
52
+ createdAt: string;
40
53
  };
41
54
  }
42
55
  interface TradesPlacedEvent extends WebhookEventBase {
@@ -45,8 +58,16 @@ interface TradesPlacedEvent extends WebhookEventBase {
45
58
  orderId: string;
46
59
  userId: string;
47
60
  side: string;
48
- venue: string;
49
- venueMarketId: string;
61
+ timestamp: string;
62
+ /**
63
+ * @deprecated Never emitted by the server in 1.x — the SDK type lied
64
+ * here for several releases. Reads always return `undefined`. The field
65
+ * is retained as `undefined`-typed for one minor release so existing
66
+ * partner code that destructures it keeps compiling; remove in 2.0.
67
+ */
68
+ venue?: undefined;
69
+ /** @deprecated See `venue`. */
70
+ venueMarketId?: undefined;
50
71
  };
51
72
  }
52
73
  interface TradesFilledEvent extends WebhookEventBase {
@@ -55,16 +76,49 @@ interface TradesFilledEvent extends WebhookEventBase {
55
76
  orderId: string;
56
77
  userId: string;
57
78
  status: string;
58
- fillPrice: number;
59
- fillSize: number;
79
+ timestamp: string;
80
+ /**
81
+ * Post-execution accuracy data. All `*Raw` values are decimal strings in
82
+ * 6-decimal atomic units. `*PriceRaw` are decimal strings (e.g. "0.5").
83
+ * `partialFillReason` is set only on `status === "partial_fill"`.
84
+ */
85
+ filledAmountRaw?: string;
86
+ quotedSharesRaw?: string;
87
+ actualSharesRaw?: string;
88
+ quotedToWinRaw?: string;
89
+ actualToWinRaw?: string;
90
+ quotedPriceRaw?: string;
91
+ executionPriceRaw?: string;
92
+ partialFillReason?: string;
93
+ /** @deprecated See `executionPriceRaw` — never emitted; remove in 2.0. */
94
+ fillPrice?: undefined;
95
+ /** @deprecated See `actualSharesRaw` / `filledAmountRaw` — never emitted; remove in 2.0. */
96
+ fillSize?: undefined;
60
97
  };
61
98
  }
62
99
  interface MarketsResolvedEvent extends WebhookEventBase {
63
100
  type: "markets.resolved";
64
101
  data: {
65
102
  venueMarketId: string;
66
- outcome: string;
103
+ externalIdentifier: string;
104
+ status: string;
105
+ outcomes: Array<{
106
+ label: string;
107
+ winner?: boolean;
108
+ externalIdentifier?: string;
109
+ }>;
67
110
  affectedUsersCount: number;
111
+ /**
112
+ * Path on the AGG API where this resolution's affected users can be
113
+ * paginated. Combine with the configured base URL — e.g.
114
+ * `https://api.agg.market${detailsPath}`.
115
+ */
116
+ detailsPath: string;
117
+ /**
118
+ * @deprecated Singular `outcome` was never emitted; use `outcomes` array.
119
+ * Remove in 2.0.
120
+ */
121
+ outcome?: undefined;
68
122
  };
69
123
  }
70
124
  interface UnknownWebhookEvent extends WebhookEventBase {
@@ -118,7 +172,9 @@ declare class AggAdminClient {
118
172
  ordersByStatus: Record<string, number>;
119
173
  ordersByVenue: Record<string, number>;
120
174
  usersLast30Days: number;
175
+ usersLast7Days: number;
121
176
  ordersLast30Days: number;
177
+ ordersLast7Days: number;
122
178
  }>;
123
179
  listOrders(appId: string, query?: {
124
180
  limit?: number;
@@ -152,4 +208,4 @@ declare class AggAdminClient {
152
208
  }>;
153
209
  }
154
210
 
155
- export { type AccountsCreatedEvent, type AccountsLinkedEvent, AggAdminClient, type AggAdminClientOptions, type ExternalIdAssertion, type KnownWebhookEvent, type MarketsResolvedEvent, type TradesFilledEvent, type TradesPlacedEvent, type UnknownWebhookEvent, type VerifyWebhookOptions, type WalletsReadyEvent, type WebhookEvent, WebhookVerificationError, parseWebhookEvent, signExternalId, verifyWebhook };
211
+ export { type AccountsCreatedEvent, type AccountsLinkedEvent, AggAdminClient, type AggAdminClientOptions, type ExternalIdAssertion, type KnownWebhookEvent, type MarketsResolvedEvent, type TradesFilledEvent, type TradesPlacedEvent, type UnknownWebhookEvent, type VerifyWebhookOptions, type WalletsReadyEvent, type WebhookEvent, WebhookVerificationError, parseWebhookEvent, parseWebhookEventAsync, signExternalId, verifyWebhook, verifyWebhookAsync };
package/dist/server.js CHANGED
@@ -60,8 +60,10 @@ __export(server_exports, {
60
60
  AggAdminClient: () => AggAdminClient,
61
61
  WebhookVerificationError: () => WebhookVerificationError,
62
62
  parseWebhookEvent: () => parseWebhookEvent,
63
+ parseWebhookEventAsync: () => parseWebhookEventAsync,
63
64
  signExternalId: () => signExternalId,
64
- verifyWebhook: () => verifyWebhook
65
+ verifyWebhook: () => verifyWebhook,
66
+ verifyWebhookAsync: () => verifyWebhookAsync
65
67
  });
66
68
  module.exports = __toCommonJS(server_exports);
67
69
  var import_node_crypto = require("crypto");
@@ -74,6 +76,22 @@ function signExternalId(appSecret, externalId) {
74
76
  hmac
75
77
  };
76
78
  }
79
+ var textEncoder = new TextEncoder();
80
+ function base64Decode(s) {
81
+ const bin = atob(s);
82
+ const out = new Uint8Array(bin.length);
83
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
84
+ return out;
85
+ }
86
+ function importHmacKey(secret) {
87
+ return __async(this, null, function* () {
88
+ const keyBytes = base64Decode(secret.replace(/^whsec_/, ""));
89
+ return crypto.subtle.importKey("raw", keyBytes, { name: "HMAC", hash: "SHA-256" }, false, [
90
+ "sign",
91
+ "verify"
92
+ ]);
93
+ });
94
+ }
77
95
  var WebhookVerificationError = class extends Error {
78
96
  constructor(message) {
79
97
  super(message);
@@ -113,6 +131,45 @@ function parseWebhookEvent(payload, headers, secret, options) {
113
131
  const parsed = JSON.parse(payload);
114
132
  return parsed;
115
133
  }
134
+ function verifyWebhookAsync(payload, headers, secret, options) {
135
+ return __async(this, null, function* () {
136
+ var _a;
137
+ const tolerance = (_a = options == null ? void 0 : options.toleranceSeconds) != null ? _a : 300;
138
+ const msgId = getHeader(headers, "webhook-id");
139
+ const timestamp = getHeader(headers, "webhook-timestamp");
140
+ const signatures = getHeader(headers, "webhook-signature");
141
+ if (!msgId) throw new WebhookVerificationError("Missing Webhook-Id header");
142
+ if (!timestamp) throw new WebhookVerificationError("Missing Webhook-Timestamp header");
143
+ if (!signatures) throw new WebhookVerificationError("Missing Webhook-Signature header");
144
+ const ts = parseInt(timestamp, 10);
145
+ if (isNaN(ts)) throw new WebhookVerificationError("Invalid Webhook-Timestamp");
146
+ const now = Math.floor(Date.now() / 1e3);
147
+ if (Math.abs(now - ts) > tolerance) {
148
+ throw new WebhookVerificationError("Webhook timestamp outside tolerance window");
149
+ }
150
+ const key = yield importHmacKey(secret);
151
+ const signed = textEncoder.encode(`${msgId}.${timestamp}.${payload}`);
152
+ for (const sig of signatures.split(" ")) {
153
+ if (!sig.startsWith("v1,")) continue;
154
+ let sigBytes;
155
+ try {
156
+ sigBytes = base64Decode(sig.slice(3));
157
+ } catch (e) {
158
+ continue;
159
+ }
160
+ const ok = yield crypto.subtle.verify("HMAC", key, sigBytes, signed);
161
+ if (ok) return;
162
+ }
163
+ throw new WebhookVerificationError("Invalid webhook signature");
164
+ });
165
+ }
166
+ function parseWebhookEventAsync(payload, headers, secret, options) {
167
+ return __async(this, null, function* () {
168
+ yield verifyWebhookAsync(payload, headers, secret, options);
169
+ const parsed = JSON.parse(payload);
170
+ return parsed;
171
+ });
172
+ }
116
173
  var AggAdminClient = class {
117
174
  constructor(options) {
118
175
  this.baseUrl = options.baseUrl.replace(/\/$/, "");
@@ -249,6 +306,8 @@ function getHeader(headers, name) {
249
306
  AggAdminClient,
250
307
  WebhookVerificationError,
251
308
  parseWebhookEvent,
309
+ parseWebhookEventAsync,
252
310
  signExternalId,
253
- verifyWebhook
311
+ verifyWebhook,
312
+ verifyWebhookAsync
254
313
  });
package/dist/server.mjs CHANGED
@@ -15,6 +15,22 @@ function signExternalId(appSecret, externalId) {
15
15
  hmac
16
16
  };
17
17
  }
18
+ var textEncoder = new TextEncoder();
19
+ function base64Decode(s) {
20
+ const bin = atob(s);
21
+ const out = new Uint8Array(bin.length);
22
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
23
+ return out;
24
+ }
25
+ function importHmacKey(secret) {
26
+ return __async(this, null, function* () {
27
+ const keyBytes = base64Decode(secret.replace(/^whsec_/, ""));
28
+ return crypto.subtle.importKey("raw", keyBytes, { name: "HMAC", hash: "SHA-256" }, false, [
29
+ "sign",
30
+ "verify"
31
+ ]);
32
+ });
33
+ }
18
34
  var WebhookVerificationError = class extends Error {
19
35
  constructor(message) {
20
36
  super(message);
@@ -54,6 +70,45 @@ function parseWebhookEvent(payload, headers, secret, options) {
54
70
  const parsed = JSON.parse(payload);
55
71
  return parsed;
56
72
  }
73
+ function verifyWebhookAsync(payload, headers, secret, options) {
74
+ return __async(this, null, function* () {
75
+ var _a;
76
+ const tolerance = (_a = options == null ? void 0 : options.toleranceSeconds) != null ? _a : 300;
77
+ const msgId = getHeader(headers, "webhook-id");
78
+ const timestamp = getHeader(headers, "webhook-timestamp");
79
+ const signatures = getHeader(headers, "webhook-signature");
80
+ if (!msgId) throw new WebhookVerificationError("Missing Webhook-Id header");
81
+ if (!timestamp) throw new WebhookVerificationError("Missing Webhook-Timestamp header");
82
+ if (!signatures) throw new WebhookVerificationError("Missing Webhook-Signature header");
83
+ const ts = parseInt(timestamp, 10);
84
+ if (isNaN(ts)) throw new WebhookVerificationError("Invalid Webhook-Timestamp");
85
+ const now = Math.floor(Date.now() / 1e3);
86
+ if (Math.abs(now - ts) > tolerance) {
87
+ throw new WebhookVerificationError("Webhook timestamp outside tolerance window");
88
+ }
89
+ const key = yield importHmacKey(secret);
90
+ const signed = textEncoder.encode(`${msgId}.${timestamp}.${payload}`);
91
+ for (const sig of signatures.split(" ")) {
92
+ if (!sig.startsWith("v1,")) continue;
93
+ let sigBytes;
94
+ try {
95
+ sigBytes = base64Decode(sig.slice(3));
96
+ } catch (e) {
97
+ continue;
98
+ }
99
+ const ok = yield crypto.subtle.verify("HMAC", key, sigBytes, signed);
100
+ if (ok) return;
101
+ }
102
+ throw new WebhookVerificationError("Invalid webhook signature");
103
+ });
104
+ }
105
+ function parseWebhookEventAsync(payload, headers, secret, options) {
106
+ return __async(this, null, function* () {
107
+ yield verifyWebhookAsync(payload, headers, secret, options);
108
+ const parsed = JSON.parse(payload);
109
+ return parsed;
110
+ });
111
+ }
57
112
  var AggAdminClient = class {
58
113
  constructor(options) {
59
114
  this.baseUrl = options.baseUrl.replace(/\/$/, "");
@@ -189,6 +244,8 @@ export {
189
244
  AggAdminClient,
190
245
  WebhookVerificationError,
191
246
  parseWebhookEvent,
247
+ parseWebhookEventAsync,
192
248
  signExternalId,
193
- verifyWebhook
249
+ verifyWebhook,
250
+ verifyWebhookAsync
194
251
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/sdk",
3
- "version": "1.2.11",
3
+ "version": "1.3.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",