@pear-protocol/core-sdk 0.0.24 → 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/dist/admin/index.d.ts +57 -0
- package/dist/admin/index.js +43 -0
- package/dist/auth/index.d.ts +8 -2
- package/dist/auth/index.js +7 -0
- package/dist/core/index.d.ts +627 -2
- package/dist/core/index.js +102 -10
- package/dist/external/index.d.ts +17 -0
- package/dist/external/index.js +25 -0
- package/dist/external/kalshi.d.ts +6 -0
- package/dist/external/kalshi.js +69 -0
- package/dist/external/polymarket.d.ts +6 -0
- package/dist/external/polymarket.js +91 -0
- package/dist/external/types.d.ts +49 -0
- package/dist/external/types.js +1 -0
- package/dist/http.d.ts +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +27 -0
- package/dist/types.d.ts +30 -7
- package/dist/utils.d.ts +1 -0
- package/package.json +3 -3
package/dist/core/index.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
class Core {
|
|
2
2
|
client;
|
|
3
|
-
|
|
3
|
+
clientId;
|
|
4
|
+
constructor(client, clientId) {
|
|
4
5
|
this.client = client;
|
|
6
|
+
this.clientId = clientId;
|
|
7
|
+
}
|
|
8
|
+
// Auto-attach the configured attribution clientId to a request body unless the
|
|
9
|
+
// caller already set one explicitly. Bound to the exact trade / trigger / schedule /
|
|
10
|
+
// rebalance payloads it serves, so an unrelated body is a compile error.
|
|
11
|
+
withClientId(body) {
|
|
12
|
+
if (!this.clientId) return body;
|
|
13
|
+
return { clientId: this.clientId, ...body };
|
|
5
14
|
}
|
|
6
15
|
accounts = {
|
|
7
16
|
list: async (query, headers) => {
|
|
@@ -33,7 +42,7 @@ class Core {
|
|
|
33
42
|
},
|
|
34
43
|
credentials: async (id, headers) => {
|
|
35
44
|
return await this.client.fetch(`/trade-accounts/${id}/credentials`, {
|
|
36
|
-
method: "
|
|
45
|
+
method: "POST",
|
|
37
46
|
headers
|
|
38
47
|
});
|
|
39
48
|
},
|
|
@@ -44,6 +53,27 @@ class Core {
|
|
|
44
53
|
});
|
|
45
54
|
}
|
|
46
55
|
};
|
|
56
|
+
apiKeys = {
|
|
57
|
+
list: async (headers) => {
|
|
58
|
+
return await this.client.fetch(`/api-keys`, {
|
|
59
|
+
method: "GET",
|
|
60
|
+
headers
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
create: async (body, headers) => {
|
|
64
|
+
return await this.client.fetch(`/api-keys`, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers,
|
|
67
|
+
body
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
revoke: async (id, headers) => {
|
|
71
|
+
return await this.client.fetch(`/api-keys/${id}`, {
|
|
72
|
+
method: "DELETE",
|
|
73
|
+
headers
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
};
|
|
47
77
|
executions = {
|
|
48
78
|
list: async (query, headers) => {
|
|
49
79
|
return await this.client.fetch(`/executions`, {
|
|
@@ -99,6 +129,30 @@ class Core {
|
|
|
99
129
|
});
|
|
100
130
|
}
|
|
101
131
|
};
|
|
132
|
+
markets = {
|
|
133
|
+
list: async (query, headers) => {
|
|
134
|
+
return await this.client.fetch(`/markets`, {
|
|
135
|
+
method: "GET",
|
|
136
|
+
headers,
|
|
137
|
+
query
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
baskets: async (query, headers) => {
|
|
141
|
+
return await this.client.fetch(`/markets/baskets`, {
|
|
142
|
+
method: "GET",
|
|
143
|
+
headers,
|
|
144
|
+
query
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
oracle = {
|
|
149
|
+
btcdom: async (headers) => {
|
|
150
|
+
return await this.client.fetch(`/oracle/btcdom`, {
|
|
151
|
+
method: "GET",
|
|
152
|
+
headers
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
};
|
|
102
156
|
positions = {
|
|
103
157
|
list: async (query, headers) => {
|
|
104
158
|
return await this.client.fetch(`/positions`, {
|
|
@@ -114,6 +168,22 @@ class Core {
|
|
|
114
168
|
});
|
|
115
169
|
}
|
|
116
170
|
};
|
|
171
|
+
portfolio = {
|
|
172
|
+
overview: async (query, headers) => {
|
|
173
|
+
return await this.client.fetch(`/portfolio`, {
|
|
174
|
+
method: "GET",
|
|
175
|
+
headers,
|
|
176
|
+
query
|
|
177
|
+
});
|
|
178
|
+
},
|
|
179
|
+
analytics: async (query, headers) => {
|
|
180
|
+
return await this.client.fetch(`/portfolio/analytics`, {
|
|
181
|
+
method: "GET",
|
|
182
|
+
headers,
|
|
183
|
+
query
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
|
117
187
|
prices = {
|
|
118
188
|
list: async (query, headers) => {
|
|
119
189
|
return await this.client.fetch(`/prices`, {
|
|
@@ -128,7 +198,7 @@ class Core {
|
|
|
128
198
|
return await this.client.fetch(`/rebalance/manually/${positionId}`, {
|
|
129
199
|
method: "POST",
|
|
130
200
|
headers,
|
|
131
|
-
body
|
|
201
|
+
body: this.withClientId(body)
|
|
132
202
|
});
|
|
133
203
|
}
|
|
134
204
|
};
|
|
@@ -144,7 +214,7 @@ class Core {
|
|
|
144
214
|
return await this.client.fetch(`/schedules`, {
|
|
145
215
|
method: "POST",
|
|
146
216
|
headers,
|
|
147
|
-
body
|
|
217
|
+
body: this.withClientId(body)
|
|
148
218
|
});
|
|
149
219
|
},
|
|
150
220
|
cancel: async (scheduleId, headers) => {
|
|
@@ -195,28 +265,28 @@ class Core {
|
|
|
195
265
|
return await this.client.fetch(`/trade/open`, {
|
|
196
266
|
method: "POST",
|
|
197
267
|
headers,
|
|
198
|
-
body
|
|
268
|
+
body: this.withClientId(body)
|
|
199
269
|
});
|
|
200
270
|
},
|
|
201
271
|
adjust: async (positionId, body, headers) => {
|
|
202
272
|
return await this.client.fetch(`/trade/${positionId}/adjust`, {
|
|
203
273
|
method: "POST",
|
|
204
274
|
headers,
|
|
205
|
-
body
|
|
275
|
+
body: this.withClientId(body)
|
|
206
276
|
});
|
|
207
277
|
},
|
|
208
278
|
close: async (positionId, body, headers) => {
|
|
209
279
|
return await this.client.fetch(`/trade/${positionId}/close`, {
|
|
210
280
|
method: "POST",
|
|
211
281
|
headers,
|
|
212
|
-
body
|
|
282
|
+
body: this.withClientId(body)
|
|
213
283
|
});
|
|
214
284
|
},
|
|
215
285
|
closeAll: async (body, headers) => {
|
|
216
286
|
return await this.client.fetch(`/trade/close-all`, {
|
|
217
287
|
method: "POST",
|
|
218
288
|
headers,
|
|
219
|
-
body
|
|
289
|
+
body: this.withClientId(body)
|
|
220
290
|
});
|
|
221
291
|
},
|
|
222
292
|
setLeverage: async (body, headers) => {
|
|
@@ -239,14 +309,14 @@ class Core {
|
|
|
239
309
|
return await this.client.fetch(`/triggers/open`, {
|
|
240
310
|
method: "POST",
|
|
241
311
|
headers,
|
|
242
|
-
body
|
|
312
|
+
body: this.withClientId(body)
|
|
243
313
|
});
|
|
244
314
|
},
|
|
245
315
|
close: async (body, headers) => {
|
|
246
316
|
return await this.client.fetch(`/triggers/close`, {
|
|
247
317
|
method: "POST",
|
|
248
318
|
headers,
|
|
249
|
-
body
|
|
319
|
+
body: this.withClientId(body)
|
|
250
320
|
});
|
|
251
321
|
},
|
|
252
322
|
cancel: async (triggerId, headers) => {
|
|
@@ -345,6 +415,28 @@ class Core {
|
|
|
345
415
|
});
|
|
346
416
|
}
|
|
347
417
|
};
|
|
418
|
+
tca = {
|
|
419
|
+
execution: async (executionId, headers) => {
|
|
420
|
+
return await this.client.fetch(`/tca/executions/${executionId}`, {
|
|
421
|
+
method: "GET",
|
|
422
|
+
headers
|
|
423
|
+
});
|
|
424
|
+
},
|
|
425
|
+
position: async (positionId, query, headers) => {
|
|
426
|
+
return await this.client.fetch(`/tca/positions/${positionId}`, {
|
|
427
|
+
method: "GET",
|
|
428
|
+
headers,
|
|
429
|
+
query
|
|
430
|
+
});
|
|
431
|
+
},
|
|
432
|
+
summary: async (query, headers) => {
|
|
433
|
+
return await this.client.fetch(`/tca/summary`, {
|
|
434
|
+
method: "GET",
|
|
435
|
+
headers,
|
|
436
|
+
query
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
};
|
|
348
440
|
}
|
|
349
441
|
|
|
350
442
|
export { Core };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SearchTriggersParams, SearchTriggersResponse } from '@pear-protocol/types';
|
|
2
|
+
export { ExternalTrigger, ExternalTriggerSource, SearchTriggersParams, SearchTriggersResponse, TriggerOutcome } from '@pear-protocol/types';
|
|
3
|
+
|
|
4
|
+
declare class External {
|
|
5
|
+
triggers: {
|
|
6
|
+
kalshi: {
|
|
7
|
+
marketNames: (tickers: string[]) => Promise<Map<string, string>>;
|
|
8
|
+
search: (params?: SearchTriggersParams) => Promise<SearchTriggersResponse>;
|
|
9
|
+
};
|
|
10
|
+
polymarket: {
|
|
11
|
+
marketNames: (ids: string[]) => Promise<Map<string, string>>;
|
|
12
|
+
search: (params?: SearchTriggersParams) => Promise<SearchTriggersResponse>;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { External };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { searchKalshiTriggers, fetchKalshiMarketNames } from './kalshi';
|
|
2
|
+
import { searchPolymarketTriggers, fetchPolymarketMarketNames } from './polymarket';
|
|
3
|
+
|
|
4
|
+
class External {
|
|
5
|
+
triggers = {
|
|
6
|
+
kalshi: {
|
|
7
|
+
marketNames: async (tickers) => {
|
|
8
|
+
return fetchKalshiMarketNames(tickers);
|
|
9
|
+
},
|
|
10
|
+
search: async (params = {}) => {
|
|
11
|
+
return searchKalshiTriggers(params);
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
polymarket: {
|
|
15
|
+
marketNames: async (ids) => {
|
|
16
|
+
return fetchPolymarketMarketNames(ids);
|
|
17
|
+
},
|
|
18
|
+
search: async (params = {}) => {
|
|
19
|
+
return searchPolymarketTriggers(params);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { External };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SearchTriggersParams, SearchTriggersResponse } from '@pear-protocol/types';
|
|
2
|
+
|
|
3
|
+
declare function fetchKalshiMarketNames(tickers: string[]): Promise<Map<string, string>>;
|
|
4
|
+
declare function searchKalshiTriggers(params?: SearchTriggersParams): Promise<SearchTriggersResponse>;
|
|
5
|
+
|
|
6
|
+
export { fetchKalshiMarketNames, searchKalshiTriggers };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const BASE_URL = "https://api.elections.kalshi.com";
|
|
2
|
+
const BATCH_SIZE = 100;
|
|
3
|
+
async function fetchKalshiMarketNames(tickers) {
|
|
4
|
+
const result = /* @__PURE__ */ new Map();
|
|
5
|
+
for (let i = 0; i < tickers.length; i += BATCH_SIZE) {
|
|
6
|
+
const batch = tickers.slice(i, i + BATCH_SIZE);
|
|
7
|
+
const url = new URL(`${BASE_URL}/trade-api/v2/markets`);
|
|
8
|
+
url.searchParams.set("tickers", batch.join(","));
|
|
9
|
+
url.searchParams.set("limit", String(BATCH_SIZE));
|
|
10
|
+
const response = await fetch(url, { method: "GET", headers: { accept: "application/json" } });
|
|
11
|
+
if (!response.ok) throw new Error(`Kalshi API error: ${response.status} ${response.statusText}`);
|
|
12
|
+
const data = await response.json();
|
|
13
|
+
for (const m of data.markets ?? []) result.set(m.ticker, m.title);
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
async function searchKalshiTriggers(params = {}) {
|
|
18
|
+
const url = new URL(`${BASE_URL}/v1/search/series`);
|
|
19
|
+
url.searchParams.set("order_by", "trending");
|
|
20
|
+
url.searchParams.set("status", "open");
|
|
21
|
+
url.searchParams.set("page_size", String(params.pageSize ?? 50));
|
|
22
|
+
if (params.category) url.searchParams.set("category", params.category);
|
|
23
|
+
if (params.search) url.searchParams.set("query", params.search);
|
|
24
|
+
if (params.cursor) url.searchParams.set("cursor", params.cursor);
|
|
25
|
+
const response = await fetch(url, { method: "GET", headers: { accept: "application/json" } });
|
|
26
|
+
if (!response.ok) return { triggers: [], nextCursor: null };
|
|
27
|
+
const data = await response.json();
|
|
28
|
+
return {
|
|
29
|
+
triggers: (data.current_page ?? []).map(mapEventToTrigger),
|
|
30
|
+
nextCursor: data.next_cursor || null
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function mapEventToTrigger(event) {
|
|
34
|
+
const imageUrl = `https://kalshi-public-docs.s3.amazonaws.com/series-images-webp/${event.event_ticker.split("-")[0]}.webp`;
|
|
35
|
+
if (event.markets.length > 1) {
|
|
36
|
+
return {
|
|
37
|
+
id: event.event_ticker,
|
|
38
|
+
category: "prediction_market",
|
|
39
|
+
source: "kalshi",
|
|
40
|
+
selectable: false,
|
|
41
|
+
oracle: null,
|
|
42
|
+
options: event.markets.map(mapMarketToOutcome),
|
|
43
|
+
type: "multi",
|
|
44
|
+
title: event.event_title,
|
|
45
|
+
imageUrl
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const market = event.markets[0];
|
|
49
|
+
return {
|
|
50
|
+
id: market?.ticker ?? event.event_ticker,
|
|
51
|
+
category: "prediction_market",
|
|
52
|
+
source: "kalshi",
|
|
53
|
+
selectable: true,
|
|
54
|
+
oracle: market?.last_price ?? null,
|
|
55
|
+
options: [],
|
|
56
|
+
type: "binary",
|
|
57
|
+
title: event.event_title,
|
|
58
|
+
imageUrl
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function mapMarketToOutcome(market) {
|
|
62
|
+
return {
|
|
63
|
+
id: market.ticker,
|
|
64
|
+
label: market.yes_subtitle || market.title,
|
|
65
|
+
oracle: market.last_price
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { fetchKalshiMarketNames, searchKalshiTriggers };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SearchTriggersParams, SearchTriggersResponse } from '@pear-protocol/types';
|
|
2
|
+
|
|
3
|
+
declare function fetchPolymarketMarketNames(ids: string[]): Promise<Map<string, string>>;
|
|
4
|
+
declare function searchPolymarketTriggers(params?: SearchTriggersParams): Promise<SearchTriggersResponse>;
|
|
5
|
+
|
|
6
|
+
export { fetchPolymarketMarketNames, searchPolymarketTriggers };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const BASE_URL = "https://gamma-api.polymarket.com";
|
|
2
|
+
const BATCH_SIZE = 100;
|
|
3
|
+
async function fetchPolymarketMarketNames(ids) {
|
|
4
|
+
const result = /* @__PURE__ */ new Map();
|
|
5
|
+
for (let i = 0; i < ids.length; i += BATCH_SIZE) {
|
|
6
|
+
const batch = ids.slice(i, i + BATCH_SIZE);
|
|
7
|
+
const url = new URL(`${BASE_URL}/markets`);
|
|
8
|
+
for (const id of batch) url.searchParams.append("id", id);
|
|
9
|
+
url.searchParams.set("limit", String(BATCH_SIZE));
|
|
10
|
+
const response = await fetch(url, { method: "GET", headers: { accept: "application/json" } });
|
|
11
|
+
if (!response.ok) throw new Error(`Polymarket API error: ${response.status} ${response.statusText}`);
|
|
12
|
+
const data = await response.json();
|
|
13
|
+
for (const m of data) result.set(m.id, m.question ?? m.groupItemTitle ?? "");
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
async function searchPolymarketTriggers(params = {}) {
|
|
18
|
+
const url = new URL(`${BASE_URL}/events/keyset`);
|
|
19
|
+
url.searchParams.set("closed", "false");
|
|
20
|
+
url.searchParams.set("limit", String(params.pageSize ?? 50));
|
|
21
|
+
url.searchParams.set("order", "volume24hr");
|
|
22
|
+
url.searchParams.set("ascending", "false");
|
|
23
|
+
if (params.search) url.searchParams.set("title_search", params.search);
|
|
24
|
+
if (params.category) url.searchParams.set("tag_slug", params.category);
|
|
25
|
+
if (params.cursor) url.searchParams.set("after_cursor", params.cursor);
|
|
26
|
+
const response = await fetch(url, { method: "GET", headers: { accept: "application/json" } });
|
|
27
|
+
if (!response.ok) return { triggers: [], nextCursor: null };
|
|
28
|
+
const data = await response.json();
|
|
29
|
+
const events = data.events ?? [];
|
|
30
|
+
return {
|
|
31
|
+
triggers: events.map(mapEventToTrigger).filter((t) => t !== null),
|
|
32
|
+
nextCursor: data.next_cursor ?? null
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function mapEventToTrigger(event) {
|
|
36
|
+
const markets = (event.markets ?? []).filter((m) => m.active !== false && m.closed !== true);
|
|
37
|
+
const [first] = markets;
|
|
38
|
+
if (!first) return null;
|
|
39
|
+
if (markets.length === 1) {
|
|
40
|
+
return {
|
|
41
|
+
id: first.id,
|
|
42
|
+
category: "prediction_market",
|
|
43
|
+
source: "polymarket",
|
|
44
|
+
selectable: true,
|
|
45
|
+
oracle: parseYesCents(first),
|
|
46
|
+
options: [],
|
|
47
|
+
type: "binary",
|
|
48
|
+
title: first.question ?? event.title ?? first.groupItemTitle ?? first.id,
|
|
49
|
+
imageUrl: first.image ?? first.icon ?? event.image ?? event.icon ?? null
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
id: event.id ?? event.slug ?? first.id,
|
|
54
|
+
category: "prediction_market",
|
|
55
|
+
source: "polymarket",
|
|
56
|
+
selectable: false,
|
|
57
|
+
oracle: null,
|
|
58
|
+
options: markets.map(mapMarketToOutcome),
|
|
59
|
+
type: "multi",
|
|
60
|
+
title: event.title ?? first.question ?? event.id,
|
|
61
|
+
imageUrl: event.image ?? event.icon ?? first.image ?? first.icon ?? null
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function mapMarketToOutcome(market) {
|
|
65
|
+
return {
|
|
66
|
+
id: market.id,
|
|
67
|
+
label: market.groupItemTitle ?? market.question ?? market.id,
|
|
68
|
+
oracle: parseYesCents(market)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function parseYesCents(market) {
|
|
72
|
+
const outcomes = parseStringArray(market.outcomes);
|
|
73
|
+
const prices = parseStringArray(market.outcomePrices);
|
|
74
|
+
const yesIndex = outcomes.findIndex((o) => o.toLowerCase() === "yes");
|
|
75
|
+
if (yesIndex < 0) return null;
|
|
76
|
+
const price = Number(prices[yesIndex] ?? "");
|
|
77
|
+
if (!Number.isFinite(price)) return null;
|
|
78
|
+
return Math.round(price * 1e4) / 100;
|
|
79
|
+
}
|
|
80
|
+
function parseStringArray(value) {
|
|
81
|
+
if (Array.isArray(value)) return value.map(String);
|
|
82
|
+
if (!value) return [];
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(value);
|
|
85
|
+
return Array.isArray(parsed) ? parsed.map(String) : [];
|
|
86
|
+
} catch {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { fetchPolymarketMarketNames, searchPolymarketTriggers };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export { ExternalTrigger, ExternalTriggerSource, SearchTriggersParams, SearchTriggersResponse, TriggerOutcome } from '@pear-protocol/types';
|
|
2
|
+
|
|
3
|
+
type KalshiMarket = {
|
|
4
|
+
ticker: string;
|
|
5
|
+
title: string;
|
|
6
|
+
};
|
|
7
|
+
type KalshiMarketsResponse = {
|
|
8
|
+
markets: KalshiMarket[];
|
|
9
|
+
};
|
|
10
|
+
type KalshiSearchSeriesMarket = {
|
|
11
|
+
ticker: string;
|
|
12
|
+
yes_subtitle: string;
|
|
13
|
+
last_price: number;
|
|
14
|
+
title: string;
|
|
15
|
+
};
|
|
16
|
+
type KalshiSearchSeriesEvent = {
|
|
17
|
+
event_ticker: string;
|
|
18
|
+
event_title: string;
|
|
19
|
+
markets: KalshiSearchSeriesMarket[];
|
|
20
|
+
};
|
|
21
|
+
type KalshiSearchSeriesResponse = {
|
|
22
|
+
current_page: KalshiSearchSeriesEvent[];
|
|
23
|
+
next_cursor: string;
|
|
24
|
+
};
|
|
25
|
+
type PolymarketMarket = {
|
|
26
|
+
id: string;
|
|
27
|
+
question?: string;
|
|
28
|
+
image?: string;
|
|
29
|
+
icon?: string;
|
|
30
|
+
active?: boolean;
|
|
31
|
+
closed?: boolean;
|
|
32
|
+
groupItemTitle?: string;
|
|
33
|
+
outcomes?: string[] | string;
|
|
34
|
+
outcomePrices?: string[] | string;
|
|
35
|
+
};
|
|
36
|
+
type PolymarketEvent = {
|
|
37
|
+
id: string;
|
|
38
|
+
slug?: string;
|
|
39
|
+
title?: string;
|
|
40
|
+
image?: string;
|
|
41
|
+
icon?: string;
|
|
42
|
+
markets?: PolymarketMarket[];
|
|
43
|
+
};
|
|
44
|
+
type PolymarketKeysetEventsResponse = {
|
|
45
|
+
events?: PolymarketEvent[];
|
|
46
|
+
next_cursor?: string | null;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type { KalshiMarket, KalshiMarketsResponse, KalshiSearchSeriesEvent, KalshiSearchSeriesMarket, KalshiSearchSeriesResponse, PolymarketEvent, PolymarketKeysetEventsResponse, PolymarketMarket };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/dist/http.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import { Admin } from './admin/index.js';
|
|
1
2
|
import { Auth } from './auth/index.js';
|
|
2
3
|
import { Core } from './core/index.js';
|
|
4
|
+
import { External } from './external/index.js';
|
|
3
5
|
import { SDKConfig } from './types.js';
|
|
4
|
-
export { HttpTypes } from '@pear-protocol/types';
|
|
6
|
+
export { ExternalTrigger, ExternalTriggerSource, HttpTypes, SearchTriggersParams, SearchTriggersResponse, TriggerOutcome } from '@pear-protocol/types';
|
|
5
7
|
export * from '@pear-protocol/utils';
|
|
6
8
|
import './http.js';
|
|
7
9
|
|
|
8
10
|
declare class PearSDK {
|
|
11
|
+
admin: Admin;
|
|
9
12
|
auth: Auth;
|
|
10
13
|
core: Core;
|
|
14
|
+
external: External;
|
|
11
15
|
constructor(config: SDKConfig);
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
export { PearSDK as default };
|
|
18
|
+
export { External, PearSDK as default };
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import { Admin } from './admin';
|
|
1
2
|
import { Auth } from './auth';
|
|
2
3
|
import { Core } from './core';
|
|
4
|
+
import { External } from './external';
|
|
5
|
+
export { External } from './external';
|
|
3
6
|
import { HttpClient } from './http';
|
|
4
7
|
import { FetchError } from './utils';
|
|
5
8
|
export * from '@pear-protocol/utils';
|
|
6
9
|
|
|
7
10
|
class PearSDK {
|
|
11
|
+
admin;
|
|
8
12
|
auth;
|
|
9
13
|
core;
|
|
14
|
+
external;
|
|
10
15
|
constructor(config) {
|
|
11
16
|
const authMode = config.auth?.type ?? "session";
|
|
12
17
|
const logger = config.logger ?? {
|
|
@@ -17,8 +22,10 @@ class PearSDK {
|
|
|
17
22
|
}
|
|
18
23
|
};
|
|
19
24
|
const client = new HttpClient(config.url, authMode, config.logger, config.debug);
|
|
25
|
+
this.admin = new Admin(client);
|
|
20
26
|
this.auth = new Auth(client);
|
|
21
27
|
this.core = new Core(client);
|
|
28
|
+
this.external = new External();
|
|
22
29
|
if (authMode === "session") {
|
|
23
30
|
let refreshInFlight = null;
|
|
24
31
|
const refreshSession = async () => {
|
|
@@ -70,6 +77,26 @@ class PearSDK {
|
|
|
70
77
|
});
|
|
71
78
|
}
|
|
72
79
|
}
|
|
80
|
+
if (authMode === "apikey" && config.auth?.key) {
|
|
81
|
+
const getKey = config.auth.key;
|
|
82
|
+
client.useRequest(async (request, next) => {
|
|
83
|
+
const key = getKey();
|
|
84
|
+
if (key) {
|
|
85
|
+
request.headers.set("x-api-key", key);
|
|
86
|
+
}
|
|
87
|
+
return next();
|
|
88
|
+
});
|
|
89
|
+
if (config.onAuthError) {
|
|
90
|
+
const onAuthError = config.onAuthError;
|
|
91
|
+
client.useResponse(async (response) => {
|
|
92
|
+
if (response.status === 401) {
|
|
93
|
+
onAuthError();
|
|
94
|
+
throw new FetchError("Unauthorized. API key may be expired or revoked.", "Unauthorized", 401);
|
|
95
|
+
}
|
|
96
|
+
return response;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
73
100
|
if (config.getTradeAccountId) {
|
|
74
101
|
const getTradeAccountId = config.getTradeAccountId;
|
|
75
102
|
client.useRequest(async (request, next) => {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { HttpTypes } from '@pear-protocol/types';
|
|
2
|
+
|
|
3
|
+
type AuthMode = 'session' | 'bearer' | 'apikey';
|
|
2
4
|
type SDKConfig = {
|
|
3
5
|
/**
|
|
4
6
|
* API endpoint.
|
|
@@ -16,17 +18,28 @@ type SDKConfig = {
|
|
|
16
18
|
*
|
|
17
19
|
* Bearer:
|
|
18
20
|
* Token set on every request via `Authorization` header. Provide
|
|
19
|
-
* `token` getter to supply the
|
|
20
|
-
* If 401, caller handles re-auth. Used by headless
|
|
21
|
+
* `token` getter to supply the JWT. No client-side refresh.
|
|
22
|
+
* If 401, caller handles re-auth. Used by headless JWT clients.
|
|
23
|
+
*
|
|
24
|
+
* Apikey:
|
|
25
|
+
* API key sent on every request via the `x-api-key` header. Provide
|
|
26
|
+
* `key` getter. No cookies, no client-side refresh. If 401, caller
|
|
27
|
+
* handles re-auth. Used by programmatic API-key clients.
|
|
21
28
|
*/
|
|
22
29
|
auth?: {
|
|
23
30
|
type: AuthMode;
|
|
24
31
|
/**
|
|
25
|
-
* Token getter for bearer mode (e.g. () =>
|
|
32
|
+
* Token getter for bearer mode (e.g. () => jwt). Ignored in other modes.
|
|
26
33
|
*
|
|
27
|
-
* Example: () => localStorage.getItem('
|
|
34
|
+
* Example: () => localStorage.getItem('accessToken')
|
|
28
35
|
*/
|
|
29
36
|
token?: () => string | null;
|
|
37
|
+
/**
|
|
38
|
+
* API key getter for apikey mode. Ignored in other modes.
|
|
39
|
+
*
|
|
40
|
+
* Example: () => localStorage.getItem('apiKey')
|
|
41
|
+
*/
|
|
42
|
+
key?: () => string | null;
|
|
30
43
|
};
|
|
31
44
|
/**
|
|
32
45
|
* Trade account ID getter (used in both modes)
|
|
@@ -35,7 +48,16 @@ type SDKConfig = {
|
|
|
35
48
|
*/
|
|
36
49
|
getTradeAccountId?: () => string | null;
|
|
37
50
|
/**
|
|
38
|
-
*
|
|
51
|
+
* Default attribution client code (client_ids.code). When set, it is
|
|
52
|
+
* auto-added to the body of trade / trigger / schedule / rebalance requests
|
|
53
|
+
* unless the call already specifies its own `clientId`. `null`/omitted →
|
|
54
|
+
* nothing is added.
|
|
55
|
+
*
|
|
56
|
+
* Example: 'AGENTPEAR'
|
|
57
|
+
*/
|
|
58
|
+
clientId?: string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Called when server returns 401 (bearer / apikey mode).
|
|
39
61
|
*
|
|
40
62
|
* Example: () => {
|
|
41
63
|
* console.error('Unauthorized. Token may be expired or revoked.');
|
|
@@ -89,5 +111,6 @@ type FetchArgs = Omit<RequestInit, 'headers' | 'body'> & {
|
|
|
89
111
|
};
|
|
90
112
|
type RequestMiddleware = (request: Request, next: () => Promise<Response>) => Promise<Response>;
|
|
91
113
|
type ResponseMiddleware = (response: Response, retry: () => Promise<Response>, request: Request) => Promise<Response>;
|
|
114
|
+
type ClientIdBody = HttpTypes.RebalanceManually | HttpTypes.CreateSchedule | HttpTypes.CreateTradeOpen | HttpTypes.CreateTradeAdjust | HttpTypes.CreateTradeClose | HttpTypes.CreateTradeCloseAll | HttpTypes.CreateTriggerOpen | HttpTypes.CreateTriggerClose;
|
|
92
115
|
|
|
93
|
-
export type { AuthMode, ClientHeaders, FetchArgs, FetchInput, FetchParams, Logger, RequestMiddleware, ResponseMiddleware, SDKConfig };
|
|
116
|
+
export type { AuthMode, ClientHeaders, ClientIdBody, FetchArgs, FetchInput, FetchParams, Logger, RequestMiddleware, ResponseMiddleware, SDKConfig };
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FetchArgs, AuthMode } from './types.js';
|
|
2
|
+
import '@pear-protocol/types';
|
|
2
3
|
|
|
3
4
|
declare function getBaseUrl(passedBaseUrl: string): string;
|
|
4
5
|
declare function normalizeRequest(init: FetchArgs | undefined, headers: Headers, authMode: AuthMode): RequestInit | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pear-protocol/core-sdk",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Pear Protocol Core SDK",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@pear-protocol/types": "^0.0
|
|
29
|
-
"@pear-protocol/utils": "^0.0.
|
|
28
|
+
"@pear-protocol/types": "^1.0.0",
|
|
29
|
+
"@pear-protocol/utils": "^0.0.23",
|
|
30
30
|
"qs": "^6.14.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|