@stellar-light/api-client 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 +109 -0
- package/dist/index.d.ts +878 -0
- package/dist/index.js +129 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# `@stellar-light/api-client`
|
|
2
|
+
|
|
3
|
+
Typed TypeScript client for the [Stellar Scout API](https://stellarlight.xyz/scout) — projects, builders, hackathons, SCF funding, audits, and research for the Stellar ecosystem.
|
|
4
|
+
|
|
5
|
+
**Zero runtime dependencies.** Native `fetch`, works in Node 20+, browsers, and edge runtimes. Types are generated from the live [OpenAPI 3.1 spec](https://stellarlight.xyz/api/openapi.json).
|
|
6
|
+
|
|
7
|
+
## Which package do I want?
|
|
8
|
+
|
|
9
|
+
| You are building… | Use |
|
|
10
|
+
|---|---|
|
|
11
|
+
| An autonomous agent or aggregator that calls the API directly | **this package** |
|
|
12
|
+
| A human-driven MCP client (Claude Desktop, Cursor, ChatGPT) | [`@stellar-light/scout-mcp`](https://www.npmjs.com/package/@stellar-light/scout-mcp) |
|
|
13
|
+
| With an agent that loads `SKILL.md` (Claude Code, Codex, OpenClaw) | `npx skills add Stellar-Light/stellar-scout` |
|
|
14
|
+
| Your own client from the spec | `npx openapi-typescript https://stellarlight.xyz/api/openapi.json -o scout.d.ts` |
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @stellar-light/api-client
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { ScoutClient } from "@stellar-light/api-client";
|
|
26
|
+
|
|
27
|
+
const scout = new ScoutClient();
|
|
28
|
+
|
|
29
|
+
// Has anyone already built this?
|
|
30
|
+
const { projects, meta } = await scout.searchProjects({
|
|
31
|
+
q: "stablecoin off-ramp",
|
|
32
|
+
scfAwarded: true,
|
|
33
|
+
limit: 5,
|
|
34
|
+
});
|
|
35
|
+
console.log(meta.matchMode, projects.map((p) => p.name));
|
|
36
|
+
|
|
37
|
+
// What's currently fundable?
|
|
38
|
+
const { rfps } = await scout.getRfps({ status: "open" });
|
|
39
|
+
|
|
40
|
+
// Search the research corpus (SEPs, audits, papers, SCF Handbook…)
|
|
41
|
+
const research = await scout.searchResearch({
|
|
42
|
+
q: "SEP-24 anchor security",
|
|
43
|
+
source: "audit",
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## All methods
|
|
48
|
+
|
|
49
|
+
| Method | Endpoint |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `getStatus()` | `GET /api/status` |
|
|
52
|
+
| `searchProjects(params)` | `GET /api/projects/search` |
|
|
53
|
+
| `getHackathons(params)` | `GET /api/hackathons` |
|
|
54
|
+
| `getHackathon(slug)` | `GET /api/hackathons/{slug}` |
|
|
55
|
+
| `compareHackathons(slugs)` | `GET /api/hackathons/compare` |
|
|
56
|
+
| `getBuilders(params)` | `GET /api/builders` |
|
|
57
|
+
| `getRfps(params)` | `GET /api/rfps` |
|
|
58
|
+
| `searchResearch(params)` | `GET /api/research` |
|
|
59
|
+
| `listSkills(params)` | `GET /api/skills` |
|
|
60
|
+
| `getSkill(name)` | `GET /api/skills/{name}` |
|
|
61
|
+
| `getClusters(params)` | `GET /api/clusters` |
|
|
62
|
+
| `analyzeEcosystem(params)` | `GET /api/analyze` |
|
|
63
|
+
| `getLeaderboard(params)` | `GET /api/leaderboard` |
|
|
64
|
+
| `submitFeedback(body)` | `POST /api/feedback` |
|
|
65
|
+
|
|
66
|
+
All endpoints are public, read-only (except feedback), no auth, edge-cached.
|
|
67
|
+
|
|
68
|
+
## Options
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const scout = new ScoutClient({
|
|
72
|
+
baseUrl: "https://stellarlight.xyz", // default
|
|
73
|
+
timeoutMs: 30_000, // default
|
|
74
|
+
headers: { "x-agent-name": "my-aggregator" }, // identify yourself (appreciated!)
|
|
75
|
+
fetch: customFetch, // testing / instrumentation
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Errors
|
|
80
|
+
|
|
81
|
+
Non-2xx responses throw `ScoutApiError` with `.status`, `.url`, and the parsed error `.body`:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { ScoutApiError } from "@stellar-light/api-client";
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await scout.getSkill("nope");
|
|
88
|
+
} catch (err) {
|
|
89
|
+
if (err instanceof ScoutApiError && err.status === 404) {
|
|
90
|
+
// handle unknown slug
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Data sources behind the API
|
|
96
|
+
|
|
97
|
+
The endpoints merge: the stellarlight directory (~741 curated Stellar projects), Stellar Passport builder profiles, Electric Capital developer activity, the Soroban audit corpus (Certora, OtterSec, Halborn, OpenZeppelin, Code4rena…), SDF's skills.stellar.org catalog, lumenloop ecosystem data, and primary research (SEPs, Mazières SCP paper, dev docs, SCF Handbook) — 4,541 embedded chunks searchable via `searchResearch`.
|
|
98
|
+
|
|
99
|
+
## Regenerating types
|
|
100
|
+
|
|
101
|
+
Types live in `src/schema.ts`, generated from the live spec:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pnpm generate
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT — [stellarlight.xyz](https://stellarlight.xyz)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,878 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was auto-generated by openapi-typescript.
|
|
3
|
+
* Do not make direct changes to the file.
|
|
4
|
+
*/
|
|
5
|
+
interface paths {
|
|
6
|
+
"/api/status": {
|
|
7
|
+
parameters: {
|
|
8
|
+
query?: never;
|
|
9
|
+
header?: never;
|
|
10
|
+
path?: never;
|
|
11
|
+
cookie?: never;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Service health + endpoint enumeration
|
|
15
|
+
* @description Returns service health, data-source freshness per collection, and a self-describing enumeration of all 14 endpoints. Useful as a self-discovery call before making other queries.
|
|
16
|
+
*/
|
|
17
|
+
get: {
|
|
18
|
+
parameters: {
|
|
19
|
+
query?: never;
|
|
20
|
+
header?: never;
|
|
21
|
+
path?: never;
|
|
22
|
+
cookie?: never;
|
|
23
|
+
};
|
|
24
|
+
requestBody?: never;
|
|
25
|
+
responses: {
|
|
26
|
+
/** @description Service status */
|
|
27
|
+
200: {
|
|
28
|
+
headers: {
|
|
29
|
+
[name: string]: unknown;
|
|
30
|
+
};
|
|
31
|
+
content: {
|
|
32
|
+
"application/json": components["schemas"]["StatusResponse"];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
put?: never;
|
|
38
|
+
post?: never;
|
|
39
|
+
delete?: never;
|
|
40
|
+
options?: never;
|
|
41
|
+
head?: never;
|
|
42
|
+
patch?: never;
|
|
43
|
+
trace?: never;
|
|
44
|
+
};
|
|
45
|
+
"/api/projects/search": {
|
|
46
|
+
parameters: {
|
|
47
|
+
query?: never;
|
|
48
|
+
header?: never;
|
|
49
|
+
path?: never;
|
|
50
|
+
cookie?: never;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Search Stellar projects (prior art / competitor lookup)
|
|
54
|
+
* @description Search 741+ curated Stellar projects with tiered match-mode (strict → loose → majority). Tier surfaced as `.meta.matchMode` so agents convey relevance honestly. Essential for *'has anyone already built this?'* gap-classification questions.
|
|
55
|
+
*/
|
|
56
|
+
get: {
|
|
57
|
+
parameters: {
|
|
58
|
+
query?: {
|
|
59
|
+
/** @description Keyword query (free text) */
|
|
60
|
+
q?: components["parameters"]["q"];
|
|
61
|
+
/** @description Filter by category */
|
|
62
|
+
category?: "Infrastructure" | "Tooling" | "User-Facing App" | "Asset" | "Protocol/Contract" | "Anchor" | "Partner Integration";
|
|
63
|
+
/** @description Filter by hackathon slug */
|
|
64
|
+
hackathon?: string;
|
|
65
|
+
/** @description Filter to SCF-funded projects only */
|
|
66
|
+
scfAwarded?: boolean;
|
|
67
|
+
/** @description Max results returned */
|
|
68
|
+
limit?: components["parameters"]["limit"];
|
|
69
|
+
};
|
|
70
|
+
header?: never;
|
|
71
|
+
path?: never;
|
|
72
|
+
cookie?: never;
|
|
73
|
+
};
|
|
74
|
+
requestBody?: never;
|
|
75
|
+
responses: {
|
|
76
|
+
/** @description Project search results */
|
|
77
|
+
200: {
|
|
78
|
+
headers: {
|
|
79
|
+
[name: string]: unknown;
|
|
80
|
+
};
|
|
81
|
+
content: {
|
|
82
|
+
"application/json": components["schemas"]["ProjectSearchResponse"];
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
put?: never;
|
|
88
|
+
post?: never;
|
|
89
|
+
delete?: never;
|
|
90
|
+
options?: never;
|
|
91
|
+
head?: never;
|
|
92
|
+
patch?: never;
|
|
93
|
+
trace?: never;
|
|
94
|
+
};
|
|
95
|
+
"/api/hackathons": {
|
|
96
|
+
parameters: {
|
|
97
|
+
query?: never;
|
|
98
|
+
header?: never;
|
|
99
|
+
path?: never;
|
|
100
|
+
cookie?: never;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* List Stellar hackathons
|
|
104
|
+
* @description Returns curated Stellar hackathons + live DoraHacks events. Empty status-scoped queries include fallback channels (BuildOnStellar / stellarlight / DoraHacks) so agents can route users to live announcement sources.
|
|
105
|
+
*/
|
|
106
|
+
get: {
|
|
107
|
+
parameters: {
|
|
108
|
+
query?: {
|
|
109
|
+
/** @description Filter by event status */
|
|
110
|
+
status?: "upcoming" | "active" | "completed";
|
|
111
|
+
/** @description Filter by organizer slug */
|
|
112
|
+
organizer?: string;
|
|
113
|
+
/** @description Restrict to one feed (curated vs DoraHacks) */
|
|
114
|
+
source?: "curated" | "dorahacks";
|
|
115
|
+
/** @description Max results returned */
|
|
116
|
+
limit?: components["parameters"]["limit"];
|
|
117
|
+
};
|
|
118
|
+
header?: never;
|
|
119
|
+
path?: never;
|
|
120
|
+
cookie?: never;
|
|
121
|
+
};
|
|
122
|
+
requestBody?: never;
|
|
123
|
+
responses: {
|
|
124
|
+
/** @description Hackathon list */
|
|
125
|
+
200: {
|
|
126
|
+
headers: {
|
|
127
|
+
[name: string]: unknown;
|
|
128
|
+
};
|
|
129
|
+
content: {
|
|
130
|
+
"application/json": components["schemas"]["HackathonsResponse"];
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
put?: never;
|
|
136
|
+
post?: never;
|
|
137
|
+
delete?: never;
|
|
138
|
+
options?: never;
|
|
139
|
+
head?: never;
|
|
140
|
+
patch?: never;
|
|
141
|
+
trace?: never;
|
|
142
|
+
};
|
|
143
|
+
"/api/hackathons/{slug}": {
|
|
144
|
+
parameters: {
|
|
145
|
+
query?: never;
|
|
146
|
+
header?: never;
|
|
147
|
+
path?: never;
|
|
148
|
+
cookie?: never;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Get one hackathon's full detail
|
|
152
|
+
* @description Returns submissions, placements, prize tracks, post-hack status funnel, and outcome data for one hackathon by slug. Dual-shape response: curated entries return full detail; DoraHacks-only entries return metadata + prize pool + an explicit `.meta.note`.
|
|
153
|
+
*/
|
|
154
|
+
get: {
|
|
155
|
+
parameters: {
|
|
156
|
+
query?: never;
|
|
157
|
+
header?: never;
|
|
158
|
+
path: {
|
|
159
|
+
/** @description Hackathon slug */
|
|
160
|
+
slug: string;
|
|
161
|
+
};
|
|
162
|
+
cookie?: never;
|
|
163
|
+
};
|
|
164
|
+
requestBody?: never;
|
|
165
|
+
responses: {
|
|
166
|
+
/** @description Hackathon detail */
|
|
167
|
+
200: {
|
|
168
|
+
headers: {
|
|
169
|
+
[name: string]: unknown;
|
|
170
|
+
};
|
|
171
|
+
content: {
|
|
172
|
+
"application/json": components["schemas"]["HackathonDetailResponse"];
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
/** @description Hackathon not found */
|
|
176
|
+
404: {
|
|
177
|
+
headers: {
|
|
178
|
+
[name: string]: unknown;
|
|
179
|
+
};
|
|
180
|
+
content: {
|
|
181
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
put?: never;
|
|
187
|
+
post?: never;
|
|
188
|
+
delete?: never;
|
|
189
|
+
options?: never;
|
|
190
|
+
head?: never;
|
|
191
|
+
patch?: never;
|
|
192
|
+
trace?: never;
|
|
193
|
+
};
|
|
194
|
+
"/api/hackathons/compare": {
|
|
195
|
+
parameters: {
|
|
196
|
+
query?: never;
|
|
197
|
+
header?: never;
|
|
198
|
+
path?: never;
|
|
199
|
+
cookie?: never;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Compare 2–5 hackathons side-by-side
|
|
203
|
+
* @description Returns each hackathon's stats + a `.deltas` block highlighting differences agents care about (prize spread, hacker count, prize-per-winner). Useful for *'which Stellar hackathon should I enter?'* type questions.
|
|
204
|
+
*/
|
|
205
|
+
get: {
|
|
206
|
+
parameters: {
|
|
207
|
+
query: {
|
|
208
|
+
/** @description 2–5 hackathon slugs */
|
|
209
|
+
slugs: string[];
|
|
210
|
+
};
|
|
211
|
+
header?: never;
|
|
212
|
+
path?: never;
|
|
213
|
+
cookie?: never;
|
|
214
|
+
};
|
|
215
|
+
requestBody?: never;
|
|
216
|
+
responses: {
|
|
217
|
+
/** @description Comparison rollup */
|
|
218
|
+
200: {
|
|
219
|
+
headers: {
|
|
220
|
+
[name: string]: unknown;
|
|
221
|
+
};
|
|
222
|
+
content: {
|
|
223
|
+
"application/json": Record<string, never>;
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
put?: never;
|
|
229
|
+
post?: never;
|
|
230
|
+
delete?: never;
|
|
231
|
+
options?: never;
|
|
232
|
+
head?: never;
|
|
233
|
+
patch?: never;
|
|
234
|
+
trace?: never;
|
|
235
|
+
};
|
|
236
|
+
"/api/builders": {
|
|
237
|
+
parameters: {
|
|
238
|
+
query?: never;
|
|
239
|
+
header?: never;
|
|
240
|
+
path?: never;
|
|
241
|
+
cookie?: never;
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Search Stellar builders
|
|
245
|
+
* @description Returns Stellar builder profiles (sourced from Stellar Passport). Useful for *'find a teammate / collaborator who has shipped in X'* queries. Small + growing dataset — flag gaps honestly.
|
|
246
|
+
*/
|
|
247
|
+
get: {
|
|
248
|
+
parameters: {
|
|
249
|
+
query?: {
|
|
250
|
+
/** @description Filter by location substring (e.g. 'Lagos', 'Brazil') */
|
|
251
|
+
location?: string;
|
|
252
|
+
/** @description Filter by skill/tech mentioned in bio */
|
|
253
|
+
skill?: string;
|
|
254
|
+
/** @description Filter by SCF tier */
|
|
255
|
+
scfTier?: string;
|
|
256
|
+
/** @description Max results returned */
|
|
257
|
+
limit?: components["parameters"]["limit"];
|
|
258
|
+
};
|
|
259
|
+
header?: never;
|
|
260
|
+
path?: never;
|
|
261
|
+
cookie?: never;
|
|
262
|
+
};
|
|
263
|
+
requestBody?: never;
|
|
264
|
+
responses: {
|
|
265
|
+
/** @description Builder list */
|
|
266
|
+
200: {
|
|
267
|
+
headers: {
|
|
268
|
+
[name: string]: unknown;
|
|
269
|
+
};
|
|
270
|
+
content: {
|
|
271
|
+
"application/json": Record<string, never>;
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
};
|
|
275
|
+
};
|
|
276
|
+
put?: never;
|
|
277
|
+
post?: never;
|
|
278
|
+
delete?: never;
|
|
279
|
+
options?: never;
|
|
280
|
+
head?: never;
|
|
281
|
+
patch?: never;
|
|
282
|
+
trace?: never;
|
|
283
|
+
};
|
|
284
|
+
"/api/rfps": {
|
|
285
|
+
parameters: {
|
|
286
|
+
query?: never;
|
|
287
|
+
header?: never;
|
|
288
|
+
path?: never;
|
|
289
|
+
cookie?: never;
|
|
290
|
+
};
|
|
291
|
+
/**
|
|
292
|
+
* List Stellar RFPs (SCF-funded sponsor briefs)
|
|
293
|
+
* @description Returns open + closed Stellar RFPs (sponsor briefs that get SCF-funded for the winning team). Quarter-aware: response includes `.meta.activeQuarter` so agents know which RFPs are open *now* vs prior rounds.
|
|
294
|
+
*/
|
|
295
|
+
get: {
|
|
296
|
+
parameters: {
|
|
297
|
+
query?: {
|
|
298
|
+
/** @description Open RFPs are fundable for the current SCF quarter; closed are prior rounds */
|
|
299
|
+
status?: "open" | "closed";
|
|
300
|
+
/** @description Filter by quarter slug (e.g. 'q1-2026') */
|
|
301
|
+
quarter?: string;
|
|
302
|
+
/** @description Max results returned */
|
|
303
|
+
limit?: components["parameters"]["limit"];
|
|
304
|
+
};
|
|
305
|
+
header?: never;
|
|
306
|
+
path?: never;
|
|
307
|
+
cookie?: never;
|
|
308
|
+
};
|
|
309
|
+
requestBody?: never;
|
|
310
|
+
responses: {
|
|
311
|
+
/** @description RFP list */
|
|
312
|
+
200: {
|
|
313
|
+
headers: {
|
|
314
|
+
[name: string]: unknown;
|
|
315
|
+
};
|
|
316
|
+
content: {
|
|
317
|
+
"application/json": Record<string, never>;
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
put?: never;
|
|
323
|
+
post?: never;
|
|
324
|
+
delete?: never;
|
|
325
|
+
options?: never;
|
|
326
|
+
head?: never;
|
|
327
|
+
patch?: never;
|
|
328
|
+
trace?: never;
|
|
329
|
+
};
|
|
330
|
+
"/api/research": {
|
|
331
|
+
parameters: {
|
|
332
|
+
query?: never;
|
|
333
|
+
header?: never;
|
|
334
|
+
path?: never;
|
|
335
|
+
cookie?: never;
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* Vector search over the Stellar research corpus
|
|
339
|
+
* @description Vector search over a 4,541-chunk corpus of primary Stellar sources: SEPs, SCF Handbook, dev docs, foundational papers (Mazières SCP), lumenloop community playbooks, Soroban audit reports (Certora, OtterSec, Halborn, OpenZeppelin, Code4rena, etc.), Electric Capital Developer Reports, SDF blog. Returns top-K chunks with severity metadata for audit chunks. Score field is cosine similarity (0–1, higher = more relevant).
|
|
340
|
+
*/
|
|
341
|
+
get: {
|
|
342
|
+
parameters: {
|
|
343
|
+
query: {
|
|
344
|
+
/** @description Natural-language search query */
|
|
345
|
+
q: string;
|
|
346
|
+
/** @description Optional source filter. Use 'audit' for security questions, 'ec-developer-report' for ecosystem stats, 'paper' for foundational protocol questions. */
|
|
347
|
+
source?: "sdf-blog" | "scf-handbook" | "sep" | "dev-docs" | "paper" | "scf-proposal" | "lumenloop" | "lumenloop-research" | "audit" | "ec-developer-report";
|
|
348
|
+
/** @description Max results (default 8, max 25) */
|
|
349
|
+
limit?: number;
|
|
350
|
+
};
|
|
351
|
+
header?: never;
|
|
352
|
+
path?: never;
|
|
353
|
+
cookie?: never;
|
|
354
|
+
};
|
|
355
|
+
requestBody?: never;
|
|
356
|
+
responses: {
|
|
357
|
+
/** @description Research results */
|
|
358
|
+
200: {
|
|
359
|
+
headers: {
|
|
360
|
+
[name: string]: unknown;
|
|
361
|
+
};
|
|
362
|
+
content: {
|
|
363
|
+
"application/json": Record<string, never>;
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
};
|
|
367
|
+
};
|
|
368
|
+
put?: never;
|
|
369
|
+
post?: never;
|
|
370
|
+
delete?: never;
|
|
371
|
+
options?: never;
|
|
372
|
+
head?: never;
|
|
373
|
+
patch?: never;
|
|
374
|
+
trace?: never;
|
|
375
|
+
};
|
|
376
|
+
"/api/skills": {
|
|
377
|
+
parameters: {
|
|
378
|
+
query?: never;
|
|
379
|
+
header?: never;
|
|
380
|
+
path?: never;
|
|
381
|
+
cookie?: never;
|
|
382
|
+
};
|
|
383
|
+
/**
|
|
384
|
+
* List AI skills for Stellar builders
|
|
385
|
+
* @description Merged catalog of SDF skills.stellar.org skills + curated Stellar Light entries + approved community submissions. Editorial source priority: Stellarlight → SDF → external ecosystem → competing aggregators → community. Featured skills sort first.
|
|
386
|
+
*/
|
|
387
|
+
get: {
|
|
388
|
+
parameters: {
|
|
389
|
+
query?: {
|
|
390
|
+
/** @description Filter by source */
|
|
391
|
+
source?: "sdf" | "stellarlight" | "lumenloop" | "external" | "community";
|
|
392
|
+
/** @description Filter by skill kind */
|
|
393
|
+
kind?: "skill-md" | "mcp-server" | "sdk" | "cli" | "agent-kit" | "tool";
|
|
394
|
+
};
|
|
395
|
+
header?: never;
|
|
396
|
+
path?: never;
|
|
397
|
+
cookie?: never;
|
|
398
|
+
};
|
|
399
|
+
requestBody?: never;
|
|
400
|
+
responses: {
|
|
401
|
+
/** @description Skills catalog */
|
|
402
|
+
200: {
|
|
403
|
+
headers: {
|
|
404
|
+
[name: string]: unknown;
|
|
405
|
+
};
|
|
406
|
+
content: {
|
|
407
|
+
"application/json": Record<string, never>;
|
|
408
|
+
};
|
|
409
|
+
};
|
|
410
|
+
};
|
|
411
|
+
};
|
|
412
|
+
put?: never;
|
|
413
|
+
post?: never;
|
|
414
|
+
delete?: never;
|
|
415
|
+
options?: never;
|
|
416
|
+
head?: never;
|
|
417
|
+
patch?: never;
|
|
418
|
+
trace?: never;
|
|
419
|
+
};
|
|
420
|
+
"/api/skills/{name}": {
|
|
421
|
+
parameters: {
|
|
422
|
+
query?: never;
|
|
423
|
+
header?: never;
|
|
424
|
+
path?: never;
|
|
425
|
+
cookie?: never;
|
|
426
|
+
};
|
|
427
|
+
/**
|
|
428
|
+
* Get one skill's full content
|
|
429
|
+
* @description Returns full SKILL.md content for SDF + Stellar Light skills (where applicable) plus metadata for all sources. Use when a user mentions a specific skill by name — cheaper than filtering the full list endpoint.
|
|
430
|
+
*/
|
|
431
|
+
get: {
|
|
432
|
+
parameters: {
|
|
433
|
+
query?: never;
|
|
434
|
+
header?: never;
|
|
435
|
+
path: {
|
|
436
|
+
/** @description Skill slug (e.g. 'soroban', 'stellar-scout', 'rozo-intent-pay') */
|
|
437
|
+
name: string;
|
|
438
|
+
};
|
|
439
|
+
cookie?: never;
|
|
440
|
+
};
|
|
441
|
+
requestBody?: never;
|
|
442
|
+
responses: {
|
|
443
|
+
/** @description Skill detail with content */
|
|
444
|
+
200: {
|
|
445
|
+
headers: {
|
|
446
|
+
[name: string]: unknown;
|
|
447
|
+
};
|
|
448
|
+
content: {
|
|
449
|
+
"application/json": Record<string, never>;
|
|
450
|
+
};
|
|
451
|
+
};
|
|
452
|
+
/** @description Skill not found */
|
|
453
|
+
404: {
|
|
454
|
+
headers: {
|
|
455
|
+
[name: string]: unknown;
|
|
456
|
+
};
|
|
457
|
+
content: {
|
|
458
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
};
|
|
462
|
+
};
|
|
463
|
+
put?: never;
|
|
464
|
+
post?: never;
|
|
465
|
+
delete?: never;
|
|
466
|
+
options?: never;
|
|
467
|
+
head?: never;
|
|
468
|
+
patch?: never;
|
|
469
|
+
trace?: never;
|
|
470
|
+
};
|
|
471
|
+
"/api/clusters": {
|
|
472
|
+
parameters: {
|
|
473
|
+
query?: never;
|
|
474
|
+
header?: never;
|
|
475
|
+
path?: never;
|
|
476
|
+
cookie?: never;
|
|
477
|
+
};
|
|
478
|
+
/**
|
|
479
|
+
* Topic clusters with crowdedness scores
|
|
480
|
+
* @description Returns clusters of projects by category or types, each with a log-scaled crowdedness score (1–10), SCF-funded count, and sample projects. Useful for *'what's most crowded on Stellar?'* / *'show me underbuilt categories'* queries.
|
|
481
|
+
*/
|
|
482
|
+
get: {
|
|
483
|
+
parameters: {
|
|
484
|
+
query?: {
|
|
485
|
+
/** @description Cluster by category (coarse 7-cat) or types (finer) */
|
|
486
|
+
dimension?: "category" | "types";
|
|
487
|
+
/** @description Only include clusters with at least N projects */
|
|
488
|
+
minSize?: number;
|
|
489
|
+
};
|
|
490
|
+
header?: never;
|
|
491
|
+
path?: never;
|
|
492
|
+
cookie?: never;
|
|
493
|
+
};
|
|
494
|
+
requestBody?: never;
|
|
495
|
+
responses: {
|
|
496
|
+
/** @description Cluster list */
|
|
497
|
+
200: {
|
|
498
|
+
headers: {
|
|
499
|
+
[name: string]: unknown;
|
|
500
|
+
};
|
|
501
|
+
content: {
|
|
502
|
+
"application/json": Record<string, never>;
|
|
503
|
+
};
|
|
504
|
+
};
|
|
505
|
+
};
|
|
506
|
+
};
|
|
507
|
+
put?: never;
|
|
508
|
+
post?: never;
|
|
509
|
+
delete?: never;
|
|
510
|
+
options?: never;
|
|
511
|
+
head?: never;
|
|
512
|
+
patch?: never;
|
|
513
|
+
trace?: never;
|
|
514
|
+
};
|
|
515
|
+
"/api/analyze": {
|
|
516
|
+
parameters: {
|
|
517
|
+
query?: never;
|
|
518
|
+
header?: never;
|
|
519
|
+
path?: never;
|
|
520
|
+
cookie?: never;
|
|
521
|
+
};
|
|
522
|
+
/**
|
|
523
|
+
* Cross-event Stellar ecosystem analytics rollup
|
|
524
|
+
* @description Aggregate stats across all hackathons + projects + SCF funding. Returns: total events, prize pool totals, top categories by project count + SCF-funded count, distribution of SCF awards, post-hackathon status funnel (Built / In Progress / Abandoned).
|
|
525
|
+
*/
|
|
526
|
+
get: {
|
|
527
|
+
parameters: {
|
|
528
|
+
query?: {
|
|
529
|
+
/** @description Which slice to return */
|
|
530
|
+
dimension?: "all" | "hackathons" | "categories" | "funding";
|
|
531
|
+
};
|
|
532
|
+
header?: never;
|
|
533
|
+
path?: never;
|
|
534
|
+
cookie?: never;
|
|
535
|
+
};
|
|
536
|
+
requestBody?: never;
|
|
537
|
+
responses: {
|
|
538
|
+
/** @description Analytics rollup */
|
|
539
|
+
200: {
|
|
540
|
+
headers: {
|
|
541
|
+
[name: string]: unknown;
|
|
542
|
+
};
|
|
543
|
+
content: {
|
|
544
|
+
"application/json": Record<string, never>;
|
|
545
|
+
};
|
|
546
|
+
};
|
|
547
|
+
};
|
|
548
|
+
};
|
|
549
|
+
put?: never;
|
|
550
|
+
post?: never;
|
|
551
|
+
delete?: never;
|
|
552
|
+
options?: never;
|
|
553
|
+
head?: never;
|
|
554
|
+
patch?: never;
|
|
555
|
+
trace?: never;
|
|
556
|
+
};
|
|
557
|
+
"/api/leaderboard": {
|
|
558
|
+
parameters: {
|
|
559
|
+
query?: never;
|
|
560
|
+
header?: never;
|
|
561
|
+
path?: never;
|
|
562
|
+
cookie?: never;
|
|
563
|
+
};
|
|
564
|
+
/**
|
|
565
|
+
* Stellar ecosystem developer activity
|
|
566
|
+
* @description Returns 28-day active dev counts, commits, full-time vs part-time vs one-time dev splits, geographic distribution. Sourced from Electric Capital. Useful for *'how does Stellar compare on dev activity?'* macro questions.
|
|
567
|
+
*/
|
|
568
|
+
get: {
|
|
569
|
+
parameters: {
|
|
570
|
+
query?: {
|
|
571
|
+
/** @description Optional comma-separated includes (e.g. 'hackathons' to surface hackathon context) */
|
|
572
|
+
include?: string;
|
|
573
|
+
};
|
|
574
|
+
header?: never;
|
|
575
|
+
path?: never;
|
|
576
|
+
cookie?: never;
|
|
577
|
+
};
|
|
578
|
+
requestBody?: never;
|
|
579
|
+
responses: {
|
|
580
|
+
/** @description Leaderboard + ecosystem stats */
|
|
581
|
+
200: {
|
|
582
|
+
headers: {
|
|
583
|
+
[name: string]: unknown;
|
|
584
|
+
};
|
|
585
|
+
content: {
|
|
586
|
+
"application/json": Record<string, never>;
|
|
587
|
+
};
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
};
|
|
591
|
+
put?: never;
|
|
592
|
+
post?: never;
|
|
593
|
+
delete?: never;
|
|
594
|
+
options?: never;
|
|
595
|
+
head?: never;
|
|
596
|
+
patch?: never;
|
|
597
|
+
trace?: never;
|
|
598
|
+
};
|
|
599
|
+
"/api/feedback": {
|
|
600
|
+
parameters: {
|
|
601
|
+
query?: never;
|
|
602
|
+
header?: never;
|
|
603
|
+
path?: never;
|
|
604
|
+
cookie?: never;
|
|
605
|
+
};
|
|
606
|
+
get?: never;
|
|
607
|
+
put?: never;
|
|
608
|
+
/**
|
|
609
|
+
* Submit feedback on Scout's output
|
|
610
|
+
* @description Send a feedback report when the skill returns wrong / missing / misleading information. Lands in the curator queue. Rate-limited to 6/min/IP (IP hashed with PAYLOAD_SECRET, never stored raw).
|
|
611
|
+
*/
|
|
612
|
+
post: {
|
|
613
|
+
parameters: {
|
|
614
|
+
query?: never;
|
|
615
|
+
header?: never;
|
|
616
|
+
path?: never;
|
|
617
|
+
cookie?: never;
|
|
618
|
+
};
|
|
619
|
+
requestBody: {
|
|
620
|
+
content: {
|
|
621
|
+
"application/json": components["schemas"]["FeedbackRequest"];
|
|
622
|
+
};
|
|
623
|
+
};
|
|
624
|
+
responses: {
|
|
625
|
+
/** @description Feedback received */
|
|
626
|
+
200: {
|
|
627
|
+
headers: {
|
|
628
|
+
[name: string]: unknown;
|
|
629
|
+
};
|
|
630
|
+
content: {
|
|
631
|
+
"application/json": {
|
|
632
|
+
ok: boolean;
|
|
633
|
+
id: string;
|
|
634
|
+
message?: string;
|
|
635
|
+
};
|
|
636
|
+
};
|
|
637
|
+
};
|
|
638
|
+
/** @description Validation error */
|
|
639
|
+
400: {
|
|
640
|
+
headers: {
|
|
641
|
+
[name: string]: unknown;
|
|
642
|
+
};
|
|
643
|
+
content: {
|
|
644
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
645
|
+
};
|
|
646
|
+
};
|
|
647
|
+
/** @description Rate limit exceeded */
|
|
648
|
+
429: {
|
|
649
|
+
headers: {
|
|
650
|
+
[name: string]: unknown;
|
|
651
|
+
};
|
|
652
|
+
content: {
|
|
653
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
654
|
+
};
|
|
655
|
+
};
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
delete?: never;
|
|
659
|
+
options?: never;
|
|
660
|
+
head?: never;
|
|
661
|
+
patch?: never;
|
|
662
|
+
trace?: never;
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
interface components {
|
|
666
|
+
schemas: {
|
|
667
|
+
/** @description Standard meta block included on every list response */
|
|
668
|
+
Meta: {
|
|
669
|
+
/** Format: uri */
|
|
670
|
+
source?: string;
|
|
671
|
+
/** Format: date-time */
|
|
672
|
+
generatedAt?: string;
|
|
673
|
+
filters?: {
|
|
674
|
+
[key: string]: unknown;
|
|
675
|
+
};
|
|
676
|
+
counts?: {
|
|
677
|
+
returned?: number;
|
|
678
|
+
};
|
|
679
|
+
};
|
|
680
|
+
ErrorResponse: {
|
|
681
|
+
error: string;
|
|
682
|
+
details?: {
|
|
683
|
+
[key: string]: unknown;
|
|
684
|
+
};
|
|
685
|
+
};
|
|
686
|
+
StatusResponse: {
|
|
687
|
+
ok: boolean;
|
|
688
|
+
/** @constant */
|
|
689
|
+
service: "Stellar Scout";
|
|
690
|
+
version: string;
|
|
691
|
+
/** Format: date-time */
|
|
692
|
+
generatedAt: string;
|
|
693
|
+
sources?: {
|
|
694
|
+
name?: string;
|
|
695
|
+
count?: number;
|
|
696
|
+
/** Format: date-time */
|
|
697
|
+
lastUpdatedAt?: string | null;
|
|
698
|
+
notes?: string;
|
|
699
|
+
}[];
|
|
700
|
+
usage?: {
|
|
701
|
+
total?: number;
|
|
702
|
+
last24h?: number;
|
|
703
|
+
last7d?: number;
|
|
704
|
+
byEndpoint?: {
|
|
705
|
+
endpoint?: string;
|
|
706
|
+
count?: number;
|
|
707
|
+
}[];
|
|
708
|
+
};
|
|
709
|
+
endpoints: string[];
|
|
710
|
+
/** Format: uri */
|
|
711
|
+
docs?: string;
|
|
712
|
+
/** Format: uri */
|
|
713
|
+
skill?: string;
|
|
714
|
+
};
|
|
715
|
+
Project: {
|
|
716
|
+
id: string;
|
|
717
|
+
name: string;
|
|
718
|
+
slug: string;
|
|
719
|
+
/** @enum {string} */
|
|
720
|
+
category: "Infrastructure" | "Tooling" | "User-Facing App" | "Asset" | "Protocol/Contract" | "Anchor" | "Partner Integration";
|
|
721
|
+
shortDescription?: string;
|
|
722
|
+
/** @enum {string} */
|
|
723
|
+
status: "Live" | "Development" | "Abandoned";
|
|
724
|
+
logoUrl?: string | null;
|
|
725
|
+
scfAwarded?: boolean;
|
|
726
|
+
scfTotalAwardedUSD?: number | null;
|
|
727
|
+
hackathon?: string | null;
|
|
728
|
+
hackathonPlacement?: string | null;
|
|
729
|
+
hackathonPrize?: number | null;
|
|
730
|
+
hackathonPrizeTrack?: string | null;
|
|
731
|
+
/** @description Relevance score for the current query (higher = better match) */
|
|
732
|
+
score?: number;
|
|
733
|
+
/** Format: uri */
|
|
734
|
+
url?: string;
|
|
735
|
+
};
|
|
736
|
+
ProjectSearchResponse: {
|
|
737
|
+
meta: components["schemas"]["Meta"] & {
|
|
738
|
+
/**
|
|
739
|
+
* @description Tier of match relaxation that produced these results
|
|
740
|
+
* @enum {string}
|
|
741
|
+
*/
|
|
742
|
+
matchMode?: "strict" | "loose" | "majority";
|
|
743
|
+
matchModeLabel?: string;
|
|
744
|
+
};
|
|
745
|
+
projects: components["schemas"]["Project"][];
|
|
746
|
+
};
|
|
747
|
+
HackathonsResponse: {
|
|
748
|
+
meta?: components["schemas"]["Meta"] & {
|
|
749
|
+
/** @description Live announcement channels when query returns 0 events */
|
|
750
|
+
fallbackChannels?: {
|
|
751
|
+
name?: string;
|
|
752
|
+
/** Format: uri */
|
|
753
|
+
url?: string;
|
|
754
|
+
}[];
|
|
755
|
+
};
|
|
756
|
+
hackathons?: Record<string, never>[];
|
|
757
|
+
};
|
|
758
|
+
HackathonDetailResponse: {
|
|
759
|
+
meta?: components["schemas"]["Meta"];
|
|
760
|
+
hackathon?: Record<string, never>;
|
|
761
|
+
};
|
|
762
|
+
FeedbackRequest: {
|
|
763
|
+
/** @enum {string} */
|
|
764
|
+
kind: "bug" | "missing-data" | "wrong-answer" | "suggestion" | "other";
|
|
765
|
+
message: string;
|
|
766
|
+
query?: string;
|
|
767
|
+
endpoint?: string;
|
|
768
|
+
agentName?: string;
|
|
769
|
+
};
|
|
770
|
+
};
|
|
771
|
+
responses: never;
|
|
772
|
+
parameters: {
|
|
773
|
+
/** @description Keyword query (free text) */
|
|
774
|
+
q: string;
|
|
775
|
+
/** @description Max results returned */
|
|
776
|
+
limit: number;
|
|
777
|
+
};
|
|
778
|
+
requestBodies: never;
|
|
779
|
+
headers: never;
|
|
780
|
+
pathItems: never;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* @stellar-light/api-client — typed TypeScript client for the Stellar
|
|
785
|
+
* Scout API (https://stellarlight.xyz/api/openapi.json).
|
|
786
|
+
*
|
|
787
|
+
* Zero runtime dependencies — native fetch, works in Node 20+, browsers,
|
|
788
|
+
* and edge runtimes. For autonomous agents and aggregators that consume
|
|
789
|
+
* the API directly; human-driven MCP clients (Claude Desktop, Cursor)
|
|
790
|
+
* should use @stellar-light/scout-mcp instead.
|
|
791
|
+
*
|
|
792
|
+
* import { ScoutClient } from "@stellar-light/api-client";
|
|
793
|
+
*
|
|
794
|
+
* const scout = new ScoutClient();
|
|
795
|
+
* const { projects } = await scout.searchProjects({ q: "stablecoin", scfAwarded: true });
|
|
796
|
+
*
|
|
797
|
+
* Types are generated from the live OpenAPI spec (src/schema.ts via
|
|
798
|
+
* openapi-typescript). Regenerate with `pnpm generate` when the spec
|
|
799
|
+
* changes.
|
|
800
|
+
*/
|
|
801
|
+
|
|
802
|
+
/** Re-exported component schemas for consumer convenience. */
|
|
803
|
+
type Project = components["schemas"]["Project"];
|
|
804
|
+
type ProjectSearchResponse = components["schemas"]["ProjectSearchResponse"];
|
|
805
|
+
type StatusResponse = components["schemas"]["StatusResponse"];
|
|
806
|
+
type HackathonsResponse = components["schemas"]["HackathonsResponse"];
|
|
807
|
+
type HackathonDetailResponse = components["schemas"]["HackathonDetailResponse"];
|
|
808
|
+
type FeedbackRequest = components["schemas"]["FeedbackRequest"];
|
|
809
|
+
/** Query params, lifted from the generated paths for ergonomic call sites. */
|
|
810
|
+
type SearchProjectsParams = NonNullable<paths["/api/projects/search"]["get"]["parameters"]["query"]>;
|
|
811
|
+
type GetHackathonsParams = NonNullable<paths["/api/hackathons"]["get"]["parameters"]["query"]>;
|
|
812
|
+
type GetBuildersParams = NonNullable<paths["/api/builders"]["get"]["parameters"]["query"]>;
|
|
813
|
+
type GetRfpsParams = NonNullable<paths["/api/rfps"]["get"]["parameters"]["query"]>;
|
|
814
|
+
type SearchResearchParams = NonNullable<paths["/api/research"]["get"]["parameters"]["query"]>;
|
|
815
|
+
type ListSkillsParams = NonNullable<paths["/api/skills"]["get"]["parameters"]["query"]>;
|
|
816
|
+
type GetClustersParams = NonNullable<paths["/api/clusters"]["get"]["parameters"]["query"]>;
|
|
817
|
+
type AnalyzeEcosystemParams = NonNullable<paths["/api/analyze"]["get"]["parameters"]["query"]>;
|
|
818
|
+
type GetLeaderboardParams = NonNullable<paths["/api/leaderboard"]["get"]["parameters"]["query"]>;
|
|
819
|
+
interface ScoutClientOptions {
|
|
820
|
+
/** API origin. Defaults to https://stellarlight.xyz */
|
|
821
|
+
baseUrl?: string;
|
|
822
|
+
/** Request timeout in ms. Defaults to 30_000. */
|
|
823
|
+
timeoutMs?: number;
|
|
824
|
+
/** Extra headers sent with every request (e.g. identify your agent). */
|
|
825
|
+
headers?: Record<string, string>;
|
|
826
|
+
/** Custom fetch implementation (testing / instrumented runtimes). */
|
|
827
|
+
fetch?: typeof globalThis.fetch;
|
|
828
|
+
}
|
|
829
|
+
/** Thrown on any non-2xx response. Carries status + parsed error body. */
|
|
830
|
+
declare class ScoutApiError extends Error {
|
|
831
|
+
readonly status: number;
|
|
832
|
+
readonly url: string;
|
|
833
|
+
readonly body: unknown;
|
|
834
|
+
constructor(status: number, url: string, body: unknown);
|
|
835
|
+
}
|
|
836
|
+
declare class ScoutClient {
|
|
837
|
+
private readonly baseUrl;
|
|
838
|
+
private readonly timeoutMs;
|
|
839
|
+
private readonly headers;
|
|
840
|
+
private readonly fetchImpl;
|
|
841
|
+
constructor(options?: ScoutClientOptions);
|
|
842
|
+
/** Service health, data-source freshness, endpoint enumeration. */
|
|
843
|
+
getStatus(): Promise<StatusResponse>;
|
|
844
|
+
/** Search 741+ curated Stellar projects (prior art / competitor lookup). */
|
|
845
|
+
searchProjects(params?: SearchProjectsParams): Promise<ProjectSearchResponse>;
|
|
846
|
+
/** List Stellar hackathons (curated + DoraHacks merged feed). */
|
|
847
|
+
getHackathons(params?: GetHackathonsParams): Promise<HackathonsResponse>;
|
|
848
|
+
/** Full detail for one hackathon by slug. */
|
|
849
|
+
getHackathon(slug: string): Promise<HackathonDetailResponse>;
|
|
850
|
+
/** Side-by-side comparison of 2–5 hackathons with a deltas block. */
|
|
851
|
+
compareHackathons(slugs: string[]): Promise<Record<string, unknown>>;
|
|
852
|
+
/** Search Stellar builder profiles (Stellar Passport directory). */
|
|
853
|
+
getBuilders(params?: GetBuildersParams): Promise<Record<string, unknown>>;
|
|
854
|
+
/** Open + closed SCF-funded sponsor briefs. */
|
|
855
|
+
getRfps(params?: GetRfpsParams): Promise<Record<string, unknown>>;
|
|
856
|
+
/** Vector search over the 4,541-chunk Stellar research corpus. */
|
|
857
|
+
searchResearch(params: SearchResearchParams): Promise<Record<string, unknown>>;
|
|
858
|
+
/** Merged AI-skill catalog (SDF + curated + community). */
|
|
859
|
+
listSkills(params?: ListSkillsParams): Promise<Record<string, unknown>>;
|
|
860
|
+
/** One skill's full content + metadata by slug. */
|
|
861
|
+
getSkill(name: string): Promise<Record<string, unknown>>;
|
|
862
|
+
/** Topic clusters with log-scaled crowdedness scores. */
|
|
863
|
+
getClusters(params?: GetClustersParams): Promise<Record<string, unknown>>;
|
|
864
|
+
/** Cross-event analytics rollup (hackathons + categories + funding). */
|
|
865
|
+
analyzeEcosystem(params?: AnalyzeEcosystemParams): Promise<Record<string, unknown>>;
|
|
866
|
+
/** Electric Capital developer-activity stats + project leaderboard. */
|
|
867
|
+
getLeaderboard(params?: GetLeaderboardParams): Promise<Record<string, unknown>>;
|
|
868
|
+
/** Report wrong / missing / misleading data to the curator queue. */
|
|
869
|
+
submitFeedback(body: FeedbackRequest): Promise<{
|
|
870
|
+
ok: boolean;
|
|
871
|
+
id: string;
|
|
872
|
+
message?: string;
|
|
873
|
+
}>;
|
|
874
|
+
private get;
|
|
875
|
+
private request;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
export { type AnalyzeEcosystemParams, type FeedbackRequest, type GetBuildersParams, type GetClustersParams, type GetHackathonsParams, type GetLeaderboardParams, type GetRfpsParams, type HackathonDetailResponse, type HackathonsResponse, type ListSkillsParams, type Project, type ProjectSearchResponse, ScoutApiError, ScoutClient, type ScoutClientOptions, type SearchProjectsParams, type SearchResearchParams, type StatusResponse, type components, type paths };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var ScoutApiError = class extends Error {
|
|
3
|
+
status;
|
|
4
|
+
url;
|
|
5
|
+
body;
|
|
6
|
+
constructor(status, url, body) {
|
|
7
|
+
const detail = body && typeof body === "object" && "error" in body ? ` \u2014 ${body.error}` : "";
|
|
8
|
+
super(`Scout API ${status} on ${url}${detail}`);
|
|
9
|
+
this.name = "ScoutApiError";
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.url = url;
|
|
12
|
+
this.body = body;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var DEFAULT_BASE_URL = "https://stellarlight.xyz";
|
|
16
|
+
var CLIENT_VERSION = "1.0.0";
|
|
17
|
+
var ScoutClient = class {
|
|
18
|
+
baseUrl;
|
|
19
|
+
timeoutMs;
|
|
20
|
+
headers;
|
|
21
|
+
fetchImpl;
|
|
22
|
+
constructor(options = {}) {
|
|
23
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
24
|
+
this.timeoutMs = options.timeoutMs ?? 3e4;
|
|
25
|
+
this.headers = {
|
|
26
|
+
"user-agent": `stellar-light-api-client/${CLIENT_VERSION}`,
|
|
27
|
+
...options.headers
|
|
28
|
+
};
|
|
29
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
30
|
+
}
|
|
31
|
+
/** Service health, data-source freshness, endpoint enumeration. */
|
|
32
|
+
getStatus() {
|
|
33
|
+
return this.get("/api/status");
|
|
34
|
+
}
|
|
35
|
+
/** Search 741+ curated Stellar projects (prior art / competitor lookup). */
|
|
36
|
+
searchProjects(params = {}) {
|
|
37
|
+
return this.get("/api/projects/search", params);
|
|
38
|
+
}
|
|
39
|
+
/** List Stellar hackathons (curated + DoraHacks merged feed). */
|
|
40
|
+
getHackathons(params = {}) {
|
|
41
|
+
return this.get("/api/hackathons", params);
|
|
42
|
+
}
|
|
43
|
+
/** Full detail for one hackathon by slug. */
|
|
44
|
+
getHackathon(slug) {
|
|
45
|
+
return this.get(`/api/hackathons/${encodeURIComponent(slug)}`);
|
|
46
|
+
}
|
|
47
|
+
/** Side-by-side comparison of 2–5 hackathons with a deltas block. */
|
|
48
|
+
compareHackathons(slugs) {
|
|
49
|
+
return this.get("/api/hackathons/compare", { slugs: slugs.join(",") });
|
|
50
|
+
}
|
|
51
|
+
/** Search Stellar builder profiles (Stellar Passport directory). */
|
|
52
|
+
getBuilders(params = {}) {
|
|
53
|
+
return this.get("/api/builders", params);
|
|
54
|
+
}
|
|
55
|
+
/** Open + closed SCF-funded sponsor briefs. */
|
|
56
|
+
getRfps(params = {}) {
|
|
57
|
+
return this.get("/api/rfps", params);
|
|
58
|
+
}
|
|
59
|
+
/** Vector search over the 4,541-chunk Stellar research corpus. */
|
|
60
|
+
searchResearch(params) {
|
|
61
|
+
return this.get("/api/research", params);
|
|
62
|
+
}
|
|
63
|
+
/** Merged AI-skill catalog (SDF + curated + community). */
|
|
64
|
+
listSkills(params = {}) {
|
|
65
|
+
return this.get("/api/skills", params);
|
|
66
|
+
}
|
|
67
|
+
/** One skill's full content + metadata by slug. */
|
|
68
|
+
getSkill(name) {
|
|
69
|
+
return this.get(`/api/skills/${encodeURIComponent(name)}`);
|
|
70
|
+
}
|
|
71
|
+
/** Topic clusters with log-scaled crowdedness scores. */
|
|
72
|
+
getClusters(params = {}) {
|
|
73
|
+
return this.get("/api/clusters", params);
|
|
74
|
+
}
|
|
75
|
+
/** Cross-event analytics rollup (hackathons + categories + funding). */
|
|
76
|
+
analyzeEcosystem(params = {}) {
|
|
77
|
+
return this.get("/api/analyze", params);
|
|
78
|
+
}
|
|
79
|
+
/** Electric Capital developer-activity stats + project leaderboard. */
|
|
80
|
+
getLeaderboard(params = {}) {
|
|
81
|
+
return this.get("/api/leaderboard", params);
|
|
82
|
+
}
|
|
83
|
+
/** Report wrong / missing / misleading data to the curator queue. */
|
|
84
|
+
submitFeedback(body) {
|
|
85
|
+
return this.request("/api/feedback", { method: "POST", body });
|
|
86
|
+
}
|
|
87
|
+
/* ── transport ──────────────────────────────────────────────────── */
|
|
88
|
+
get(path, params) {
|
|
89
|
+
return this.request(path, { method: "GET", params });
|
|
90
|
+
}
|
|
91
|
+
async request(path, init) {
|
|
92
|
+
const url = new URL(this.baseUrl + path);
|
|
93
|
+
for (const [key, value] of Object.entries(init.params ?? {})) {
|
|
94
|
+
if (value === void 0 || value === null) continue;
|
|
95
|
+
if (Array.isArray(value)) {
|
|
96
|
+
for (const v of value) url.searchParams.append(key, String(v));
|
|
97
|
+
} else {
|
|
98
|
+
url.searchParams.set(key, String(value));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const controller = new AbortController();
|
|
102
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
103
|
+
try {
|
|
104
|
+
const res = await this.fetchImpl(url.toString(), {
|
|
105
|
+
method: init.method,
|
|
106
|
+
headers: {
|
|
107
|
+
accept: "application/json",
|
|
108
|
+
...init.body !== void 0 && {
|
|
109
|
+
"content-type": "application/json"
|
|
110
|
+
},
|
|
111
|
+
...this.headers
|
|
112
|
+
},
|
|
113
|
+
...init.body !== void 0 && { body: JSON.stringify(init.body) },
|
|
114
|
+
signal: controller.signal
|
|
115
|
+
});
|
|
116
|
+
const body = await res.json().catch(() => null);
|
|
117
|
+
if (!res.ok) {
|
|
118
|
+
throw new ScoutApiError(res.status, url.toString(), body);
|
|
119
|
+
}
|
|
120
|
+
return body;
|
|
121
|
+
} finally {
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
export {
|
|
127
|
+
ScoutApiError,
|
|
128
|
+
ScoutClient
|
|
129
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stellar-light/api-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Typed TypeScript client for the Stellar Scout API — projects, builders, hackathons, SCF, audits, research. Zero dependencies, for autonomous agents and aggregators.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"stellar",
|
|
7
|
+
"soroban",
|
|
8
|
+
"api-client",
|
|
9
|
+
"sdk",
|
|
10
|
+
"typescript",
|
|
11
|
+
"agent",
|
|
12
|
+
"ai",
|
|
13
|
+
"ecosystem",
|
|
14
|
+
"scf",
|
|
15
|
+
"openapi"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://stellarlight.xyz/scout",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/alexanderkoh/stellarlight/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/alexanderkoh/stellarlight.git",
|
|
24
|
+
"directory": "api-client"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"author": "stellarlight.xyz",
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup src/index.ts --format esm --dts --target node20 --clean",
|
|
43
|
+
"generate": "openapi-typescript https://stellarlight.xyz/api/openapi.json -o src/schema.ts",
|
|
44
|
+
"typecheck": "tsc --noEmit",
|
|
45
|
+
"test": "pnpm build && node test/smoke.mjs",
|
|
46
|
+
"prepublishOnly": "pnpm build"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=20.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^22.10.5",
|
|
53
|
+
"openapi-typescript": "^7.13.0",
|
|
54
|
+
"tsup": "^8.3.5",
|
|
55
|
+
"typescript": "^5.7.2"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
}
|
|
60
|
+
}
|