@agg-build/sdk 4.25.0 → 4.27.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/agg-websocket-BstVWtLA.d.mts +6004 -0
- package/dist/agg-websocket-BstVWtLA.d.mts.map +1 -0
- package/dist/agg-websocket-BstVWtLA.d.ts +6004 -0
- package/dist/agg-websocket-BstVWtLA.d.ts.map +1 -0
- package/dist/agg-websocket-CK2iXfti.mjs +1427 -0
- package/dist/agg-websocket-CK2iXfti.mjs.map +1 -0
- package/dist/agg-websocket-DJbIfxKb.js +1478 -0
- package/dist/browser.d.mts +67 -66
- package/dist/browser.d.mts.map +1 -0
- package/dist/browser.d.ts +67 -66
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +720 -2047
- package/dist/browser.mjs +423 -799
- package/dist/browser.mjs.map +1 -0
- package/dist/candle-builder-BNewIe9K.mjs +148 -0
- package/dist/candle-builder-BNewIe9K.mjs.map +1 -0
- package/dist/candle-builder-BULYdxB4.js +151 -0
- package/dist/index.d.mts +2 -1342
- package/dist/index.d.ts +2 -1342
- package/dist/index.js +2794 -4656
- package/dist/index.mjs +2788 -2486
- package/dist/index.mjs.map +1 -0
- package/dist/market-data.d.mts +6 -6
- package/dist/market-data.d.mts.map +1 -0
- package/dist/market-data.d.ts +6 -6
- package/dist/market-data.d.ts.map +1 -0
- package/dist/market-data.js +314 -1774
- package/dist/market-data.mjs +314 -350
- package/dist/market-data.mjs.map +1 -0
- package/dist/server.d.mts +235 -234
- package/dist/server.d.mts.map +1 -0
- package/dist/server.d.ts +235 -234
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +168 -296
- package/dist/server.mjs +163 -234
- package/dist/server.mjs.map +1 -0
- package/package.json +4 -4
- package/dist/agg-websocket-Bxt9PzTz.d.mts +0 -4479
- package/dist/agg-websocket-Bxt9PzTz.d.ts +0 -4479
- package/dist/chunk-QXBVA5TW.mjs +0 -2073
- package/dist/chunk-VD5UTAVD.mjs +0 -158
- package/dist/chunk-WNQUEZJF.mjs +0 -58
package/dist/server.mjs
CHANGED
|
@@ -1,251 +1,180 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
__spreadProps,
|
|
4
|
-
__spreadValues
|
|
5
|
-
} from "./chunk-WNQUEZJF.mjs";
|
|
6
|
-
|
|
7
|
-
// src/server.ts
|
|
8
|
-
import { createHmac, timingSafeEqual } from "crypto";
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
//#region src/server.ts
|
|
9
3
|
function signExternalId(appSecret, externalId) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
4
|
+
const timestamp = Date.now();
|
|
5
|
+
return {
|
|
6
|
+
externalId,
|
|
7
|
+
timestamp,
|
|
8
|
+
hmac: createHmac("sha256", Buffer.from(appSecret, "hex")).update(`${externalId}:${timestamp}`).digest("hex")
|
|
9
|
+
};
|
|
17
10
|
}
|
|
18
|
-
|
|
11
|
+
const textEncoder = new TextEncoder();
|
|
19
12
|
function base64Decode(s) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
const bin = atob(s);
|
|
14
|
+
const out = new Uint8Array(bin.length);
|
|
15
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
16
|
+
return out;
|
|
24
17
|
}
|
|
25
|
-
function importHmacKey(secret) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
]);
|
|
32
|
-
});
|
|
18
|
+
async function importHmacKey(secret) {
|
|
19
|
+
const keyBytes = base64Decode(secret.replace(/^whsec_/, ""));
|
|
20
|
+
return crypto.subtle.importKey("raw", keyBytes, {
|
|
21
|
+
name: "HMAC",
|
|
22
|
+
hash: "SHA-256"
|
|
23
|
+
}, false, ["sign", "verify"]);
|
|
33
24
|
}
|
|
34
25
|
var WebhookVerificationError = class extends Error {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
constructor(message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = "WebhookVerificationError";
|
|
29
|
+
}
|
|
39
30
|
};
|
|
40
31
|
function verifyWebhook(payload, headers, secret, options) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const matched = signatures.split(" ").some((sig) => {
|
|
61
|
-
const sigBuf = Buffer.from(sig);
|
|
62
|
-
return sigBuf.length === expectedBuf.length && timingSafeEqual(sigBuf, expectedBuf);
|
|
63
|
-
});
|
|
64
|
-
if (!matched) {
|
|
65
|
-
throw new WebhookVerificationError("Invalid webhook signature");
|
|
66
|
-
}
|
|
32
|
+
const tolerance = options?.toleranceSeconds ?? 300;
|
|
33
|
+
const msgId = getHeader(headers, "webhook-id");
|
|
34
|
+
const timestamp = getHeader(headers, "webhook-timestamp");
|
|
35
|
+
const signatures = getHeader(headers, "webhook-signature");
|
|
36
|
+
if (!msgId) throw new WebhookVerificationError("Missing Webhook-Id header");
|
|
37
|
+
if (!timestamp) throw new WebhookVerificationError("Missing Webhook-Timestamp header");
|
|
38
|
+
if (!signatures) throw new WebhookVerificationError("Missing Webhook-Signature header");
|
|
39
|
+
const ts = parseInt(timestamp, 10);
|
|
40
|
+
if (isNaN(ts)) throw new WebhookVerificationError("Invalid Webhook-Timestamp");
|
|
41
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
42
|
+
if (Math.abs(now - ts) > tolerance) throw new WebhookVerificationError("Webhook timestamp outside tolerance window");
|
|
43
|
+
const secretBytes = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
|
|
44
|
+
const signedContent = `${msgId}.${timestamp}.${payload}`;
|
|
45
|
+
const expectedSig = `v1,${createHmac("sha256", secretBytes).update(signedContent).digest("base64")}`;
|
|
46
|
+
const expectedBuf = Buffer.from(expectedSig);
|
|
47
|
+
if (!signatures.split(" ").some((sig) => {
|
|
48
|
+
const sigBuf = Buffer.from(sig);
|
|
49
|
+
return sigBuf.length === expectedBuf.length && timingSafeEqual(sigBuf, expectedBuf);
|
|
50
|
+
})) throw new WebhookVerificationError("Invalid webhook signature");
|
|
67
51
|
}
|
|
68
52
|
function parseWebhookEvent(payload, headers, secret, options) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return parsed;
|
|
53
|
+
verifyWebhook(payload, headers, secret, options);
|
|
54
|
+
return JSON.parse(payload);
|
|
72
55
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
});
|
|
56
|
+
/**
|
|
57
|
+
* Async, edge-runtime-friendly variant of {@link verifyWebhook}. Same
|
|
58
|
+
* Svix v1 signing scheme. Use this in Cloudflare Workers / Vercel Edge /
|
|
59
|
+
* Deno / Bun. The sync variant remains available for Node.js consumers.
|
|
60
|
+
*/
|
|
61
|
+
async function verifyWebhookAsync(payload, headers, secret, options) {
|
|
62
|
+
const tolerance = options?.toleranceSeconds ?? 300;
|
|
63
|
+
const msgId = getHeader(headers, "webhook-id");
|
|
64
|
+
const timestamp = getHeader(headers, "webhook-timestamp");
|
|
65
|
+
const signatures = getHeader(headers, "webhook-signature");
|
|
66
|
+
if (!msgId) throw new WebhookVerificationError("Missing Webhook-Id header");
|
|
67
|
+
if (!timestamp) throw new WebhookVerificationError("Missing Webhook-Timestamp header");
|
|
68
|
+
if (!signatures) throw new WebhookVerificationError("Missing Webhook-Signature header");
|
|
69
|
+
const ts = parseInt(timestamp, 10);
|
|
70
|
+
if (isNaN(ts)) throw new WebhookVerificationError("Invalid Webhook-Timestamp");
|
|
71
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
72
|
+
if (Math.abs(now - ts) > tolerance) throw new WebhookVerificationError("Webhook timestamp outside tolerance window");
|
|
73
|
+
const key = await importHmacKey(secret);
|
|
74
|
+
const signed = textEncoder.encode(`${msgId}.${timestamp}.${payload}`);
|
|
75
|
+
for (const sig of signatures.split(" ")) {
|
|
76
|
+
if (!sig.startsWith("v1,")) continue;
|
|
77
|
+
let sigBytes;
|
|
78
|
+
try {
|
|
79
|
+
sigBytes = base64Decode(sig.slice(3));
|
|
80
|
+
} catch {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (await crypto.subtle.verify("HMAC", key, sigBytes, signed)) return;
|
|
84
|
+
}
|
|
85
|
+
throw new WebhookVerificationError("Invalid webhook signature");
|
|
104
86
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Async, edge-runtime-friendly variant of {@link parseWebhookEvent}.
|
|
89
|
+
*/
|
|
90
|
+
async function parseWebhookEventAsync(payload, headers, secret, options) {
|
|
91
|
+
await verifyWebhookAsync(payload, headers, secret, options);
|
|
92
|
+
return JSON.parse(payload);
|
|
111
93
|
}
|
|
112
94
|
var AggAdminClient = class {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
return this.request(`/apps/${appId}/analytics`);
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
listOrders(appId, query) {
|
|
189
|
-
return __async(this, null, function* () {
|
|
190
|
-
var _a;
|
|
191
|
-
return this.request(`/apps/${appId}/orders`, {
|
|
192
|
-
query: {
|
|
193
|
-
limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
|
|
194
|
-
cursor: query == null ? void 0 : query.cursor,
|
|
195
|
-
venue: query == null ? void 0 : query.venue,
|
|
196
|
-
status: query == null ? void 0 : query.status
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
// ── Webhooks ─────────────────────────────────────────────────────────
|
|
202
|
-
rotateWebhookSecret(appId, webhookId) {
|
|
203
|
-
return __async(this, null, function* () {
|
|
204
|
-
return this.request(`/apps/${appId}/webhooks/${webhookId}/rotate-secret`, {
|
|
205
|
-
method: "POST"
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
replayWebhookDeliveries(appId, webhookId) {
|
|
210
|
-
return __async(this, null, function* () {
|
|
211
|
-
return this.request(`/apps/${appId}/webhooks/${webhookId}/replay`, {
|
|
212
|
-
method: "POST"
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
// ── Market Resolutions ───────────────────────────────────────────────
|
|
217
|
-
listMarketResolutionUsers(appId, venueMarketId, query) {
|
|
218
|
-
return __async(this, null, function* () {
|
|
219
|
-
var _a;
|
|
220
|
-
return this.request(`/apps/${appId}/market-resolutions/${venueMarketId}/users`, {
|
|
221
|
-
query: {
|
|
222
|
-
limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
|
|
223
|
-
cursor: query == null ? void 0 : query.cursor,
|
|
224
|
-
includeEmails: (query == null ? void 0 : query.includeEmails) ? "true" : void 0
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
}
|
|
95
|
+
constructor(options) {
|
|
96
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
97
|
+
this.apiKey = options.apiKey;
|
|
98
|
+
}
|
|
99
|
+
async request(path, init) {
|
|
100
|
+
const response = await this.rawFetch(path, init);
|
|
101
|
+
if (!response.ok) return this.throwResponseError(response);
|
|
102
|
+
return response.json();
|
|
103
|
+
}
|
|
104
|
+
async rawFetch(path, init) {
|
|
105
|
+
const headers = {
|
|
106
|
+
"Content-Type": "application/json",
|
|
107
|
+
"x-app-api-key": this.apiKey
|
|
108
|
+
};
|
|
109
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
110
|
+
if (init?.query) for (const [key, value] of Object.entries(init.query)) {
|
|
111
|
+
if (value === void 0) continue;
|
|
112
|
+
if (Array.isArray(value)) for (const v of value) url.searchParams.append(key, v);
|
|
113
|
+
else url.searchParams.set(key, value);
|
|
114
|
+
}
|
|
115
|
+
return fetch(url, {
|
|
116
|
+
...init,
|
|
117
|
+
headers: {
|
|
118
|
+
...headers,
|
|
119
|
+
...init?.headers
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async throwResponseError(response) {
|
|
124
|
+
let message = `AGG API error: ${response.status} ${response.statusText}`;
|
|
125
|
+
try {
|
|
126
|
+
const body = await response.json();
|
|
127
|
+
if (typeof body.message === "string" && body.message.length > 0) message = body.message;
|
|
128
|
+
} catch {}
|
|
129
|
+
const error = new Error(message);
|
|
130
|
+
error.status = response.status;
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
async listUsers(appId, query) {
|
|
134
|
+
return this.request(`/apps/${appId}/users`, { query: {
|
|
135
|
+
limit: query?.limit?.toString(),
|
|
136
|
+
cursor: query?.cursor,
|
|
137
|
+
search: query?.search
|
|
138
|
+
} });
|
|
139
|
+
}
|
|
140
|
+
async getUser(appId, userId) {
|
|
141
|
+
return this.request(`/apps/${appId}/users/${userId}`);
|
|
142
|
+
}
|
|
143
|
+
async getAnalytics(appId) {
|
|
144
|
+
return this.request(`/apps/${appId}/analytics`);
|
|
145
|
+
}
|
|
146
|
+
async listOrders(appId, query) {
|
|
147
|
+
return this.request(`/apps/${appId}/orders`, { query: {
|
|
148
|
+
limit: query?.limit?.toString(),
|
|
149
|
+
cursor: query?.cursor,
|
|
150
|
+
venue: query?.venue,
|
|
151
|
+
status: query?.status
|
|
152
|
+
} });
|
|
153
|
+
}
|
|
154
|
+
async rotateWebhookSecret(appId, webhookId) {
|
|
155
|
+
return this.request(`/apps/${appId}/webhooks/${webhookId}/rotate-secret`, { method: "POST" });
|
|
156
|
+
}
|
|
157
|
+
async replayWebhookDeliveries(appId, webhookId) {
|
|
158
|
+
return this.request(`/apps/${appId}/webhooks/${webhookId}/replay`, { method: "POST" });
|
|
159
|
+
}
|
|
160
|
+
async listMarketResolutionUsers(appId, venueMarketId, query) {
|
|
161
|
+
return this.request(`/apps/${appId}/market-resolutions/${venueMarketId}/users`, { query: {
|
|
162
|
+
limit: query?.limit?.toString(),
|
|
163
|
+
cursor: query?.cursor,
|
|
164
|
+
includeEmails: query?.includeEmails ? "true" : void 0
|
|
165
|
+
} });
|
|
166
|
+
}
|
|
229
167
|
};
|
|
230
168
|
function getHeader(headers, name) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
return Array.isArray(v) ? v[0] : v;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return void 0;
|
|
169
|
+
const val = headers[name] ?? headers[name.toLowerCase()];
|
|
170
|
+
if (val !== void 0) return Array.isArray(val) ? val[0] : val;
|
|
171
|
+
const lower = name.toLowerCase();
|
|
172
|
+
for (const key of Object.keys(headers)) if (key.toLowerCase() === lower) {
|
|
173
|
+
const v = headers[key];
|
|
174
|
+
return Array.isArray(v) ? v[0] : v;
|
|
175
|
+
}
|
|
242
176
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
parseWebhookEventAsync,
|
|
248
|
-
signExternalId,
|
|
249
|
-
verifyWebhook,
|
|
250
|
-
verifyWebhookAsync
|
|
251
|
-
};
|
|
177
|
+
//#endregion
|
|
178
|
+
export { AggAdminClient, WebhookVerificationError, parseWebhookEvent, parseWebhookEventAsync, signExternalId, verifyWebhook, verifyWebhookAsync };
|
|
179
|
+
|
|
180
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../src/server.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from \"node:crypto\";\n\n// ── External ID Signing ──────────────────────────────────────────────────────\n\nexport interface ExternalIdAssertion {\n externalId: string;\n timestamp: number;\n hmac: string;\n}\n\nexport function signExternalId(appSecret: string, externalId: string): ExternalIdAssertion {\n const timestamp = Date.now();\n const hmac = createHmac(\"sha256\", Buffer.from(appSecret, \"hex\"))\n .update(`${externalId}:${timestamp}`)\n .digest(\"hex\");\n\n return {\n externalId,\n timestamp,\n hmac,\n };\n}\n\n// ── WebCrypto helpers (edge-runtime friendly) ────────────────────────────────\n//\n// The sync verifyWebhook/parseWebhookEvent below rely on `node:crypto`. That\n// works in Node and bundlers that polyfill it, but breaks in edge runtimes\n// (Cloudflare Workers, Vercel Edge, Deno, Bun without --compat). The async\n// variants below use the WebCrypto API which is universally available — same\n// signing scheme (Svix v1), same secret format, just async.\n\nconst textEncoder = new TextEncoder();\n\nfunction base64Decode(s: string): Uint8Array<ArrayBuffer> {\n // `atob` is in every modern runtime (Node ≥16, all edge runtimes).\n const bin = atob(s);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nasync function importHmacKey(secret: string): Promise<CryptoKey> {\n const keyBytes = base64Decode(secret.replace(/^whsec_/, \"\"));\n return crypto.subtle.importKey(\"raw\", keyBytes, { name: \"HMAC\", hash: \"SHA-256\" }, false, [\n \"sign\",\n \"verify\",\n ]);\n}\n\n// ── Webhook Verification ─────────────────────────────────────────────────────\n\nexport class WebhookVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WebhookVerificationError\";\n }\n}\n\nexport interface VerifyWebhookOptions {\n toleranceSeconds?: number;\n}\n\nexport function verifyWebhook(\n payload: string,\n headers: Record<string, string | string[] | undefined>,\n secret: string,\n options?: VerifyWebhookOptions,\n): void {\n const tolerance = options?.toleranceSeconds ?? 300;\n\n const msgId = getHeader(headers, \"webhook-id\");\n const timestamp = getHeader(headers, \"webhook-timestamp\");\n const signatures = getHeader(headers, \"webhook-signature\");\n\n if (!msgId) throw new WebhookVerificationError(\"Missing Webhook-Id header\");\n if (!timestamp) throw new WebhookVerificationError(\"Missing Webhook-Timestamp header\");\n if (!signatures) throw new WebhookVerificationError(\"Missing Webhook-Signature header\");\n\n const ts = parseInt(timestamp, 10);\n if (isNaN(ts)) throw new WebhookVerificationError(\"Invalid Webhook-Timestamp\");\n const now = Math.floor(Date.now() / 1000);\n if (Math.abs(now - ts) > tolerance) {\n throw new WebhookVerificationError(\"Webhook timestamp outside tolerance window\");\n }\n\n const secretBytes = Buffer.from(secret.replace(/^whsec_/, \"\"), \"base64\");\n const signedContent = `${msgId}.${timestamp}.${payload}`;\n const expected = createHmac(\"sha256\", secretBytes).update(signedContent).digest(\"base64\");\n const expectedSig = `v1,${expected}`;\n const expectedBuf = Buffer.from(expectedSig);\n\n const matched = signatures.split(\" \").some((sig) => {\n const sigBuf = Buffer.from(sig);\n return sigBuf.length === expectedBuf.length && timingSafeEqual(sigBuf, expectedBuf);\n });\n\n if (!matched) {\n throw new WebhookVerificationError(\"Invalid webhook signature\");\n }\n}\n\nexport function parseWebhookEvent(\n payload: string,\n headers: Record<string, string | string[] | undefined>,\n secret: string,\n options?: VerifyWebhookOptions,\n): WebhookEvent {\n verifyWebhook(payload, headers, secret, options);\n const parsed = JSON.parse(payload) as {\n id: string;\n type: string;\n createdAt: string;\n data: unknown;\n };\n return parsed as WebhookEvent;\n}\n\n/**\n * Async, edge-runtime-friendly variant of {@link verifyWebhook}. Same\n * Svix v1 signing scheme. Use this in Cloudflare Workers / Vercel Edge /\n * Deno / Bun. The sync variant remains available for Node.js consumers.\n */\nexport async function verifyWebhookAsync(\n payload: string,\n headers: Record<string, string | string[] | undefined>,\n secret: string,\n options?: VerifyWebhookOptions,\n): Promise<void> {\n const tolerance = options?.toleranceSeconds ?? 300;\n const msgId = getHeader(headers, \"webhook-id\");\n const timestamp = getHeader(headers, \"webhook-timestamp\");\n const signatures = getHeader(headers, \"webhook-signature\");\n\n if (!msgId) throw new WebhookVerificationError(\"Missing Webhook-Id header\");\n if (!timestamp) throw new WebhookVerificationError(\"Missing Webhook-Timestamp header\");\n if (!signatures) throw new WebhookVerificationError(\"Missing Webhook-Signature header\");\n\n const ts = parseInt(timestamp, 10);\n if (isNaN(ts)) throw new WebhookVerificationError(\"Invalid Webhook-Timestamp\");\n const now = Math.floor(Date.now() / 1000);\n if (Math.abs(now - ts) > tolerance) {\n throw new WebhookVerificationError(\"Webhook timestamp outside tolerance window\");\n }\n\n const key = await importHmacKey(secret);\n const signed = textEncoder.encode(`${msgId}.${timestamp}.${payload}`);\n\n // WebCrypto's verify() is constant-time internally — safer than a manual\n // === comparison. Walk the space-separated signature list and accept the\n // first v1 match.\n for (const sig of signatures.split(\" \")) {\n if (!sig.startsWith(\"v1,\")) continue;\n let sigBytes: Uint8Array<ArrayBuffer>;\n try {\n sigBytes = base64Decode(sig.slice(3));\n } catch {\n continue;\n }\n const ok = await crypto.subtle.verify(\"HMAC\", key, sigBytes, signed);\n if (ok) return;\n }\n\n throw new WebhookVerificationError(\"Invalid webhook signature\");\n}\n\n/**\n * Async, edge-runtime-friendly variant of {@link parseWebhookEvent}.\n */\nexport async function parseWebhookEventAsync(\n payload: string,\n headers: Record<string, string | string[] | undefined>,\n secret: string,\n options?: VerifyWebhookOptions,\n): Promise<WebhookEvent> {\n await verifyWebhookAsync(payload, headers, secret, options);\n const parsed = JSON.parse(payload) as {\n id: string;\n type: string;\n createdAt: string;\n data: unknown;\n };\n return parsed as WebhookEvent;\n}\n\n// ── Webhook Event Types ──────────────────────────────────────────────────────\n//\n// These interfaces describe the exact shape of `event.data` that partners\n// receive. Keep them in lockstep with the producer payloads in\n// `apps/api/libs/webhook-dispatch/src/webhook-dispatch.client.ts` —\n// any field added here that the producer doesn't emit will be `undefined`\n// at runtime without a type error, which is exactly the kind of contract\n// drift that broke earlier revisions of this file.\n\ninterface WebhookEventBase {\n id: string;\n createdAt: string;\n}\n\nexport interface AccountsCreatedEvent extends WebhookEventBase {\n type: \"accounts.created\";\n data: { userId: string; appId: string; createdAt: string; email: string | null };\n}\n\nexport interface AccountsLinkedEvent extends WebhookEventBase {\n type: \"accounts.linked\";\n data: { userId: string; externalId: string; linkedAt: string };\n}\n\nexport interface WalletsReadyEvent extends WebhookEventBase {\n type: \"wallets.ready\";\n data: {\n userId: string;\n evmAddress: string;\n svmAddress: string;\n createdAt: string;\n };\n}\n\nexport interface TradesPlacedEvent extends WebhookEventBase {\n type: \"trades.placed\";\n data: {\n orderId: string;\n userId: string;\n side: string;\n timestamp: string;\n /** Your trade id from `POST /execution/orders`, or `null` if the trade did not carry one. */\n externalId: string | null;\n /**\n * @deprecated Never emitted by the server in 1.x — the SDK type lied\n * here for several releases. Reads always return `undefined`. The field\n * is retained as `undefined`-typed for one minor release so existing\n * partner code that destructures it keeps compiling; remove in 2.0.\n */\n venue?: undefined;\n /** @deprecated See `venue`. */\n venueMarketId?: undefined;\n };\n}\n\nexport interface TradesFilledEvent extends WebhookEventBase {\n type: \"trades.filled\";\n data: {\n orderId: string;\n userId: string;\n status: string;\n timestamp: string;\n /** Your trade id from `POST /execution/orders`, or `null` if the trade did not carry one. */\n externalId: string | null;\n /**\n * Post-execution accuracy data. All `*Raw` values are decimal strings in\n * 6-decimal atomic units. `*PriceRaw` are decimal strings (e.g. \"0.5\").\n * `partialFillReason` is set only on `status === \"partial_fill\"`.\n */\n filledAmountRaw?: string;\n quotedSharesRaw?: string;\n actualSharesRaw?: string;\n quotedToWinRaw?: string;\n actualToWinRaw?: string;\n quotedPriceRaw?: string;\n executionPriceRaw?: string;\n partialFillReason?: string;\n /** @deprecated See `executionPriceRaw` — never emitted; remove in 2.0. */\n fillPrice?: undefined;\n /** @deprecated See `actualSharesRaw` / `filledAmountRaw` — never emitted; remove in 2.0. */\n fillSize?: undefined;\n };\n}\n\n/**\n * A self-custody trade's app fee reached its final state. Sent once per trade,\n * a few seconds after `trades.filled` (the fee needs the user's second\n * signature and an on-chain confirmation).\n */\nexport interface TradesFeeReconciledEvent extends WebhookEventBase {\n type: \"trades.fee_reconciled\";\n data: {\n dagRunId: string;\n quoteId: string;\n userId: string;\n /** Every order in the trade. The fee is charged once across all of them. */\n orders: Array<{ orderId: string; externalId: string | null }>;\n /**\n * `confirmed`, `under_collected`, `failed`, `skipped_zero`, … or `none`\n * when no fee applied to the trade.\n */\n status: string;\n /** Token-native atomic units. `\"0\"` when `status` is `none`. */\n feeDueRaw: string;\n feeCollectedRaw: string;\n appShareRaw: string;\n platformShareRaw: string;\n chainId: string | null;\n tokenSymbol: string | null;\n tokenAddress: string | null;\n appTxHash: string | null;\n platformTxHash: string | null;\n timestamp: string;\n };\n}\n\nexport interface MarketsResolvedEvent extends WebhookEventBase {\n type: \"markets.resolved\";\n data: {\n venueMarketId: string;\n externalIdentifier: string;\n status: string;\n outcomes: Array<{ label: string; winner?: boolean; externalIdentifier?: string }>;\n affectedUsersCount: number;\n /**\n * Path on the AGG API where this resolution's affected users can be\n * paginated. Combine with the configured base URL — e.g.\n * `https://api.agg.market${detailsPath}`.\n */\n detailsPath: string;\n /**\n * @deprecated Singular `outcome` was never emitted; use `outcomes` array.\n * Remove in 2.0.\n */\n outcome?: undefined;\n };\n}\n\nexport interface DepositsConfirmedEvent extends WebhookEventBase {\n type: \"deposits.confirmed\";\n data: {\n userId: string;\n chainId: number;\n tokenSymbol: string;\n tokenAddress: string;\n /** Token-native atomic units (6 decimals for USDC). */\n amountRaw: string;\n txHash: string;\n fromAddress: string;\n timestamp: string;\n };\n}\n\nexport interface UnknownWebhookEvent extends WebhookEventBase {\n type: string;\n data: Record<string, unknown>;\n}\n\nexport type KnownWebhookEvent =\n | AccountsCreatedEvent\n | AccountsLinkedEvent\n | WalletsReadyEvent\n | TradesPlacedEvent\n | TradesFilledEvent\n | TradesFeeReconciledEvent\n | MarketsResolvedEvent\n | DepositsConfirmedEvent;\n\nexport type WebhookEvent = KnownWebhookEvent | UnknownWebhookEvent;\n\n// ── Admin API Client ─────────────────────────────────────────────────────────\n\nexport interface AggAdminClientOptions {\n baseUrl: string;\n apiKey: string;\n}\n\nexport class AggAdminClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n\n constructor(options: AggAdminClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n }\n\n // ── Core HTTP ────────────────────────────────────────────────────────\n\n public async request<T>(\n path: string,\n init?: RequestInit & { query?: Record<string, string | string[] | undefined> },\n ): Promise<T> {\n const response = await this.rawFetch(path, init);\n if (!response.ok) {\n return this.throwResponseError(response);\n }\n return response.json() as Promise<T>;\n }\n\n private async rawFetch(\n path: string,\n init?: RequestInit & { query?: Record<string, string | string[] | undefined> },\n ): Promise<Response> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"x-app-api-key\": this.apiKey,\n };\n\n const url = new URL(`${this.baseUrl}${path}`);\n if (init?.query) {\n for (const [key, value] of Object.entries(init.query)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const v of value) url.searchParams.append(key, v);\n } else {\n url.searchParams.set(key, value);\n }\n }\n }\n\n return fetch(url, {\n ...init,\n headers: { ...headers, ...init?.headers },\n });\n }\n\n private async throwResponseError(response: Response): Promise<never> {\n let message = `AGG API error: ${response.status} ${response.statusText}`;\n try {\n const body = (await response.json()) as { message?: string };\n if (typeof body.message === \"string\" && body.message.length > 0) {\n message = body.message;\n }\n } catch {\n // best-effort parse\n }\n const error = new Error(message) as Error & { status: number };\n error.status = response.status;\n throw error;\n }\n\n // ── Users ────────────────────────────────────────────────────────────\n\n async listUsers(appId: string, query?: { limit?: number; cursor?: string; search?: string }) {\n return this.request<{\n data: {\n id: string;\n username: string | null;\n externalId: string | null;\n suspended: boolean;\n createdAt: string;\n }[];\n nextCursor: string | null;\n hasMore: boolean;\n }>(`/apps/${appId}/users`, {\n query: {\n limit: query?.limit?.toString(),\n cursor: query?.cursor,\n search: query?.search,\n },\n });\n }\n\n async getUser(appId: string, userId: string) {\n return this.request<{\n id: string;\n username: string | null;\n externalId: string | null;\n suspended: boolean;\n createdAt: string;\n updatedAt: string;\n _count: { orders: number };\n }>(`/apps/${appId}/users/${userId}`);\n }\n\n // ── Analytics & Orders ───────────────────────────────────────────────\n\n async getAnalytics(appId: string) {\n return this.request<{\n totalUsers: number;\n totalOrders: number;\n ordersByStatus: Record<string, number>;\n ordersByVenue: Record<string, number>;\n usersLast30Days: number;\n usersLast7Days: number;\n ordersLast30Days: number;\n ordersLast7Days: number;\n }>(`/apps/${appId}/analytics`);\n }\n\n async listOrders(\n appId: string,\n query?: { limit?: number; cursor?: string; venue?: string; status?: string },\n ) {\n return this.request<{\n data: unknown[];\n nextCursor: string | null;\n hasMore: boolean;\n }>(`/apps/${appId}/orders`, {\n query: {\n limit: query?.limit?.toString(),\n cursor: query?.cursor,\n venue: query?.venue,\n status: query?.status,\n },\n });\n }\n\n // ── Webhooks ─────────────────────────────────────────────────────────\n\n async rotateWebhookSecret(appId: string, webhookId: string) {\n return this.request<{ secret: string }>(`/apps/${appId}/webhooks/${webhookId}/rotate-secret`, {\n method: \"POST\",\n });\n }\n\n async replayWebhookDeliveries(appId: string, webhookId: string) {\n return this.request<{ success: boolean }>(`/apps/${appId}/webhooks/${webhookId}/replay`, {\n method: \"POST\",\n });\n }\n\n // ── Market Resolutions ───────────────────────────────────────────────\n\n async listMarketResolutionUsers(\n appId: string,\n venueMarketId: string,\n query?: { limit?: number; cursor?: string; includeEmails?: boolean },\n ) {\n return this.request<{\n venueMarketId: string;\n note: string;\n data: { userId: string; email?: string | null }[];\n nextCursor: string | null;\n hasMore: boolean;\n }>(`/apps/${appId}/market-resolutions/${venueMarketId}/users`, {\n query: {\n limit: query?.limit?.toString(),\n cursor: query?.cursor,\n includeEmails: query?.includeEmails ? \"true\" : undefined,\n },\n });\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction getHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string,\n): string | undefined {\n const val = headers[name] ?? headers[name.toLowerCase()];\n if (val !== undefined) return Array.isArray(val) ? val[0] : val;\n\n const lower = name.toLowerCase();\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lower) {\n const v = headers[key];\n return Array.isArray(v) ? v[0] : v;\n }\n }\n return undefined;\n}\n"],"mappings":";;AAUA,SAAgB,eAAe,WAAmB,YAAyC;CACzF,MAAM,YAAY,KAAK,IAAI;CAK3B,OAAO;EACL;EACA;EACA,MAPW,WAAW,UAAU,OAAO,KAAK,WAAW,KAAK,CAAC,CAAC,CAC7D,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC,CACpC,OAAO,KAKL;CACL;AACF;AAUA,MAAM,cAAc,IAAI,YAAY;AAEpC,SAAS,aAAa,GAAoC;CAExD,MAAM,MAAM,KAAK,CAAC;CAClB,MAAM,MAAM,IAAI,WAAW,IAAI,MAAM;CACrC,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,IAAI,KAAK,IAAI,WAAW,CAAC;CAC9D,OAAO;AACT;AAEA,eAAe,cAAc,QAAoC;CAC/D,MAAM,WAAW,aAAa,OAAO,QAAQ,WAAW,EAAE,CAAC;CAC3D,OAAO,OAAO,OAAO,UAAU,OAAO,UAAU;EAAE,MAAM;EAAQ,MAAM;CAAU,GAAG,OAAO,CACxF,QACA,QACF,CAAC;AACH;AAIA,IAAa,2BAAb,cAA8C,MAAM;CAClD,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAMA,SAAgB,cACd,SACA,SACA,QACA,SACM;CACN,MAAM,YAAY,SAAS,oBAAoB;CAE/C,MAAM,QAAQ,UAAU,SAAS,YAAY;CAC7C,MAAM,YAAY,UAAU,SAAS,mBAAmB;CACxD,MAAM,aAAa,UAAU,SAAS,mBAAmB;CAEzD,IAAI,CAAC,OAAO,MAAM,IAAI,yBAAyB,2BAA2B;CAC1E,IAAI,CAAC,WAAW,MAAM,IAAI,yBAAyB,kCAAkC;CACrF,IAAI,CAAC,YAAY,MAAM,IAAI,yBAAyB,kCAAkC;CAEtF,MAAM,KAAK,SAAS,WAAW,EAAE;CACjC,IAAI,MAAM,EAAE,GAAG,MAAM,IAAI,yBAAyB,2BAA2B;CAC7E,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;CACxC,IAAI,KAAK,IAAI,MAAM,EAAE,IAAI,WACvB,MAAM,IAAI,yBAAyB,4CAA4C;CAGjF,MAAM,cAAc,OAAO,KAAK,OAAO,QAAQ,WAAW,EAAE,GAAG,QAAQ;CACvE,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,GAAG;CAE/C,MAAM,cAAc,MADH,WAAW,UAAU,WAAW,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC,OAAO,QAC/C;CACjC,MAAM,cAAc,OAAO,KAAK,WAAW;CAO3C,IAAI,CALY,WAAW,MAAM,GAAG,CAAC,CAAC,MAAM,QAAQ;EAClD,MAAM,SAAS,OAAO,KAAK,GAAG;EAC9B,OAAO,OAAO,WAAW,YAAY,UAAU,gBAAgB,QAAQ,WAAW;CACpF,CAEW,GACT,MAAM,IAAI,yBAAyB,2BAA2B;AAElE;AAEA,SAAgB,kBACd,SACA,SACA,QACA,SACc;CACd,cAAc,SAAS,SAAS,QAAQ,OAAO;CAO/C,OANe,KAAK,MAAM,OAMd;AACd;;;;;;AAOA,eAAsB,mBACpB,SACA,SACA,QACA,SACe;CACf,MAAM,YAAY,SAAS,oBAAoB;CAC/C,MAAM,QAAQ,UAAU,SAAS,YAAY;CAC7C,MAAM,YAAY,UAAU,SAAS,mBAAmB;CACxD,MAAM,aAAa,UAAU,SAAS,mBAAmB;CAEzD,IAAI,CAAC,OAAO,MAAM,IAAI,yBAAyB,2BAA2B;CAC1E,IAAI,CAAC,WAAW,MAAM,IAAI,yBAAyB,kCAAkC;CACrF,IAAI,CAAC,YAAY,MAAM,IAAI,yBAAyB,kCAAkC;CAEtF,MAAM,KAAK,SAAS,WAAW,EAAE;CACjC,IAAI,MAAM,EAAE,GAAG,MAAM,IAAI,yBAAyB,2BAA2B;CAC7E,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;CACxC,IAAI,KAAK,IAAI,MAAM,EAAE,IAAI,WACvB,MAAM,IAAI,yBAAyB,4CAA4C;CAGjF,MAAM,MAAM,MAAM,cAAc,MAAM;CACtC,MAAM,SAAS,YAAY,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS;CAKpE,KAAK,MAAM,OAAO,WAAW,MAAM,GAAG,GAAG;EACvC,IAAI,CAAC,IAAI,WAAW,KAAK,GAAG;EAC5B,IAAI;EACJ,IAAI;GACF,WAAW,aAAa,IAAI,MAAM,CAAC,CAAC;EACtC,QAAQ;GACN;EACF;EAEA,IAAI,MADa,OAAO,OAAO,OAAO,QAAQ,KAAK,UAAU,MAAM,GAC3D;CACV;CAEA,MAAM,IAAI,yBAAyB,2BAA2B;AAChE;;;;AAKA,eAAsB,uBACpB,SACA,SACA,QACA,SACuB;CACvB,MAAM,mBAAmB,SAAS,SAAS,QAAQ,OAAO;CAO1D,OANe,KAAK,MAAM,OAMd;AACd;AAmLA,IAAa,iBAAb,MAA4B;CAI1B,YAAY,SAAgC;EAC1C,KAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;EAChD,KAAK,SAAS,QAAQ;CACxB;CAIA,MAAa,QACX,MACA,MACY;EACZ,MAAM,WAAW,MAAM,KAAK,SAAS,MAAM,IAAI;EAC/C,IAAI,CAAC,SAAS,IACZ,OAAO,KAAK,mBAAmB,QAAQ;EAEzC,OAAO,SAAS,KAAK;CACvB;CAEA,MAAc,SACZ,MACA,MACmB;EACnB,MAAM,UAAkC;GACtC,gBAAgB;GAChB,iBAAiB,KAAK;EACxB;EAEA,MAAM,MAAM,IAAI,IAAI,GAAG,KAAK,UAAU,MAAM;EAC5C,IAAI,MAAM,OACR,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,KAAK,GAAG;GACrD,IAAI,UAAU,KAAA,GAAW;GACzB,IAAI,MAAM,QAAQ,KAAK,GACrB,KAAK,MAAM,KAAK,OAAO,IAAI,aAAa,OAAO,KAAK,CAAC;QAErD,IAAI,aAAa,IAAI,KAAK,KAAK;EAEnC;EAGF,OAAO,MAAM,KAAK;GAChB,GAAG;GACH,SAAS;IAAE,GAAG;IAAS,GAAG,MAAM;GAAQ;EAC1C,CAAC;CACH;CAEA,MAAc,mBAAmB,UAAoC;EACnE,IAAI,UAAU,kBAAkB,SAAS,OAAO,GAAG,SAAS;EAC5D,IAAI;GACF,MAAM,OAAQ,MAAM,SAAS,KAAK;GAClC,IAAI,OAAO,KAAK,YAAY,YAAY,KAAK,QAAQ,SAAS,GAC5D,UAAU,KAAK;EAEnB,QAAQ,CAER;EACA,MAAM,QAAQ,IAAI,MAAM,OAAO;EAC/B,MAAM,SAAS,SAAS;EACxB,MAAM;CACR;CAIA,MAAM,UAAU,OAAe,OAA8D;EAC3F,OAAO,KAAK,QAUT,SAAS,MAAM,SAAS,EACzB,OAAO;GACL,OAAO,OAAO,OAAO,SAAS;GAC9B,QAAQ,OAAO;GACf,QAAQ,OAAO;EACjB,EACF,CAAC;CACH;CAEA,MAAM,QAAQ,OAAe,QAAgB;EAC3C,OAAO,KAAK,QAQT,SAAS,MAAM,SAAS,QAAQ;CACrC;CAIA,MAAM,aAAa,OAAe;EAChC,OAAO,KAAK,QAST,SAAS,MAAM,WAAW;CAC/B;CAEA,MAAM,WACJ,OACA,OACA;EACA,OAAO,KAAK,QAIT,SAAS,MAAM,UAAU,EAC1B,OAAO;GACL,OAAO,OAAO,OAAO,SAAS;GAC9B,QAAQ,OAAO;GACf,OAAO,OAAO;GACd,QAAQ,OAAO;EACjB,EACF,CAAC;CACH;CAIA,MAAM,oBAAoB,OAAe,WAAmB;EAC1D,OAAO,KAAK,QAA4B,SAAS,MAAM,YAAY,UAAU,iBAAiB,EAC5F,QAAQ,OACV,CAAC;CACH;CAEA,MAAM,wBAAwB,OAAe,WAAmB;EAC9D,OAAO,KAAK,QAA8B,SAAS,MAAM,YAAY,UAAU,UAAU,EACvF,QAAQ,OACV,CAAC;CACH;CAIA,MAAM,0BACJ,OACA,eACA,OACA;EACA,OAAO,KAAK,QAMT,SAAS,MAAM,sBAAsB,cAAc,SAAS,EAC7D,OAAO;GACL,OAAO,OAAO,OAAO,SAAS;GAC9B,QAAQ,OAAO;GACf,eAAe,OAAO,gBAAgB,SAAS,KAAA;EACjD,EACF,CAAC;CACH;AACF;AAIA,SAAS,UACP,SACA,MACoB;CACpB,MAAM,MAAM,QAAQ,SAAS,QAAQ,KAAK,YAAY;CACtD,IAAI,QAAQ,KAAA,GAAW,OAAO,MAAM,QAAQ,GAAG,IAAI,IAAI,KAAK;CAE5D,MAAM,QAAQ,KAAK,YAAY;CAC/B,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,GACnC,IAAI,IAAI,YAAY,MAAM,OAAO;EAC/B,MAAM,IAAI,QAAQ;EAClB,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK;CACnC;AAGJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agg-build/sdk",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.27.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",
|
|
@@ -91,11 +91,11 @@
|
|
|
91
91
|
"access": "public"
|
|
92
92
|
},
|
|
93
93
|
"scripts": {
|
|
94
|
-
"build": "
|
|
95
|
-
"dev": "
|
|
94
|
+
"build": "tsdown",
|
|
95
|
+
"dev": "tsdown --watch",
|
|
96
96
|
"test": "pnpm exec vitest run --config vitest.config.ts",
|
|
97
97
|
"test:coverage": "pnpm exec vitest run --config vitest.config.ts --coverage",
|
|
98
|
-
"typecheck": "tsc --noEmit",
|
|
98
|
+
"typecheck": "node ../../node_modules/@agg/typescript-native/bin/tsc --noEmit",
|
|
99
99
|
"lint": "eslint . --max-warnings 0",
|
|
100
100
|
"clean": "rm -rf .turbo node_modules dist"
|
|
101
101
|
}
|