@obolos_tech/mcp-server 0.1.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 +111 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +301 -0
- package/dist/index.js.map +1 -0
- package/dist/marketplace.d.ts +49 -0
- package/dist/marketplace.js +138 -0
- package/dist/marketplace.js.map +1 -0
- package/dist/payment.d.ts +26 -0
- package/dist/payment.js +137 -0
- package/dist/payment.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Obolos MCP Server
|
|
2
|
+
|
|
3
|
+
**Let AI agents discover and pay for APIs on the Obolos x402 marketplace.**
|
|
4
|
+
|
|
5
|
+
Every API on the Obolos marketplace becomes a tool your AI agent can call — with automatic USDC micropayments on Base.
|
|
6
|
+
|
|
7
|
+
## Quick Setup
|
|
8
|
+
|
|
9
|
+
### Claude Code
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
claude mcp add obolos -- node /path/to/mcp-server/dist/index.js
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or with a payment wallet:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
claude mcp add obolos -e OBOLOS_PRIVATE_KEY=0xyour_private_key -- node /path/to/mcp-server/dist/index.js
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Claude Desktop
|
|
22
|
+
|
|
23
|
+
Add to `~/.claude/claude_desktop_config.json`:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"obolos": {
|
|
29
|
+
"command": "node",
|
|
30
|
+
"args": ["/path/to/mcp-server/dist/index.js"],
|
|
31
|
+
"env": {
|
|
32
|
+
"OBOLOS_PRIVATE_KEY": "0xyour_private_key"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Cursor / Windsurf / Other MCP Clients
|
|
40
|
+
|
|
41
|
+
Add to your MCP config:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"obolos": {
|
|
46
|
+
"command": "node",
|
|
47
|
+
"args": ["/path/to/mcp-server/dist/index.js"],
|
|
48
|
+
"env": {
|
|
49
|
+
"OBOLOS_PRIVATE_KEY": "0xyour_private_key"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Tools
|
|
56
|
+
|
|
57
|
+
| Tool | Description |
|
|
58
|
+
|------|-------------|
|
|
59
|
+
| `search_apis` | Search the marketplace by query, category, or sort order |
|
|
60
|
+
| `list_categories` | Browse available API categories |
|
|
61
|
+
| `get_api_details` | Get full details, input fields, and pricing for an API |
|
|
62
|
+
| `call_api` | Execute an API with automatic x402 USDC payment |
|
|
63
|
+
| `get_balance` | Check your wallet's USDC balance on Base |
|
|
64
|
+
|
|
65
|
+
## Environment Variables
|
|
66
|
+
|
|
67
|
+
| Variable | Required | Description |
|
|
68
|
+
|----------|----------|-------------|
|
|
69
|
+
| `OBOLOS_PRIVATE_KEY` | For payments | Private key of a Base wallet with USDC |
|
|
70
|
+
| `OBOLOS_API_URL` | No | Marketplace URL (default: `https://obolos.tech`) |
|
|
71
|
+
|
|
72
|
+
## Example Usage
|
|
73
|
+
|
|
74
|
+
Once configured, your AI agent can:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
"Search for token price APIs on Obolos"
|
|
78
|
+
→ search_apis(query: "token price")
|
|
79
|
+
|
|
80
|
+
"How much does the DeFi portfolio API cost?"
|
|
81
|
+
→ get_api_details(api_id: "ext-abc123")
|
|
82
|
+
|
|
83
|
+
"Get the current ETH price using Obolos"
|
|
84
|
+
→ call_api(api_id: "ext-abc123", method: "GET", query_params: {"symbol": "ETH"})
|
|
85
|
+
|
|
86
|
+
"What's my Obolos wallet balance?"
|
|
87
|
+
→ get_balance()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## How Payments Work
|
|
91
|
+
|
|
92
|
+
1. Agent calls `call_api` with an API id and parameters
|
|
93
|
+
2. MCP server sends request to Obolos proxy
|
|
94
|
+
3. Proxy returns HTTP 402 with payment requirements
|
|
95
|
+
4. Server signs an EIP-712 payment with your private key
|
|
96
|
+
5. Retries request with payment header
|
|
97
|
+
6. API response is returned to the agent
|
|
98
|
+
|
|
99
|
+
Payments are USDC micropayments on Base ($0.001–$0.10 per call). Only 1% platform fee — 99% goes directly to the API creator.
|
|
100
|
+
|
|
101
|
+
## Build from Source
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd mcp-server
|
|
105
|
+
npm install
|
|
106
|
+
npm run build
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Obolos MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes the Obolos x402 API marketplace as MCP tools.
|
|
6
|
+
* Any AI agent (Claude Code, Cursor, Windsurf, etc.) can discover,
|
|
7
|
+
* browse, and pay for APIs through this server.
|
|
8
|
+
*
|
|
9
|
+
* Configuration (env vars):
|
|
10
|
+
* OBOLOS_API_URL — Marketplace URL (default: https://obolos.tech)
|
|
11
|
+
* OBOLOS_PRIVATE_KEY — Wallet private key for x402 payments (optional)
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Obolos MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes the Obolos x402 API marketplace as MCP tools.
|
|
6
|
+
* Any AI agent (Claude Code, Cursor, Windsurf, etc.) can discover,
|
|
7
|
+
* browse, and pay for APIs through this server.
|
|
8
|
+
*
|
|
9
|
+
* Configuration (env vars):
|
|
10
|
+
* OBOLOS_API_URL — Marketplace URL (default: https://obolos.tech)
|
|
11
|
+
* OBOLOS_PRIVATE_KEY — Wallet private key for x402 payments (optional)
|
|
12
|
+
*/
|
|
13
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
14
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import { MarketplaceClient } from './marketplace.js';
|
|
17
|
+
import { PaymentSigner } from './payment.js';
|
|
18
|
+
const OBOLOS_API_URL = process.env.OBOLOS_API_URL || 'https://obolos.tech';
|
|
19
|
+
const OBOLOS_PRIVATE_KEY = process.env.OBOLOS_PRIVATE_KEY || '';
|
|
20
|
+
const marketplace = new MarketplaceClient(OBOLOS_API_URL);
|
|
21
|
+
const signer = OBOLOS_PRIVATE_KEY ? new PaymentSigner(OBOLOS_PRIVATE_KEY) : null;
|
|
22
|
+
const server = new McpServer({
|
|
23
|
+
name: 'obolos',
|
|
24
|
+
version: '0.1.0',
|
|
25
|
+
});
|
|
26
|
+
// ─── Tool: search_apis ──────────────────────────────────────────────────────
|
|
27
|
+
server.tool('search_apis', 'Search the Obolos x402 marketplace for pay-per-call APIs. ' +
|
|
28
|
+
'Returns APIs that AI agents can call with automatic USDC micropayments. ' +
|
|
29
|
+
'Use this to find data services, AI endpoints, blockchain tools, and more.', {
|
|
30
|
+
query: z.string().optional().describe('Search query (e.g. "weather", "token price", "web scraping")'),
|
|
31
|
+
category: z.string().optional().describe('Filter by category'),
|
|
32
|
+
sort: z.enum(['popular', 'newest', 'price_asc', 'price_desc']).optional()
|
|
33
|
+
.describe('Sort order. Default: popular'),
|
|
34
|
+
limit: z.number().min(1).max(50).optional().describe('Max results (default 20)'),
|
|
35
|
+
}, async ({ query, category, sort, limit }) => {
|
|
36
|
+
try {
|
|
37
|
+
const result = await marketplace.searchApis({
|
|
38
|
+
query,
|
|
39
|
+
category,
|
|
40
|
+
sort,
|
|
41
|
+
limit: limit || 20,
|
|
42
|
+
});
|
|
43
|
+
const summary = result.apis.map((api) => ({
|
|
44
|
+
id: api.id,
|
|
45
|
+
name: api.name,
|
|
46
|
+
description: api.description?.slice(0, 200),
|
|
47
|
+
category: api.category,
|
|
48
|
+
price: `$${api.price_per_call.toFixed(4)} USDC`,
|
|
49
|
+
method: api.http_method,
|
|
50
|
+
type: api.api_type,
|
|
51
|
+
rating: api.average_rating ? `${api.average_rating.toFixed(1)}/5` : 'unrated',
|
|
52
|
+
calls: api.total_calls,
|
|
53
|
+
}));
|
|
54
|
+
return {
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: JSON.stringify({
|
|
59
|
+
total: result.pagination.total,
|
|
60
|
+
showing: summary.length,
|
|
61
|
+
apis: summary,
|
|
62
|
+
tip: 'Use get_api_details with an API id to see full details including input fields. Use call_api to execute.',
|
|
63
|
+
}, null, 2),
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
return {
|
|
70
|
+
content: [{ type: 'text', text: `Error searching APIs: ${err.message}` }],
|
|
71
|
+
isError: true,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
// ─── Tool: list_categories ──────────────────────────────────────────────────
|
|
76
|
+
server.tool('list_categories', 'List all API categories available on the Obolos marketplace. ' +
|
|
77
|
+
'Useful for browsing what types of APIs are available.', {}, async () => {
|
|
78
|
+
try {
|
|
79
|
+
const result = await marketplace.getCategories();
|
|
80
|
+
return {
|
|
81
|
+
content: [
|
|
82
|
+
{
|
|
83
|
+
type: 'text',
|
|
84
|
+
text: JSON.stringify({
|
|
85
|
+
categories: result.categories,
|
|
86
|
+
total_native_apis: result.nativeCount,
|
|
87
|
+
total_external_apis: result.externalCount,
|
|
88
|
+
}, null, 2),
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
content: [{ type: 'text', text: `Error: ${err.message}` }],
|
|
96
|
+
isError: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// ─── Tool: get_api_details ──────────────────────────────────────────────────
|
|
101
|
+
server.tool('get_api_details', 'Get full details for a specific API including input fields, pricing, ' +
|
|
102
|
+
'example request/response, and how to call it. Use an API id from search_apis.', {
|
|
103
|
+
api_id: z.string().describe('The API id (e.g. "ext-a1b2c3d4" for external, or a UUID for native)'),
|
|
104
|
+
}, async ({ api_id }) => {
|
|
105
|
+
try {
|
|
106
|
+
const api = await marketplace.getApiDetails(api_id);
|
|
107
|
+
const details = {
|
|
108
|
+
id: api.id,
|
|
109
|
+
name: api.name,
|
|
110
|
+
description: api.description,
|
|
111
|
+
category: api.category,
|
|
112
|
+
price: `$${api.price_per_call.toFixed(4)} USDC per call`,
|
|
113
|
+
method: api.http_method,
|
|
114
|
+
type: api.api_type,
|
|
115
|
+
rating: api.average_rating ? `${api.average_rating.toFixed(1)}/5 (${api.review_count} reviews)` : 'unrated',
|
|
116
|
+
total_calls: api.total_calls,
|
|
117
|
+
seller: api.seller_name,
|
|
118
|
+
};
|
|
119
|
+
if (api.input_schema) {
|
|
120
|
+
details.input_fields = api.input_schema;
|
|
121
|
+
}
|
|
122
|
+
if (api.example_request) {
|
|
123
|
+
try {
|
|
124
|
+
details.example_request = JSON.parse(api.example_request);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
details.example_request = api.example_request;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (api.example_response) {
|
|
131
|
+
try {
|
|
132
|
+
details.example_response = JSON.parse(api.example_response);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
details.example_response = api.example_response;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
details.how_to_call = {
|
|
139
|
+
tool: 'call_api',
|
|
140
|
+
params: {
|
|
141
|
+
api_id: api.id,
|
|
142
|
+
method: api.http_method,
|
|
143
|
+
body: api.input_schema?.fields
|
|
144
|
+
? Object.fromEntries(Object.entries(api.input_schema.fields).map(([k, v]) => [
|
|
145
|
+
k,
|
|
146
|
+
v.example ?? `<${v.type}>`,
|
|
147
|
+
]))
|
|
148
|
+
: undefined,
|
|
149
|
+
},
|
|
150
|
+
note: signer
|
|
151
|
+
? `Payment will be signed automatically with wallet ${signer.address}`
|
|
152
|
+
: 'Set OBOLOS_PRIVATE_KEY env var to enable automatic payments',
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
content: [{ type: 'text', text: JSON.stringify(details, null, 2) }],
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
return {
|
|
160
|
+
content: [{ type: 'text', text: `Error: ${err.message}` }],
|
|
161
|
+
isError: true,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// ─── Tool: call_api ─────────────────────────────────────────────────────────
|
|
166
|
+
server.tool('call_api', 'Execute an API call on the Obolos marketplace with automatic x402 USDC payment. ' +
|
|
167
|
+
'Requires OBOLOS_PRIVATE_KEY env var to be set. ' +
|
|
168
|
+
'The payment is a micropayment (typically $0.001–$0.01 USDC per call).', {
|
|
169
|
+
api_id: z.string().describe('The API id to call'),
|
|
170
|
+
method: z.enum(['GET', 'POST', 'PUT', 'PATCH']).optional().describe('HTTP method (default: GET)'),
|
|
171
|
+
body: z.record(z.unknown()).optional().describe('Request body (for POST/PUT/PATCH)'),
|
|
172
|
+
query_params: z.record(z.string()).optional().describe('Query parameters (for GET)'),
|
|
173
|
+
}, async ({ api_id, method, body, query_params }) => {
|
|
174
|
+
if (!signer) {
|
|
175
|
+
return {
|
|
176
|
+
content: [
|
|
177
|
+
{
|
|
178
|
+
type: 'text',
|
|
179
|
+
text: 'Payment not configured. Set the OBOLOS_PRIVATE_KEY environment variable ' +
|
|
180
|
+
'with a Base wallet private key that has USDC balance.\n\n' +
|
|
181
|
+
'Example: OBOLOS_PRIVATE_KEY=0xabc123... in your MCP server config.',
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
isError: true,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
const result = await marketplace.callApi(api_id, {
|
|
189
|
+
method,
|
|
190
|
+
body,
|
|
191
|
+
queryParams: query_params,
|
|
192
|
+
signPayment: async (paymentRequired) => {
|
|
193
|
+
return signer.signPayment(paymentRequired);
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
if (result.status >= 400) {
|
|
197
|
+
return {
|
|
198
|
+
content: [
|
|
199
|
+
{
|
|
200
|
+
type: 'text',
|
|
201
|
+
text: JSON.stringify({
|
|
202
|
+
error: true,
|
|
203
|
+
status: result.status,
|
|
204
|
+
body: result.body,
|
|
205
|
+
}, null, 2),
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
isError: true,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
content: [
|
|
213
|
+
{
|
|
214
|
+
type: 'text',
|
|
215
|
+
text: JSON.stringify({
|
|
216
|
+
status: result.status,
|
|
217
|
+
data: result.body,
|
|
218
|
+
}, null, 2),
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
return {
|
|
225
|
+
content: [{ type: 'text', text: `API call failed: ${err.message}` }],
|
|
226
|
+
isError: true,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
// ─── Tool: get_balance ──────────────────────────────────────────────────────
|
|
231
|
+
server.tool('get_balance', 'Check the USDC balance of the configured payment wallet on Base.', {}, async () => {
|
|
232
|
+
if (!signer) {
|
|
233
|
+
return {
|
|
234
|
+
content: [
|
|
235
|
+
{
|
|
236
|
+
type: 'text',
|
|
237
|
+
text: 'No wallet configured. Set OBOLOS_PRIVATE_KEY env var.',
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
isError: true,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const balance = await signer.getUsdcBalance();
|
|
245
|
+
return {
|
|
246
|
+
content: [
|
|
247
|
+
{
|
|
248
|
+
type: 'text',
|
|
249
|
+
text: JSON.stringify({
|
|
250
|
+
address: signer.address,
|
|
251
|
+
usdc_balance: `${balance.formatted} USDC`,
|
|
252
|
+
network: 'Base (Chain ID: 8453)',
|
|
253
|
+
}, null, 2),
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
return {
|
|
260
|
+
content: [{ type: 'text', text: `Balance check failed: ${err.message}` }],
|
|
261
|
+
isError: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
// ─── Resources ──────────────────────────────────────────────────────────────
|
|
266
|
+
server.resource('marketplace-info', 'obolos://marketplace/info', async () => ({
|
|
267
|
+
contents: [
|
|
268
|
+
{
|
|
269
|
+
uri: 'obolos://marketplace/info',
|
|
270
|
+
mimeType: 'application/json',
|
|
271
|
+
text: JSON.stringify({
|
|
272
|
+
name: 'Obolos x402 Marketplace',
|
|
273
|
+
url: OBOLOS_API_URL,
|
|
274
|
+
description: 'Pay-per-call API marketplace powered by x402 micropayments. ' +
|
|
275
|
+
'Browse and call hundreds of APIs with automatic USDC payments on Base. ' +
|
|
276
|
+
'Only 1% platform fee — 99% goes directly to API creators.',
|
|
277
|
+
wallet: signer
|
|
278
|
+
? { address: signer.address, configured: true }
|
|
279
|
+
: { configured: false, note: 'Set OBOLOS_PRIVATE_KEY to enable payments' },
|
|
280
|
+
documentation: 'https://obolos.tech/app/marketplace',
|
|
281
|
+
}, null, 2),
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
}));
|
|
285
|
+
// ─── Start ──────────────────────────────────────────────────────────────────
|
|
286
|
+
async function main() {
|
|
287
|
+
const transport = new StdioServerTransport();
|
|
288
|
+
await server.connect(transport);
|
|
289
|
+
console.error(`[obolos-mcp] Connected to ${OBOLOS_API_URL}`);
|
|
290
|
+
if (signer) {
|
|
291
|
+
console.error(`[obolos-mcp] Wallet: ${signer.address}`);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
console.error('[obolos-mcp] No wallet configured (set OBOLOS_PRIVATE_KEY for payments)');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
main().catch((err) => {
|
|
298
|
+
console.error('[obolos-mcp] Fatal:', err);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
});
|
|
301
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,qBAAqB,CAAC;AAC3E,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC;AAEhE,MAAM,WAAW,GAAG,IAAI,iBAAiB,CAAC,cAAc,CAAC,CAAC;AAC1D,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAEjF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,+EAA+E;AAE/E,MAAM,CAAC,IAAI,CACT,aAAa,EACb,4DAA4D;IAC1D,0EAA0E;IAC1E,2EAA2E,EAC7E;IACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;IACrG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAC9D,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE;SACtE,QAAQ,CAAC,8BAA8B,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;CACjF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC;YAC1C,KAAK;YACL,QAAQ;YACR,IAAI;YACJ,KAAK,EAAE,KAAK,IAAI,EAAE;SACnB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACxC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YAC3C,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;YAC/C,MAAM,EAAE,GAAG,CAAC,WAAW;YACvB,IAAI,EAAE,GAAG,CAAC,QAAQ;YAClB,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YAC7E,KAAK,EAAE,GAAG,CAAC,WAAW;SACvB,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK;wBAC9B,OAAO,EAAE,OAAO,CAAC,MAAM;wBACvB,IAAI,EAAE,OAAO;wBACb,GAAG,EAAE,yGAAyG;qBAC/G,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,yBAA0B,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7F,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAE/E,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,+DAA+D;IAC7D,uDAAuD,EACzD,EAAE,EACF,KAAK,IAAI,EAAE;IACT,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,aAAa,EAAE,CAAC;QACjD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,UAAU,EAAE,MAAM,CAAC,UAAU;wBAC7B,iBAAiB,EAAE,MAAM,CAAC,WAAW;wBACrC,mBAAmB,EAAE,MAAM,CAAC,aAAa;qBAC1C,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9E,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAE/E,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,uEAAuE;IACrE,+EAA+E,EACjF;IACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;CACnG,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEpD,MAAM,OAAO,GAA4B;YACvC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB;YACxD,MAAM,EAAE,GAAG,CAAC,WAAW;YACvB,IAAI,EAAE,GAAG,CAAC,QAAQ;YAClB,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,YAAY,WAAW,CAAC,CAAC,CAAC,SAAS;YAC3G,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,MAAM,EAAE,GAAG,CAAC,WAAW;SACxB,CAAC;QAEF,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;YACrB,OAAO,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;QAC1C,CAAC;QAED,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC;gBACH,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;YAChD,CAAC;QACH,CAAC;QAED,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC9D,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC,gBAAgB,CAAC;YAClD,CAAC;QACH,CAAC;QAED,OAAO,CAAC,WAAW,GAAG;YACpB,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE;gBACN,MAAM,EAAE,GAAG,CAAC,EAAE;gBACd,MAAM,EAAE,GAAG,CAAC,WAAW;gBACvB,IAAI,EAAE,GAAG,CAAC,YAAY,EAAE,MAAM;oBAC5B,CAAC,CAAC,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;wBACtD,CAAC;wBACD,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,IAAI,GAAG;qBAC3B,CAAC,CACH;oBACH,CAAC,CAAC,SAAS;aACd;YACD,IAAI,EAAE,MAAM;gBACV,CAAC,CAAC,oDAAoD,MAAM,CAAC,OAAO,EAAE;gBACtE,CAAC,CAAC,6DAA6D;SAClE,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC7E,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9E,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAE/E,MAAM,CAAC,IAAI,CACT,UAAU,EACV,kFAAkF;IAChF,iDAAiD;IACjD,uEAAuE,EACzE;IACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACjD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IACjG,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;IACpF,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;CACrF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE;IAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EACF,0EAA0E;wBAC1E,2DAA2D;wBAC3D,oEAAoE;iBACvE;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE;YAC/C,MAAM;YACN,IAAI;YACJ,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;gBACrC,OAAO,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;YAC7C,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;4BACE,KAAK,EAAE,IAAI;4BACX,MAAM,EAAE,MAAM,CAAC,MAAM;4BACrB,IAAI,EAAE,MAAM,CAAC,IAAI;yBAClB,EACD,IAAI,EACJ,CAAC,CACF;qBACF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,IAAI,EAAE,MAAM,CAAC,IAAI;qBAClB,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oBAAqB,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YACxF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAE/E,MAAM,CAAC,IAAI,CACT,aAAa,EACb,kEAAkE,EAClE,EAAE,EACF,KAAK,IAAI,EAAE;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,uDAAuD;iBAC9D;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAC;QAC9C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,YAAY,EAAE,GAAG,OAAO,CAAC,SAAS,OAAO;wBACzC,OAAO,EAAE,uBAAuB;qBACjC,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,yBAA0B,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7F,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAE/E,MAAM,CAAC,QAAQ,CACb,kBAAkB,EAClB,2BAA2B,EAC3B,KAAK,IAAI,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE;QACR;YACE,GAAG,EAAE,2BAA2B;YAChC,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;gBACE,IAAI,EAAE,yBAAyB;gBAC/B,GAAG,EAAE,cAAc;gBACnB,WAAW,EACT,8DAA8D;oBAC9D,yEAAyE;oBACzE,2DAA2D;gBAC7D,MAAM,EAAE,MAAM;oBACZ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE;oBAC/C,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,2CAA2C,EAAE;gBAC5E,aAAa,EAAE,qCAAqC;aACrD,EACD,IAAI,EACJ,CAAC,CACF;SACF;KACF;CACF,CAAC,CACH,CAAC;AAEF,+EAA+E;AAE/E,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,6BAA6B,cAAc,EAAE,CAAC,CAAC;IAC7D,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Obolos Marketplace API Client
|
|
3
|
+
* Fetches API catalog from the Obolos marketplace backend
|
|
4
|
+
*/
|
|
5
|
+
import type { MarketplaceApi, MarketplaceListResponse, MarketplaceSearchResponse, CategoryResponse } from './types.js';
|
|
6
|
+
export declare class MarketplaceClient {
|
|
7
|
+
private baseUrl;
|
|
8
|
+
constructor(baseUrl: string);
|
|
9
|
+
/**
|
|
10
|
+
* List all marketplace APIs with optional category filter
|
|
11
|
+
*/
|
|
12
|
+
listApis(options?: {
|
|
13
|
+
category?: string;
|
|
14
|
+
page?: number;
|
|
15
|
+
limit?: number;
|
|
16
|
+
}): Promise<MarketplaceListResponse>;
|
|
17
|
+
/**
|
|
18
|
+
* Search APIs by query, category, and sort order
|
|
19
|
+
*/
|
|
20
|
+
searchApis(options: {
|
|
21
|
+
query?: string;
|
|
22
|
+
category?: string;
|
|
23
|
+
sort?: 'popular' | 'newest' | 'price_asc' | 'price_desc';
|
|
24
|
+
page?: number;
|
|
25
|
+
limit?: number;
|
|
26
|
+
}): Promise<MarketplaceSearchResponse>;
|
|
27
|
+
/**
|
|
28
|
+
* Get full details for a single API
|
|
29
|
+
*/
|
|
30
|
+
getApiDetails(id: string): Promise<MarketplaceApi>;
|
|
31
|
+
/**
|
|
32
|
+
* List all available categories
|
|
33
|
+
*/
|
|
34
|
+
getCategories(): Promise<CategoryResponse>;
|
|
35
|
+
/**
|
|
36
|
+
* Call an API via the Obolos proxy.
|
|
37
|
+
* Handles the x402 payment flow: initial request → 402 → sign → retry.
|
|
38
|
+
*/
|
|
39
|
+
callApi(apiId: string, options: {
|
|
40
|
+
method?: string;
|
|
41
|
+
body?: Record<string, unknown>;
|
|
42
|
+
queryParams?: Record<string, string>;
|
|
43
|
+
signPayment: (paymentRequired: any) => Promise<Record<string, string>>;
|
|
44
|
+
}): Promise<{
|
|
45
|
+
status: number;
|
|
46
|
+
headers: Record<string, string>;
|
|
47
|
+
body: unknown;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Obolos Marketplace API Client
|
|
3
|
+
* Fetches API catalog from the Obolos marketplace backend
|
|
4
|
+
*/
|
|
5
|
+
export class MarketplaceClient {
|
|
6
|
+
baseUrl;
|
|
7
|
+
constructor(baseUrl) {
|
|
8
|
+
// Strip trailing slash
|
|
9
|
+
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* List all marketplace APIs with optional category filter
|
|
13
|
+
*/
|
|
14
|
+
async listApis(options) {
|
|
15
|
+
const params = new URLSearchParams();
|
|
16
|
+
if (options?.category)
|
|
17
|
+
params.set('category', options.category);
|
|
18
|
+
if (options?.page)
|
|
19
|
+
params.set('page', String(options.page));
|
|
20
|
+
if (options?.limit)
|
|
21
|
+
params.set('limit', String(options.limit));
|
|
22
|
+
params.set('type', 'native');
|
|
23
|
+
const url = `${this.baseUrl}/api/marketplace/apis?${params}`;
|
|
24
|
+
const res = await fetch(url);
|
|
25
|
+
if (!res.ok)
|
|
26
|
+
throw new Error(`Marketplace list failed: ${res.status} ${res.statusText}`);
|
|
27
|
+
return res.json();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Search APIs by query, category, and sort order
|
|
31
|
+
*/
|
|
32
|
+
async searchApis(options) {
|
|
33
|
+
const params = new URLSearchParams();
|
|
34
|
+
if (options.query)
|
|
35
|
+
params.set('q', options.query);
|
|
36
|
+
if (options.category)
|
|
37
|
+
params.set('category', options.category);
|
|
38
|
+
if (options.sort)
|
|
39
|
+
params.set('sort', options.sort);
|
|
40
|
+
if (options.page)
|
|
41
|
+
params.set('page', String(options.page));
|
|
42
|
+
if (options.limit)
|
|
43
|
+
params.set('limit', String(options.limit));
|
|
44
|
+
params.set('type', 'native');
|
|
45
|
+
const url = `${this.baseUrl}/api/marketplace/apis/search?${params}`;
|
|
46
|
+
const res = await fetch(url);
|
|
47
|
+
if (!res.ok)
|
|
48
|
+
throw new Error(`Marketplace search failed: ${res.status} ${res.statusText}`);
|
|
49
|
+
return res.json();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get full details for a single API
|
|
53
|
+
*/
|
|
54
|
+
async getApiDetails(id) {
|
|
55
|
+
const url = `${this.baseUrl}/api/marketplace/apis/${encodeURIComponent(id)}`;
|
|
56
|
+
const res = await fetch(url);
|
|
57
|
+
if (!res.ok)
|
|
58
|
+
throw new Error(`API detail fetch failed: ${res.status} ${res.statusText}`);
|
|
59
|
+
return res.json();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* List all available categories
|
|
63
|
+
*/
|
|
64
|
+
async getCategories() {
|
|
65
|
+
const url = `${this.baseUrl}/api/marketplace/categories`;
|
|
66
|
+
const res = await fetch(url);
|
|
67
|
+
if (!res.ok)
|
|
68
|
+
throw new Error(`Categories fetch failed: ${res.status} ${res.statusText}`);
|
|
69
|
+
return res.json();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Call an API via the Obolos proxy.
|
|
73
|
+
* Handles the x402 payment flow: initial request → 402 → sign → retry.
|
|
74
|
+
*/
|
|
75
|
+
async callApi(apiId, options) {
|
|
76
|
+
const method = (options.method || 'GET').toUpperCase();
|
|
77
|
+
const proxyUrl = new URL(`${this.baseUrl}/api/proxy/${encodeURIComponent(apiId)}`);
|
|
78
|
+
if (options.queryParams) {
|
|
79
|
+
for (const [k, v] of Object.entries(options.queryParams)) {
|
|
80
|
+
proxyUrl.searchParams.set(k, v);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const fetchOptions = { method };
|
|
84
|
+
if (method !== 'GET' && options.body) {
|
|
85
|
+
fetchOptions.headers = { 'Content-Type': 'application/json' };
|
|
86
|
+
fetchOptions.body = JSON.stringify(options.body);
|
|
87
|
+
}
|
|
88
|
+
// First request — expect 402
|
|
89
|
+
let response = await fetch(proxyUrl.toString(), fetchOptions);
|
|
90
|
+
if (response.status === 402) {
|
|
91
|
+
// Parse payment requirements from body (v1 format) or header (v2)
|
|
92
|
+
let paymentInfo;
|
|
93
|
+
try {
|
|
94
|
+
paymentInfo = await response.json();
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
throw new Error('Got 402 but could not parse payment requirements');
|
|
98
|
+
}
|
|
99
|
+
// Ask caller to sign the payment
|
|
100
|
+
const paymentHeaders = await options.signPayment(paymentInfo);
|
|
101
|
+
// Retry with payment
|
|
102
|
+
const paidFetchOptions = {
|
|
103
|
+
...fetchOptions,
|
|
104
|
+
headers: {
|
|
105
|
+
...(fetchOptions.headers || {}),
|
|
106
|
+
...paymentHeaders,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
response = await fetch(proxyUrl.toString(), paidFetchOptions);
|
|
110
|
+
}
|
|
111
|
+
// Collect response headers
|
|
112
|
+
const responseHeaders = {};
|
|
113
|
+
response.headers.forEach((v, k) => {
|
|
114
|
+
responseHeaders[k] = v;
|
|
115
|
+
});
|
|
116
|
+
// Parse response body
|
|
117
|
+
const contentType = response.headers.get('content-type') || '';
|
|
118
|
+
let body;
|
|
119
|
+
if (contentType.includes('application/json')) {
|
|
120
|
+
body = await response.json();
|
|
121
|
+
}
|
|
122
|
+
else if (contentType.includes('text/')) {
|
|
123
|
+
body = await response.text();
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// Binary — return base64
|
|
127
|
+
const buffer = await response.arrayBuffer();
|
|
128
|
+
body = {
|
|
129
|
+
_binary: true,
|
|
130
|
+
contentType,
|
|
131
|
+
base64: Buffer.from(buffer).toString('base64'),
|
|
132
|
+
size: buffer.byteLength,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return { status: response.status, headers: responseHeaders, body };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=marketplace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marketplace.js","sourceRoot":"","sources":["../src/marketplace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 Payment Signing for MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Signs x402 payment requests using a private key (no browser wallet needed).
|
|
5
|
+
* Supports both v1 (exact) and v2 (x402x-router-settlement) payment schemes.
|
|
6
|
+
*/
|
|
7
|
+
export declare class PaymentSigner {
|
|
8
|
+
private account;
|
|
9
|
+
private client;
|
|
10
|
+
constructor(privateKey: string);
|
|
11
|
+
get address(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Get USDC balance for the signing wallet
|
|
14
|
+
*/
|
|
15
|
+
getUsdcBalance(): Promise<{
|
|
16
|
+
raw: bigint;
|
|
17
|
+
formatted: string;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Sign an x402 payment request and return the payment headers.
|
|
21
|
+
*
|
|
22
|
+
* This handles the EIP-712 typed data signing that the x402 protocol requires.
|
|
23
|
+
* Works with both v1 (exact scheme) and v2 format 402 responses.
|
|
24
|
+
*/
|
|
25
|
+
signPayment(paymentRequired: any): Promise<Record<string, string>>;
|
|
26
|
+
}
|
package/dist/payment.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 Payment Signing for MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Signs x402 payment requests using a private key (no browser wallet needed).
|
|
5
|
+
* Supports both v1 (exact) and v2 (x402x-router-settlement) payment schemes.
|
|
6
|
+
*/
|
|
7
|
+
import { createWalletClient, http, publicActions, formatUnits, } from 'viem';
|
|
8
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
9
|
+
import { base } from 'viem/chains';
|
|
10
|
+
const USDC_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
|
|
11
|
+
const USDC_ABI = [
|
|
12
|
+
{
|
|
13
|
+
inputs: [{ name: 'account', type: 'address' }],
|
|
14
|
+
name: 'balanceOf',
|
|
15
|
+
outputs: [{ name: '', type: 'uint256' }],
|
|
16
|
+
stateMutability: 'view',
|
|
17
|
+
type: 'function',
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
export class PaymentSigner {
|
|
21
|
+
account;
|
|
22
|
+
client;
|
|
23
|
+
constructor(privateKey) {
|
|
24
|
+
if (!privateKey.startsWith('0x')) {
|
|
25
|
+
privateKey = `0x${privateKey}`;
|
|
26
|
+
}
|
|
27
|
+
this.account = privateKeyToAccount(privateKey);
|
|
28
|
+
this.client = createWalletClient({
|
|
29
|
+
account: this.account,
|
|
30
|
+
chain: base,
|
|
31
|
+
transport: http(),
|
|
32
|
+
}).extend(publicActions);
|
|
33
|
+
}
|
|
34
|
+
get address() {
|
|
35
|
+
return this.account.address;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get USDC balance for the signing wallet
|
|
39
|
+
*/
|
|
40
|
+
async getUsdcBalance() {
|
|
41
|
+
const balance = await this.client.readContract({
|
|
42
|
+
address: USDC_ADDRESS,
|
|
43
|
+
abi: USDC_ABI,
|
|
44
|
+
functionName: 'balanceOf',
|
|
45
|
+
args: [this.account.address],
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
raw: balance,
|
|
49
|
+
formatted: formatUnits(balance, 6),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Sign an x402 payment request and return the payment headers.
|
|
54
|
+
*
|
|
55
|
+
* This handles the EIP-712 typed data signing that the x402 protocol requires.
|
|
56
|
+
* Works with both v1 (exact scheme) and v2 format 402 responses.
|
|
57
|
+
*/
|
|
58
|
+
async signPayment(paymentRequired) {
|
|
59
|
+
// Extract payment details from the 402 response
|
|
60
|
+
const accepts = paymentRequired.accepts;
|
|
61
|
+
if (!accepts || accepts.length === 0) {
|
|
62
|
+
throw new Error('No payment options in 402 response');
|
|
63
|
+
}
|
|
64
|
+
const requirement = accepts[0];
|
|
65
|
+
const scheme = requirement.scheme || 'exact';
|
|
66
|
+
const network = requirement.network || 'base';
|
|
67
|
+
const amount = requirement.maxAmountRequired || requirement.amount;
|
|
68
|
+
const payTo = requirement.payTo;
|
|
69
|
+
const asset = requirement.asset || USDC_ADDRESS;
|
|
70
|
+
if (!amount || !payTo) {
|
|
71
|
+
throw new Error('Missing amount or payTo in payment requirement');
|
|
72
|
+
}
|
|
73
|
+
// Build EIP-712 typed data for the exact scheme
|
|
74
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + 300); // 5 min
|
|
75
|
+
const amountBigInt = BigInt(amount);
|
|
76
|
+
const domain = {
|
|
77
|
+
name: 'x402',
|
|
78
|
+
version: '1',
|
|
79
|
+
chainId: 8453n,
|
|
80
|
+
verifyingContract: asset,
|
|
81
|
+
};
|
|
82
|
+
const types = {
|
|
83
|
+
TransferWithAuthorization: [
|
|
84
|
+
{ name: 'from', type: 'address' },
|
|
85
|
+
{ name: 'to', type: 'address' },
|
|
86
|
+
{ name: 'value', type: 'uint256' },
|
|
87
|
+
{ name: 'validAfter', type: 'uint256' },
|
|
88
|
+
{ name: 'validBefore', type: 'uint256' },
|
|
89
|
+
{ name: 'nonce', type: 'bytes32' },
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
// Generate a random nonce
|
|
93
|
+
const nonceBytes = new Uint8Array(32);
|
|
94
|
+
crypto.getRandomValues(nonceBytes);
|
|
95
|
+
const nonce = `0x${Array.from(nonceBytes).map(b => b.toString(16).padStart(2, '0')).join('')}`;
|
|
96
|
+
const message = {
|
|
97
|
+
from: this.account.address,
|
|
98
|
+
to: payTo,
|
|
99
|
+
value: amountBigInt,
|
|
100
|
+
validAfter: 0n,
|
|
101
|
+
validBefore: deadline,
|
|
102
|
+
nonce,
|
|
103
|
+
};
|
|
104
|
+
const signature = await this.client.signTypedData({
|
|
105
|
+
account: this.account,
|
|
106
|
+
domain,
|
|
107
|
+
types,
|
|
108
|
+
primaryType: 'TransferWithAuthorization',
|
|
109
|
+
message,
|
|
110
|
+
});
|
|
111
|
+
// Build the payment payload
|
|
112
|
+
const paymentPayload = {
|
|
113
|
+
x402Version: paymentRequired.x402Version || 1,
|
|
114
|
+
scheme,
|
|
115
|
+
network,
|
|
116
|
+
payload: {
|
|
117
|
+
signature,
|
|
118
|
+
authorization: {
|
|
119
|
+
from: this.account.address,
|
|
120
|
+
to: payTo,
|
|
121
|
+
value: amount.toString(),
|
|
122
|
+
validAfter: '0',
|
|
123
|
+
validBefore: deadline.toString(),
|
|
124
|
+
nonce,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
// Encode as base64 for the payment header
|
|
129
|
+
const encoded = Buffer.from(JSON.stringify(paymentPayload)).toString('base64');
|
|
130
|
+
// Return appropriate headers based on version
|
|
131
|
+
if (paymentRequired.x402Version === 2) {
|
|
132
|
+
return { 'payment-signature': encoded };
|
|
133
|
+
}
|
|
134
|
+
return { 'x-payment': encoded };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=payment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Obolos MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export interface MarketplaceApi {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
slug: string | null;
|
|
8
|
+
description: string;
|
|
9
|
+
category: string;
|
|
10
|
+
price_per_call: number;
|
|
11
|
+
http_method: string;
|
|
12
|
+
seller_name: string;
|
|
13
|
+
total_calls: number;
|
|
14
|
+
example_request: string | null;
|
|
15
|
+
example_response: string | null;
|
|
16
|
+
api_type: 'native' | 'external';
|
|
17
|
+
average_rating: number | null;
|
|
18
|
+
review_count: number;
|
|
19
|
+
input_schema?: InputSchema | null;
|
|
20
|
+
input_type?: string;
|
|
21
|
+
response_type?: string;
|
|
22
|
+
proxy_endpoint?: string;
|
|
23
|
+
resource_url?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface InputSchema {
|
|
26
|
+
method: string;
|
|
27
|
+
bodyType: string;
|
|
28
|
+
fields: Record<string, FieldSchema>;
|
|
29
|
+
exampleResponse?: unknown;
|
|
30
|
+
}
|
|
31
|
+
export interface FieldSchema {
|
|
32
|
+
type: string;
|
|
33
|
+
required?: boolean;
|
|
34
|
+
example?: unknown;
|
|
35
|
+
description?: string;
|
|
36
|
+
enum?: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface MarketplaceListResponse {
|
|
39
|
+
apis: MarketplaceApi[];
|
|
40
|
+
pagination: {
|
|
41
|
+
page: number;
|
|
42
|
+
limit: number;
|
|
43
|
+
total: number;
|
|
44
|
+
total_pages: number;
|
|
45
|
+
has_next: boolean;
|
|
46
|
+
has_prev: boolean;
|
|
47
|
+
};
|
|
48
|
+
timestamp: string;
|
|
49
|
+
}
|
|
50
|
+
export interface MarketplaceSearchResponse extends MarketplaceListResponse {
|
|
51
|
+
query: string | null;
|
|
52
|
+
category: string | null;
|
|
53
|
+
sort: string;
|
|
54
|
+
}
|
|
55
|
+
export interface CategoryResponse {
|
|
56
|
+
categories: Array<{
|
|
57
|
+
name: string;
|
|
58
|
+
count: number;
|
|
59
|
+
}>;
|
|
60
|
+
nativeCount: number;
|
|
61
|
+
externalCount: number;
|
|
62
|
+
count: number;
|
|
63
|
+
}
|
|
64
|
+
export interface PaymentRequiredResponse {
|
|
65
|
+
x402Version: number;
|
|
66
|
+
accepts: Array<{
|
|
67
|
+
scheme: string;
|
|
68
|
+
network: string;
|
|
69
|
+
maxAmountRequired?: string;
|
|
70
|
+
amount?: string;
|
|
71
|
+
resource?: string;
|
|
72
|
+
payTo: string;
|
|
73
|
+
asset: string;
|
|
74
|
+
}>;
|
|
75
|
+
error?: string;
|
|
76
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@obolos_tech/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for Obolos x402 API marketplace — lets AI agents discover and pay for APIs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"files": ["dist", "README.md"],
|
|
8
|
+
"bin": {
|
|
9
|
+
"obolos-mcp": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsx src/index.ts",
|
|
14
|
+
"start": "node dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"x402",
|
|
19
|
+
"obolos",
|
|
20
|
+
"ai-agents",
|
|
21
|
+
"micropayments",
|
|
22
|
+
"marketplace"
|
|
23
|
+
],
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
27
|
+
"viem": "^2.45.2",
|
|
28
|
+
"zod": "^3.25.76"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^22.0.0",
|
|
32
|
+
"tsx": "^4.21.0",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
}
|
|
35
|
+
}
|