@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.
- package/README.md +355 -0
- package/dist/chunk-AXBFBHS2.mjs +45 -0
- package/dist/index.d.mts +2546 -0
- package/dist/index.d.ts +2546 -0
- package/dist/index.js +2581 -0
- package/dist/index.mjs +2483 -0
- package/dist/server.d.mts +155 -0
- package/dist/server.d.ts +155 -0
- package/dist/server.js +254 -0
- package/dist/server.mjs +194 -0
- package/package.json +82 -0
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__async,
|
|
3
|
+
__spreadProps,
|
|
4
|
+
__spreadValues
|
|
5
|
+
} from "./chunk-AXBFBHS2.mjs";
|
|
6
|
+
|
|
7
|
+
// src/server.ts
|
|
8
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
9
|
+
function signExternalId(appSecret, externalId) {
|
|
10
|
+
const timestamp = Date.now();
|
|
11
|
+
const hmac = createHmac("sha256", Buffer.from(appSecret, "hex")).update(`${externalId}:${timestamp}`).digest("hex");
|
|
12
|
+
return {
|
|
13
|
+
externalId,
|
|
14
|
+
timestamp,
|
|
15
|
+
hmac
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
var WebhookVerificationError = class extends Error {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "WebhookVerificationError";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
function verifyWebhook(payload, headers, secret, options) {
|
|
25
|
+
var _a;
|
|
26
|
+
const tolerance = (_a = options == null ? void 0 : options.toleranceSeconds) != null ? _a : 300;
|
|
27
|
+
const msgId = getHeader(headers, "webhook-id");
|
|
28
|
+
const timestamp = getHeader(headers, "webhook-timestamp");
|
|
29
|
+
const signatures = getHeader(headers, "webhook-signature");
|
|
30
|
+
if (!msgId) throw new WebhookVerificationError("Missing Webhook-Id header");
|
|
31
|
+
if (!timestamp) throw new WebhookVerificationError("Missing Webhook-Timestamp header");
|
|
32
|
+
if (!signatures) throw new WebhookVerificationError("Missing Webhook-Signature header");
|
|
33
|
+
const ts = parseInt(timestamp, 10);
|
|
34
|
+
if (isNaN(ts)) throw new WebhookVerificationError("Invalid Webhook-Timestamp");
|
|
35
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
36
|
+
if (Math.abs(now - ts) > tolerance) {
|
|
37
|
+
throw new WebhookVerificationError("Webhook timestamp outside tolerance window");
|
|
38
|
+
}
|
|
39
|
+
const secretBytes = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
|
|
40
|
+
const signedContent = `${msgId}.${timestamp}.${payload}`;
|
|
41
|
+
const expected = createHmac("sha256", secretBytes).update(signedContent).digest("base64");
|
|
42
|
+
const expectedSig = `v1,${expected}`;
|
|
43
|
+
const expectedBuf = Buffer.from(expectedSig);
|
|
44
|
+
const matched = signatures.split(" ").some((sig) => {
|
|
45
|
+
const sigBuf = Buffer.from(sig);
|
|
46
|
+
return sigBuf.length === expectedBuf.length && timingSafeEqual(sigBuf, expectedBuf);
|
|
47
|
+
});
|
|
48
|
+
if (!matched) {
|
|
49
|
+
throw new WebhookVerificationError("Invalid webhook signature");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function parseWebhookEvent(payload, headers, secret, options) {
|
|
53
|
+
verifyWebhook(payload, headers, secret, options);
|
|
54
|
+
const parsed = JSON.parse(payload);
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
var AggAdminClient = class {
|
|
58
|
+
constructor(options) {
|
|
59
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
60
|
+
this.apiKey = options.apiKey;
|
|
61
|
+
}
|
|
62
|
+
// ── Core HTTP ────────────────────────────────────────────────────────
|
|
63
|
+
request(path, init) {
|
|
64
|
+
return __async(this, null, function* () {
|
|
65
|
+
const response = yield this.rawFetch(path, init);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
return this.throwResponseError(response);
|
|
68
|
+
}
|
|
69
|
+
return response.json();
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
rawFetch(path, init) {
|
|
73
|
+
return __async(this, null, function* () {
|
|
74
|
+
const headers = {
|
|
75
|
+
"Content-Type": "application/json",
|
|
76
|
+
"x-app-api-key": this.apiKey
|
|
77
|
+
};
|
|
78
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
79
|
+
if (init == null ? void 0 : init.query) {
|
|
80
|
+
for (const [key, value] of Object.entries(init.query)) {
|
|
81
|
+
if (value === void 0) continue;
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
for (const v of value) url.searchParams.append(key, v);
|
|
84
|
+
} else {
|
|
85
|
+
url.searchParams.set(key, value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return fetch(url, __spreadProps(__spreadValues({}, init), {
|
|
90
|
+
headers: __spreadValues(__spreadValues({}, headers), init == null ? void 0 : init.headers)
|
|
91
|
+
}));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
throwResponseError(response) {
|
|
95
|
+
return __async(this, null, function* () {
|
|
96
|
+
let message = `AGG API error: ${response.status} ${response.statusText}`;
|
|
97
|
+
try {
|
|
98
|
+
const body = yield response.json();
|
|
99
|
+
if (typeof body.message === "string" && body.message.length > 0) {
|
|
100
|
+
message = body.message;
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
}
|
|
104
|
+
const error = new Error(message);
|
|
105
|
+
error.status = response.status;
|
|
106
|
+
throw error;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// ── Users ────────────────────────────────────────────────────────────
|
|
110
|
+
listUsers(appId, query) {
|
|
111
|
+
return __async(this, null, function* () {
|
|
112
|
+
var _a;
|
|
113
|
+
return this.request(`/apps/${appId}/users`, {
|
|
114
|
+
query: {
|
|
115
|
+
limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
|
|
116
|
+
cursor: query == null ? void 0 : query.cursor,
|
|
117
|
+
search: query == null ? void 0 : query.search
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
getUser(appId, userId) {
|
|
123
|
+
return __async(this, null, function* () {
|
|
124
|
+
return this.request(`/apps/${appId}/users/${userId}`);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// ── Analytics & Orders ───────────────────────────────────────────────
|
|
128
|
+
getAnalytics(appId) {
|
|
129
|
+
return __async(this, null, function* () {
|
|
130
|
+
return this.request(`/apps/${appId}/analytics`);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
listOrders(appId, query) {
|
|
134
|
+
return __async(this, null, function* () {
|
|
135
|
+
var _a;
|
|
136
|
+
return this.request(`/apps/${appId}/orders`, {
|
|
137
|
+
query: {
|
|
138
|
+
limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
|
|
139
|
+
cursor: query == null ? void 0 : query.cursor,
|
|
140
|
+
venue: query == null ? void 0 : query.venue,
|
|
141
|
+
status: query == null ? void 0 : query.status
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// ── Webhooks ─────────────────────────────────────────────────────────
|
|
147
|
+
rotateWebhookSecret(appId, webhookId) {
|
|
148
|
+
return __async(this, null, function* () {
|
|
149
|
+
return this.request(`/apps/${appId}/webhooks/${webhookId}/rotate-secret`, {
|
|
150
|
+
method: "POST"
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
replayWebhookDeliveries(appId, webhookId) {
|
|
155
|
+
return __async(this, null, function* () {
|
|
156
|
+
return this.request(`/apps/${appId}/webhooks/${webhookId}/replay`, {
|
|
157
|
+
method: "POST"
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// ── Market Resolutions ───────────────────────────────────────────────
|
|
162
|
+
listMarketResolutionUsers(appId, venueMarketId, query) {
|
|
163
|
+
return __async(this, null, function* () {
|
|
164
|
+
var _a;
|
|
165
|
+
return this.request(`/apps/${appId}/market-resolutions/${venueMarketId}/users`, {
|
|
166
|
+
query: {
|
|
167
|
+
limit: (_a = query == null ? void 0 : query.limit) == null ? void 0 : _a.toString(),
|
|
168
|
+
cursor: query == null ? void 0 : query.cursor,
|
|
169
|
+
includeEmails: (query == null ? void 0 : query.includeEmails) ? "true" : void 0
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
function getHeader(headers, name) {
|
|
176
|
+
var _a;
|
|
177
|
+
const val = (_a = headers[name]) != null ? _a : headers[name.toLowerCase()];
|
|
178
|
+
if (val !== void 0) return Array.isArray(val) ? val[0] : val;
|
|
179
|
+
const lower = name.toLowerCase();
|
|
180
|
+
for (const key of Object.keys(headers)) {
|
|
181
|
+
if (key.toLowerCase() === lower) {
|
|
182
|
+
const v = headers[key];
|
|
183
|
+
return Array.isArray(v) ? v[0] : v;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return void 0;
|
|
187
|
+
}
|
|
188
|
+
export {
|
|
189
|
+
AggAdminClient,
|
|
190
|
+
WebhookVerificationError,
|
|
191
|
+
parseWebhookEvent,
|
|
192
|
+
signExternalId,
|
|
193
|
+
verifyWebhook
|
|
194
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agg-build/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
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
|
+
"sideEffects": false,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://docs.agg.market/",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"agg",
|
|
10
|
+
"agg-market",
|
|
11
|
+
"agg-build",
|
|
12
|
+
"prediction-markets",
|
|
13
|
+
"prediction-market",
|
|
14
|
+
"trading",
|
|
15
|
+
"sdk",
|
|
16
|
+
"typescript",
|
|
17
|
+
"siwe",
|
|
18
|
+
"siws",
|
|
19
|
+
"polymarket",
|
|
20
|
+
"kalshi",
|
|
21
|
+
"orderbook",
|
|
22
|
+
"websocket"
|
|
23
|
+
],
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.mjs",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"typesVersions": {
|
|
28
|
+
"*": {
|
|
29
|
+
"server": [
|
|
30
|
+
"./dist/server.d.ts"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/Snag-Solutions/Agg.git",
|
|
37
|
+
"directory": "packages/sdk"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
],
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"import": {
|
|
45
|
+
"types": "./dist/index.d.mts",
|
|
46
|
+
"default": "./dist/index.mjs"
|
|
47
|
+
},
|
|
48
|
+
"require": {
|
|
49
|
+
"types": "./dist/index.d.ts",
|
|
50
|
+
"default": "./dist/index.js"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"./server": {
|
|
54
|
+
"import": {
|
|
55
|
+
"types": "./dist/server.d.mts",
|
|
56
|
+
"default": "./dist/server.mjs"
|
|
57
|
+
},
|
|
58
|
+
"require": {
|
|
59
|
+
"types": "./dist/server.d.ts",
|
|
60
|
+
"default": "./dist/server.js"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@polymarket/builder-signing-sdk": "^0.0.8",
|
|
66
|
+
"@polymarket/clob-client": "^5.2.3",
|
|
67
|
+
"ethers": "^5.7.2",
|
|
68
|
+
"viem": "^2.46.2"
|
|
69
|
+
},
|
|
70
|
+
"publishConfig": {
|
|
71
|
+
"access": "public"
|
|
72
|
+
},
|
|
73
|
+
"scripts": {
|
|
74
|
+
"build": "tsup",
|
|
75
|
+
"dev": "tsup --watch",
|
|
76
|
+
"test": "pnpm exec vitest run --config vitest.config.ts",
|
|
77
|
+
"test:coverage": "pnpm exec vitest run --config vitest.config.ts --coverage",
|
|
78
|
+
"typecheck": "tsc --noEmit",
|
|
79
|
+
"lint": "eslint . --max-warnings 0",
|
|
80
|
+
"clean": "rm -rf .turbo node_modules dist"
|
|
81
|
+
}
|
|
82
|
+
}
|