@agg-build/sdk 1.0.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.
@@ -0,0 +1,155 @@
1
+ interface ExternalIdAssertion {
2
+ externalId: string;
3
+ timestamp: number;
4
+ hmac: string;
5
+ }
6
+ declare function signExternalId(appSecret: string, externalId: string): ExternalIdAssertion;
7
+ declare class WebhookVerificationError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ interface VerifyWebhookOptions {
11
+ toleranceSeconds?: number;
12
+ }
13
+ declare function verifyWebhook(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): void;
14
+ declare function parseWebhookEvent(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): WebhookEvent;
15
+ interface WebhookEventBase {
16
+ id: string;
17
+ createdAt: string;
18
+ }
19
+ interface AccountsCreatedEvent extends WebhookEventBase {
20
+ type: "accounts.created";
21
+ data: {
22
+ userId: string;
23
+ appId: string;
24
+ };
25
+ }
26
+ interface AccountsLinkedEvent extends WebhookEventBase {
27
+ type: "accounts.linked";
28
+ data: {
29
+ userId: string;
30
+ externalId: string;
31
+ linkedAt: string;
32
+ };
33
+ }
34
+ interface WalletsReadyEvent extends WebhookEventBase {
35
+ type: "wallets.ready";
36
+ data: {
37
+ userId: string;
38
+ evmAddress: string;
39
+ svmAddress: string;
40
+ };
41
+ }
42
+ interface TradesPlacedEvent extends WebhookEventBase {
43
+ type: "trades.placed";
44
+ data: {
45
+ orderId: string;
46
+ userId: string;
47
+ side: string;
48
+ venue: string;
49
+ venueMarketId: string;
50
+ };
51
+ }
52
+ interface TradesFilledEvent extends WebhookEventBase {
53
+ type: "trades.filled";
54
+ data: {
55
+ orderId: string;
56
+ userId: string;
57
+ status: string;
58
+ fillPrice: number;
59
+ fillSize: number;
60
+ };
61
+ }
62
+ interface MarketsResolvedEvent extends WebhookEventBase {
63
+ type: "markets.resolved";
64
+ data: {
65
+ venueMarketId: string;
66
+ outcome: string;
67
+ affectedUsersCount: number;
68
+ };
69
+ }
70
+ interface UnknownWebhookEvent extends WebhookEventBase {
71
+ type: string;
72
+ data: Record<string, unknown>;
73
+ }
74
+ type KnownWebhookEvent = AccountsCreatedEvent | AccountsLinkedEvent | WalletsReadyEvent | TradesPlacedEvent | TradesFilledEvent | MarketsResolvedEvent;
75
+ type WebhookEvent = KnownWebhookEvent | UnknownWebhookEvent;
76
+ interface AggAdminClientOptions {
77
+ baseUrl: string;
78
+ apiKey: string;
79
+ }
80
+ declare class AggAdminClient {
81
+ private readonly baseUrl;
82
+ private readonly apiKey;
83
+ constructor(options: AggAdminClientOptions);
84
+ request<T>(path: string, init?: RequestInit & {
85
+ query?: Record<string, string | string[] | undefined>;
86
+ }): Promise<T>;
87
+ private rawFetch;
88
+ private throwResponseError;
89
+ listUsers(appId: string, query?: {
90
+ limit?: number;
91
+ cursor?: string;
92
+ search?: string;
93
+ }): Promise<{
94
+ data: {
95
+ id: string;
96
+ username: string | null;
97
+ externalId: string | null;
98
+ suspended: boolean;
99
+ createdAt: string;
100
+ }[];
101
+ nextCursor: string | null;
102
+ hasMore: boolean;
103
+ }>;
104
+ getUser(appId: string, userId: string): Promise<{
105
+ id: string;
106
+ username: string | null;
107
+ externalId: string | null;
108
+ suspended: boolean;
109
+ createdAt: string;
110
+ updatedAt: string;
111
+ _count: {
112
+ orders: number;
113
+ };
114
+ }>;
115
+ getAnalytics(appId: string): Promise<{
116
+ totalUsers: number;
117
+ totalOrders: number;
118
+ ordersByStatus: Record<string, number>;
119
+ ordersByVenue: Record<string, number>;
120
+ usersLast30Days: number;
121
+ ordersLast30Days: number;
122
+ }>;
123
+ listOrders(appId: string, query?: {
124
+ limit?: number;
125
+ cursor?: string;
126
+ venue?: string;
127
+ status?: string;
128
+ }): Promise<{
129
+ data: unknown[];
130
+ nextCursor: string | null;
131
+ hasMore: boolean;
132
+ }>;
133
+ rotateWebhookSecret(appId: string, webhookId: string): Promise<{
134
+ secret: string;
135
+ }>;
136
+ replayWebhookDeliveries(appId: string, webhookId: string): Promise<{
137
+ success: boolean;
138
+ }>;
139
+ listMarketResolutionUsers(appId: string, venueMarketId: string, query?: {
140
+ limit?: number;
141
+ cursor?: string;
142
+ includeEmails?: boolean;
143
+ }): Promise<{
144
+ venueMarketId: string;
145
+ note: string;
146
+ data: {
147
+ userId: string;
148
+ email?: string | null;
149
+ }[];
150
+ nextCursor: string | null;
151
+ hasMore: boolean;
152
+ }>;
153
+ }
154
+
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 };
@@ -0,0 +1,155 @@
1
+ interface ExternalIdAssertion {
2
+ externalId: string;
3
+ timestamp: number;
4
+ hmac: string;
5
+ }
6
+ declare function signExternalId(appSecret: string, externalId: string): ExternalIdAssertion;
7
+ declare class WebhookVerificationError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ interface VerifyWebhookOptions {
11
+ toleranceSeconds?: number;
12
+ }
13
+ declare function verifyWebhook(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): void;
14
+ declare function parseWebhookEvent(payload: string, headers: Record<string, string | string[] | undefined>, secret: string, options?: VerifyWebhookOptions): WebhookEvent;
15
+ interface WebhookEventBase {
16
+ id: string;
17
+ createdAt: string;
18
+ }
19
+ interface AccountsCreatedEvent extends WebhookEventBase {
20
+ type: "accounts.created";
21
+ data: {
22
+ userId: string;
23
+ appId: string;
24
+ };
25
+ }
26
+ interface AccountsLinkedEvent extends WebhookEventBase {
27
+ type: "accounts.linked";
28
+ data: {
29
+ userId: string;
30
+ externalId: string;
31
+ linkedAt: string;
32
+ };
33
+ }
34
+ interface WalletsReadyEvent extends WebhookEventBase {
35
+ type: "wallets.ready";
36
+ data: {
37
+ userId: string;
38
+ evmAddress: string;
39
+ svmAddress: string;
40
+ };
41
+ }
42
+ interface TradesPlacedEvent extends WebhookEventBase {
43
+ type: "trades.placed";
44
+ data: {
45
+ orderId: string;
46
+ userId: string;
47
+ side: string;
48
+ venue: string;
49
+ venueMarketId: string;
50
+ };
51
+ }
52
+ interface TradesFilledEvent extends WebhookEventBase {
53
+ type: "trades.filled";
54
+ data: {
55
+ orderId: string;
56
+ userId: string;
57
+ status: string;
58
+ fillPrice: number;
59
+ fillSize: number;
60
+ };
61
+ }
62
+ interface MarketsResolvedEvent extends WebhookEventBase {
63
+ type: "markets.resolved";
64
+ data: {
65
+ venueMarketId: string;
66
+ outcome: string;
67
+ affectedUsersCount: number;
68
+ };
69
+ }
70
+ interface UnknownWebhookEvent extends WebhookEventBase {
71
+ type: string;
72
+ data: Record<string, unknown>;
73
+ }
74
+ type KnownWebhookEvent = AccountsCreatedEvent | AccountsLinkedEvent | WalletsReadyEvent | TradesPlacedEvent | TradesFilledEvent | MarketsResolvedEvent;
75
+ type WebhookEvent = KnownWebhookEvent | UnknownWebhookEvent;
76
+ interface AggAdminClientOptions {
77
+ baseUrl: string;
78
+ apiKey: string;
79
+ }
80
+ declare class AggAdminClient {
81
+ private readonly baseUrl;
82
+ private readonly apiKey;
83
+ constructor(options: AggAdminClientOptions);
84
+ request<T>(path: string, init?: RequestInit & {
85
+ query?: Record<string, string | string[] | undefined>;
86
+ }): Promise<T>;
87
+ private rawFetch;
88
+ private throwResponseError;
89
+ listUsers(appId: string, query?: {
90
+ limit?: number;
91
+ cursor?: string;
92
+ search?: string;
93
+ }): Promise<{
94
+ data: {
95
+ id: string;
96
+ username: string | null;
97
+ externalId: string | null;
98
+ suspended: boolean;
99
+ createdAt: string;
100
+ }[];
101
+ nextCursor: string | null;
102
+ hasMore: boolean;
103
+ }>;
104
+ getUser(appId: string, userId: string): Promise<{
105
+ id: string;
106
+ username: string | null;
107
+ externalId: string | null;
108
+ suspended: boolean;
109
+ createdAt: string;
110
+ updatedAt: string;
111
+ _count: {
112
+ orders: number;
113
+ };
114
+ }>;
115
+ getAnalytics(appId: string): Promise<{
116
+ totalUsers: number;
117
+ totalOrders: number;
118
+ ordersByStatus: Record<string, number>;
119
+ ordersByVenue: Record<string, number>;
120
+ usersLast30Days: number;
121
+ ordersLast30Days: number;
122
+ }>;
123
+ listOrders(appId: string, query?: {
124
+ limit?: number;
125
+ cursor?: string;
126
+ venue?: string;
127
+ status?: string;
128
+ }): Promise<{
129
+ data: unknown[];
130
+ nextCursor: string | null;
131
+ hasMore: boolean;
132
+ }>;
133
+ rotateWebhookSecret(appId: string, webhookId: string): Promise<{
134
+ secret: string;
135
+ }>;
136
+ replayWebhookDeliveries(appId: string, webhookId: string): Promise<{
137
+ success: boolean;
138
+ }>;
139
+ listMarketResolutionUsers(appId: string, venueMarketId: string, query?: {
140
+ limit?: number;
141
+ cursor?: string;
142
+ includeEmails?: boolean;
143
+ }): Promise<{
144
+ venueMarketId: string;
145
+ note: string;
146
+ data: {
147
+ userId: string;
148
+ email?: string | null;
149
+ }[];
150
+ nextCursor: string | null;
151
+ hasMore: boolean;
152
+ }>;
153
+ }
154
+
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 };
package/dist/server.js ADDED
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
+ var __export = (target, all) => {
24
+ for (var name in all)
25
+ __defProp(target, name, { get: all[name], enumerable: true });
26
+ };
27
+ var __copyProps = (to, from, except, desc) => {
28
+ if (from && typeof from === "object" || typeof from === "function") {
29
+ for (let key of __getOwnPropNames(from))
30
+ if (!__hasOwnProp.call(to, key) && key !== except)
31
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
32
+ }
33
+ return to;
34
+ };
35
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
+ var __async = (__this, __arguments, generator) => {
37
+ return new Promise((resolve, reject) => {
38
+ var fulfilled = (value) => {
39
+ try {
40
+ step(generator.next(value));
41
+ } catch (e) {
42
+ reject(e);
43
+ }
44
+ };
45
+ var rejected = (value) => {
46
+ try {
47
+ step(generator.throw(value));
48
+ } catch (e) {
49
+ reject(e);
50
+ }
51
+ };
52
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
53
+ step((generator = generator.apply(__this, __arguments)).next());
54
+ });
55
+ };
56
+
57
+ // src/server.ts
58
+ var server_exports = {};
59
+ __export(server_exports, {
60
+ AggAdminClient: () => AggAdminClient,
61
+ WebhookVerificationError: () => WebhookVerificationError,
62
+ parseWebhookEvent: () => parseWebhookEvent,
63
+ signExternalId: () => signExternalId,
64
+ verifyWebhook: () => verifyWebhook
65
+ });
66
+ module.exports = __toCommonJS(server_exports);
67
+ var import_node_crypto = require("crypto");
68
+ function signExternalId(appSecret, externalId) {
69
+ const timestamp = Date.now();
70
+ const hmac = (0, import_node_crypto.createHmac)("sha256", Buffer.from(appSecret, "hex")).update(`${externalId}:${timestamp}`).digest("hex");
71
+ return {
72
+ externalId,
73
+ timestamp,
74
+ hmac
75
+ };
76
+ }
77
+ var WebhookVerificationError = class extends Error {
78
+ constructor(message) {
79
+ super(message);
80
+ this.name = "WebhookVerificationError";
81
+ }
82
+ };
83
+ function verifyWebhook(payload, headers, secret, options) {
84
+ var _a;
85
+ const tolerance = (_a = options == null ? void 0 : options.toleranceSeconds) != null ? _a : 300;
86
+ const msgId = getHeader(headers, "webhook-id");
87
+ const timestamp = getHeader(headers, "webhook-timestamp");
88
+ const signatures = getHeader(headers, "webhook-signature");
89
+ if (!msgId) throw new WebhookVerificationError("Missing Webhook-Id header");
90
+ if (!timestamp) throw new WebhookVerificationError("Missing Webhook-Timestamp header");
91
+ if (!signatures) throw new WebhookVerificationError("Missing Webhook-Signature header");
92
+ const ts = parseInt(timestamp, 10);
93
+ if (isNaN(ts)) throw new WebhookVerificationError("Invalid Webhook-Timestamp");
94
+ const now = Math.floor(Date.now() / 1e3);
95
+ if (Math.abs(now - ts) > tolerance) {
96
+ throw new WebhookVerificationError("Webhook timestamp outside tolerance window");
97
+ }
98
+ const secretBytes = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
99
+ const signedContent = `${msgId}.${timestamp}.${payload}`;
100
+ const expected = (0, import_node_crypto.createHmac)("sha256", secretBytes).update(signedContent).digest("base64");
101
+ const expectedSig = `v1,${expected}`;
102
+ const expectedBuf = Buffer.from(expectedSig);
103
+ const matched = signatures.split(" ").some((sig) => {
104
+ const sigBuf = Buffer.from(sig);
105
+ return sigBuf.length === expectedBuf.length && (0, import_node_crypto.timingSafeEqual)(sigBuf, expectedBuf);
106
+ });
107
+ if (!matched) {
108
+ throw new WebhookVerificationError("Invalid webhook signature");
109
+ }
110
+ }
111
+ function parseWebhookEvent(payload, headers, secret, options) {
112
+ verifyWebhook(payload, headers, secret, options);
113
+ const parsed = JSON.parse(payload);
114
+ return parsed;
115
+ }
116
+ var AggAdminClient = class {
117
+ constructor(options) {
118
+ this.baseUrl = options.baseUrl.replace(/\/$/, "");
119
+ this.apiKey = options.apiKey;
120
+ }
121
+ // ── Core HTTP ────────────────────────────────────────────────────────
122
+ request(path, init) {
123
+ return __async(this, null, function* () {
124
+ const response = yield this.rawFetch(path, init);
125
+ if (!response.ok) {
126
+ return this.throwResponseError(response);
127
+ }
128
+ return response.json();
129
+ });
130
+ }
131
+ rawFetch(path, init) {
132
+ return __async(this, null, function* () {
133
+ const headers = {
134
+ "Content-Type": "application/json",
135
+ "x-app-api-key": this.apiKey
136
+ };
137
+ const url = new URL(`${this.baseUrl}${path}`);
138
+ if (init == null ? void 0 : init.query) {
139
+ for (const [key, value] of Object.entries(init.query)) {
140
+ if (value === void 0) continue;
141
+ if (Array.isArray(value)) {
142
+ for (const v of value) url.searchParams.append(key, v);
143
+ } else {
144
+ url.searchParams.set(key, value);
145
+ }
146
+ }
147
+ }
148
+ return fetch(url, __spreadProps(__spreadValues({}, init), {
149
+ headers: __spreadValues(__spreadValues({}, headers), init == null ? void 0 : init.headers)
150
+ }));
151
+ });
152
+ }
153
+ throwResponseError(response) {
154
+ return __async(this, null, function* () {
155
+ let message = `AGG API error: ${response.status} ${response.statusText}`;
156
+ try {
157
+ const body = yield response.json();
158
+ if (typeof body.message === "string" && body.message.length > 0) {
159
+ message = body.message;
160
+ }
161
+ } catch (e) {
162
+ }
163
+ const error = new Error(message);
164
+ error.status = response.status;
165
+ throw error;
166
+ });
167
+ }
168
+ // ── Users ────────────────────────────────────────────────────────────
169
+ listUsers(appId, query) {
170
+ return __async(this, null, function* () {
171
+ var _a;
172
+ return this.request(`/apps/${appId}/users`, {
173
+ query: {
174
+ limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
175
+ cursor: query == null ? void 0 : query.cursor,
176
+ search: query == null ? void 0 : query.search
177
+ }
178
+ });
179
+ });
180
+ }
181
+ getUser(appId, userId) {
182
+ return __async(this, null, function* () {
183
+ return this.request(`/apps/${appId}/users/${userId}`);
184
+ });
185
+ }
186
+ // ── Analytics & Orders ───────────────────────────────────────────────
187
+ getAnalytics(appId) {
188
+ return __async(this, null, function* () {
189
+ return this.request(`/apps/${appId}/analytics`);
190
+ });
191
+ }
192
+ listOrders(appId, query) {
193
+ return __async(this, null, function* () {
194
+ var _a;
195
+ return this.request(`/apps/${appId}/orders`, {
196
+ query: {
197
+ limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
198
+ cursor: query == null ? void 0 : query.cursor,
199
+ venue: query == null ? void 0 : query.venue,
200
+ status: query == null ? void 0 : query.status
201
+ }
202
+ });
203
+ });
204
+ }
205
+ // ── Webhooks ─────────────────────────────────────────────────────────
206
+ rotateWebhookSecret(appId, webhookId) {
207
+ return __async(this, null, function* () {
208
+ return this.request(`/apps/${appId}/webhooks/${webhookId}/rotate-secret`, {
209
+ method: "POST"
210
+ });
211
+ });
212
+ }
213
+ replayWebhookDeliveries(appId, webhookId) {
214
+ return __async(this, null, function* () {
215
+ return this.request(`/apps/${appId}/webhooks/${webhookId}/replay`, {
216
+ method: "POST"
217
+ });
218
+ });
219
+ }
220
+ // ── Market Resolutions ───────────────────────────────────────────────
221
+ listMarketResolutionUsers(appId, venueMarketId, query) {
222
+ return __async(this, null, function* () {
223
+ var _a;
224
+ return this.request(`/apps/${appId}/market-resolutions/${venueMarketId}/users`, {
225
+ query: {
226
+ limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
227
+ cursor: query == null ? void 0 : query.cursor,
228
+ includeEmails: (query == null ? void 0 : query.includeEmails) ? "true" : void 0
229
+ }
230
+ });
231
+ });
232
+ }
233
+ };
234
+ function getHeader(headers, name) {
235
+ var _a;
236
+ const val = (_a = headers[name]) != null ? _a : headers[name.toLowerCase()];
237
+ if (val !== void 0) return Array.isArray(val) ? val[0] : val;
238
+ const lower = name.toLowerCase();
239
+ for (const key of Object.keys(headers)) {
240
+ if (key.toLowerCase() === lower) {
241
+ const v = headers[key];
242
+ return Array.isArray(v) ? v[0] : v;
243
+ }
244
+ }
245
+ return void 0;
246
+ }
247
+ // Annotate the CommonJS export names for ESM import in node:
248
+ 0 && (module.exports = {
249
+ AggAdminClient,
250
+ WebhookVerificationError,
251
+ parseWebhookEvent,
252
+ signExternalId,
253
+ verifyWebhook
254
+ });