bsv-mcp 0.2.0 → 0.2.7
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/CHANGELOG.md +13 -0
- package/dist/index.js +87272 -70728
- package/index.ts +409 -22
- package/package.json +28 -24
- package/tools/a2b/discover.ts +13 -13
- package/tools/bap/friend.ts +2 -3
- package/tools/bap/generate.ts +7 -9
- package/tools/bap/getCurrentAddress.ts +1 -8
- package/tools/bap/getId.ts +3 -3
- package/tools/bsocial/bmapFollow.ts +3 -7
- package/tools/bsocial/bmapLikes.ts +3 -3
- package/tools/bsocial/bmapReadPosts.ts +3 -3
- package/tools/bsocial/createPost.ts +3 -3
- package/tools/bsocial/readPosts.ts +3 -3
- package/tools/bsv/decodeTransaction.ts +2 -5
- package/tools/bsv/explore.ts +2 -3
- package/tools/bsv/getPrice.ts +1 -9
- package/tools/bsv/token.ts +14 -26
- package/tools/index.ts +0 -13
- package/tools/mnee/getBalance.ts +2 -4
- package/tools/mnee/parseTx.ts +3 -3
- package/tools/mnee/sendMnee.ts +5 -5
- package/tools/ordinals/getInscription.ts +2 -3
- package/tools/ordinals/getTokenByIdOrTicker.ts +6 -3
- package/tools/ordinals/marketListings.ts +2 -18
- package/tools/ordinals/marketSales.ts +2 -4
- package/tools/ordinals/searchInscriptions.ts +2 -4
- package/tools/utils/index.ts +14 -16
- package/tools/wallet/a2bPublishAgent.ts +18 -27
- package/tools/wallet/a2bPublishMcp.ts +17 -22
- package/tools/wallet/createOrdinals.ts +11 -20
- package/tools/wallet/fetchPaymentUtxos.ts +9 -1
- package/tools/wallet/gatherCollectionInfo.ts +9 -13
- package/tools/wallet/getAddress.ts +1 -9
- package/tools/wallet/getBalance.ts +2 -14
- package/tools/wallet/getBalanceDroplet.ts +2 -13
- package/tools/wallet/getPublicKey.ts +3 -16
- package/tools/wallet/mintCollection.ts +17 -22
- package/tools/wallet/purchaseListing.ts +19 -29
- package/tools/wallet/refreshUtxos.ts +2 -14
- package/tools/wallet/sendOrdinals.ts +11 -20
- package/tools/wallet/sendToAddress.ts +2 -22
- package/tools/wallet/setupDroplet.ts +7 -18
- package/tools/wallet/tools.ts +10 -80
- package/tools/wallet/transferOrdToken.ts +12 -20
- package/vite.config.ts +15 -0
- package/tools/bigblocks/components.ts +0 -304
- package/tools/bigblocks/docs.ts +0 -488
- package/tools/bigblocks/examples.ts +0 -527
- package/tools/bigblocks/generator.ts +0 -485
- package/tools/bigblocks/index.ts +0 -23
- package/tools/bsocial/bigblocksApiClient.ts +0 -189
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { basename, extname, resolve } from "node:path";
|
|
3
|
-
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
-
import { z } from "zod";
|
|
5
|
-
|
|
6
|
-
// TypeScript interfaces for BigBlocks registry
|
|
7
|
-
interface BigBlocksComponent {
|
|
8
|
-
name: string;
|
|
9
|
-
type: string;
|
|
10
|
-
description: string;
|
|
11
|
-
files?: string[];
|
|
12
|
-
dependencies?: string[];
|
|
13
|
-
registryDependencies?: string[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface BigBlocksRegistry {
|
|
17
|
-
components: BigBlocksComponent[];
|
|
18
|
-
version?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Load BigBlocks registry data
|
|
22
|
-
function loadBigBlocksRegistry(): BigBlocksRegistry | null {
|
|
23
|
-
try {
|
|
24
|
-
const registryPath = resolve(
|
|
25
|
-
"node_modules/bigblocks/registry/registry.json",
|
|
26
|
-
);
|
|
27
|
-
const registryData = JSON.parse(readFileSync(registryPath, "utf-8"));
|
|
28
|
-
return registryData as BigBlocksRegistry;
|
|
29
|
-
} catch (error) {
|
|
30
|
-
console.error("Failed to load BigBlocks registry:", error);
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Code generation templates
|
|
36
|
-
const TEMPLATES = {
|
|
37
|
-
"auth-setup": {
|
|
38
|
-
description: "Complete authentication setup with providers",
|
|
39
|
-
code: `import {
|
|
40
|
-
BitcoinAuthProvider,
|
|
41
|
-
BitcoinThemeProvider,
|
|
42
|
-
BitcoinQueryProvider,
|
|
43
|
-
type BitcoinAuthConfig
|
|
44
|
-
} from 'bigblocks';
|
|
45
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
46
|
-
import { Theme } from '@radix-ui/themes';
|
|
47
|
-
import '@radix-ui/themes/styles.css';
|
|
48
|
-
|
|
49
|
-
const queryClient = new QueryClient();
|
|
50
|
-
|
|
51
|
-
const authConfig: BitcoinAuthConfig = {
|
|
52
|
-
apiUrl: process.env.NEXT_PUBLIC_API_URL || '/api/auth',
|
|
53
|
-
storage: {
|
|
54
|
-
async get(key: string): Promise<string | null> {
|
|
55
|
-
return localStorage.getItem(key);
|
|
56
|
-
},
|
|
57
|
-
async set(key: string, value: string): Promise<void> {
|
|
58
|
-
localStorage.setItem(key, value);
|
|
59
|
-
},
|
|
60
|
-
async remove(key: string): Promise<void> {
|
|
61
|
-
localStorage.removeItem(key);
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
storageNamespace: 'my-app-auth',
|
|
65
|
-
oauthProviders: ['google', 'github'],
|
|
66
|
-
backupTypes: {
|
|
67
|
-
enabled: ['BapMasterBackup', 'BapMemberBackup', 'OneSatBackup', 'WifBackup']
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
72
|
-
return (
|
|
73
|
-
<QueryClientProvider client={queryClient}>
|
|
74
|
-
<Theme appearance="dark" accentColor="amber">
|
|
75
|
-
<BitcoinThemeProvider>
|
|
76
|
-
<BitcoinQueryProvider>
|
|
77
|
-
<BitcoinAuthProvider config={authConfig}>
|
|
78
|
-
{children}
|
|
79
|
-
</BitcoinAuthProvider>
|
|
80
|
-
</BitcoinQueryProvider>
|
|
81
|
-
</BitcoinThemeProvider>
|
|
82
|
-
</Theme>
|
|
83
|
-
</QueryClientProvider>
|
|
84
|
-
);
|
|
85
|
-
}`,
|
|
86
|
-
},
|
|
87
|
-
"auth-flow": {
|
|
88
|
-
description: "Complete authentication flow component",
|
|
89
|
-
code: `import {
|
|
90
|
-
AuthFlowOrchestrator,
|
|
91
|
-
useBitcoinAuth,
|
|
92
|
-
type AuthFlowType
|
|
93
|
-
} from 'bigblocks';
|
|
94
|
-
import { useState } from 'react';
|
|
95
|
-
|
|
96
|
-
interface AuthFlowProps {
|
|
97
|
-
onSuccess?: () => void;
|
|
98
|
-
flowType?: AuthFlowType;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function AuthFlow({ onSuccess, flowType = 'unified' }: AuthFlowProps) {
|
|
102
|
-
const { user, isAuthenticated } = useBitcoinAuth();
|
|
103
|
-
|
|
104
|
-
const handleSuccess = (user: any) => {
|
|
105
|
-
console.log('Authentication successful:', user);
|
|
106
|
-
onSuccess?.();
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const handleError = (error: Error) => {
|
|
110
|
-
console.error('Authentication error:', error);
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
if (isAuthenticated) {
|
|
114
|
-
return (
|
|
115
|
-
<div className="text-center">
|
|
116
|
-
<h2>Welcome, {user?.profile?.name || 'User'}!</h2>
|
|
117
|
-
<p>You are successfully authenticated.</p>
|
|
118
|
-
</div>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return (
|
|
123
|
-
<AuthFlowOrchestrator
|
|
124
|
-
flowType={flowType}
|
|
125
|
-
enableOAuth={true}
|
|
126
|
-
enableFileImport={true}
|
|
127
|
-
enableLocalBackup={true}
|
|
128
|
-
onSuccess={handleSuccess}
|
|
129
|
-
onError={handleError}
|
|
130
|
-
title="Sign In"
|
|
131
|
-
subtitle="Secure authentication using Bitcoin signatures"
|
|
132
|
-
showHeader={true}
|
|
133
|
-
showFooter={true}
|
|
134
|
-
layout="centered"
|
|
135
|
-
autoDetectFlow={true}
|
|
136
|
-
persistFlow={true}
|
|
137
|
-
/>
|
|
138
|
-
);
|
|
139
|
-
}`,
|
|
140
|
-
},
|
|
141
|
-
"social-feed": {
|
|
142
|
-
description: "Social media feed with BigBlocks components",
|
|
143
|
-
code: `import {
|
|
144
|
-
SocialFeed,
|
|
145
|
-
PostButton,
|
|
146
|
-
LikeButton,
|
|
147
|
-
FollowButton,
|
|
148
|
-
PostCard
|
|
149
|
-
} from 'bigblocks';
|
|
150
|
-
import { useState, useEffect } from 'react';
|
|
151
|
-
|
|
152
|
-
export function MySocialFeed() {
|
|
153
|
-
const [posts, setPosts] = useState([]);
|
|
154
|
-
const [loading, setLoading] = useState(true);
|
|
155
|
-
|
|
156
|
-
const handleNewPost = (txid: string) => {
|
|
157
|
-
console.log('New post created:', txid);
|
|
158
|
-
// Refresh posts or add new post to feed
|
|
159
|
-
loadPosts();
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const loadPosts = async () => {
|
|
163
|
-
try {
|
|
164
|
-
// Fetch posts from your API or BMAP
|
|
165
|
-
const response = await fetch('/api/posts');
|
|
166
|
-
const data = await response.json();
|
|
167
|
-
setPosts(data.posts || []);
|
|
168
|
-
} catch (error) {
|
|
169
|
-
console.error('Failed to load posts:', error);
|
|
170
|
-
} finally {
|
|
171
|
-
setLoading(false);
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
useEffect(() => {
|
|
176
|
-
loadPosts();
|
|
177
|
-
}, []);
|
|
178
|
-
|
|
179
|
-
return (
|
|
180
|
-
<div className="max-w-2xl mx-auto p-4">
|
|
181
|
-
<div className="mb-6">
|
|
182
|
-
<PostButton
|
|
183
|
-
onSuccess={handleNewPost}
|
|
184
|
-
encryption={false}
|
|
185
|
-
placeholder="What's happening?"
|
|
186
|
-
/>
|
|
187
|
-
</div>
|
|
188
|
-
|
|
189
|
-
<SocialFeed
|
|
190
|
-
posts={posts}
|
|
191
|
-
loading={loading}
|
|
192
|
-
onLoadMore={() => {
|
|
193
|
-
// Load more posts
|
|
194
|
-
console.log('Load more posts');
|
|
195
|
-
}}
|
|
196
|
-
showActions={true}
|
|
197
|
-
/>
|
|
198
|
-
</div>
|
|
199
|
-
);
|
|
200
|
-
}`,
|
|
201
|
-
},
|
|
202
|
-
"wallet-interface": {
|
|
203
|
-
description: "Complete wallet interface with BigBlocks",
|
|
204
|
-
code: `import {
|
|
205
|
-
WalletOverview,
|
|
206
|
-
SendBSVButton,
|
|
207
|
-
TokenBalance,
|
|
208
|
-
QuickSendButton,
|
|
209
|
-
DonateButton
|
|
210
|
-
} from 'bigblocks';
|
|
211
|
-
import { useState } from 'react';
|
|
212
|
-
|
|
213
|
-
export function WalletInterface() {
|
|
214
|
-
const [selectedAmount, setSelectedAmount] = useState(0.001);
|
|
215
|
-
|
|
216
|
-
const handleSendSuccess = (txid: string) => {
|
|
217
|
-
console.log('Payment sent successfully:', txid);
|
|
218
|
-
// Refresh wallet data
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const handleDonation = (txid: string) => {
|
|
222
|
-
console.log('Donation sent:', txid);
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
return (
|
|
226
|
-
<div className="max-w-4xl mx-auto p-6">
|
|
227
|
-
<h1 className="text-2xl font-bold mb-6">My Wallet</h1>
|
|
228
|
-
|
|
229
|
-
{/* Wallet Overview */}
|
|
230
|
-
<div className="mb-8">
|
|
231
|
-
<WalletOverview
|
|
232
|
-
showHistory={true}
|
|
233
|
-
showTokens={true}
|
|
234
|
-
compact={false}
|
|
235
|
-
/>
|
|
236
|
-
</div>
|
|
237
|
-
|
|
238
|
-
{/* Quick Actions */}
|
|
239
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
|
|
240
|
-
<div className="space-y-4">
|
|
241
|
-
<h2 className="text-lg font-semibold">Send BSV</h2>
|
|
242
|
-
<SendBSVButton
|
|
243
|
-
amount={selectedAmount}
|
|
244
|
-
onSuccess={handleSendSuccess}
|
|
245
|
-
confirmRequired={true}
|
|
246
|
-
/>
|
|
247
|
-
|
|
248
|
-
<QuickSendButton
|
|
249
|
-
presetAmounts={[0.001, 0.01, 0.1]}
|
|
250
|
-
onSend={handleSendSuccess}
|
|
251
|
-
/>
|
|
252
|
-
</div>
|
|
253
|
-
|
|
254
|
-
<div className="space-y-4">
|
|
255
|
-
<h2 className="text-lg font-semibold">Donations</h2>
|
|
256
|
-
<DonateButton
|
|
257
|
-
recipient="1DonationAddressExample..."
|
|
258
|
-
amounts={[0.01, 0.05, 0.1]}
|
|
259
|
-
message="Thank you for your support!"
|
|
260
|
-
onDonate={handleDonation}
|
|
261
|
-
/>
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
264
|
-
|
|
265
|
-
{/* Token Balances */}
|
|
266
|
-
<div>
|
|
267
|
-
<h2 className="text-lg font-semibold mb-4">Token Balances</h2>
|
|
268
|
-
<TokenBalance
|
|
269
|
-
showTokens={true}
|
|
270
|
-
showUSD={true}
|
|
271
|
-
refreshInterval={30000}
|
|
272
|
-
/>
|
|
273
|
-
</div>
|
|
274
|
-
</div>
|
|
275
|
-
);
|
|
276
|
-
}`,
|
|
277
|
-
},
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
const generatorSchema = z.object({
|
|
281
|
-
template: z
|
|
282
|
-
.string()
|
|
283
|
-
.optional()
|
|
284
|
-
.describe(
|
|
285
|
-
"Template to generate (auth-setup, auth-flow, social-feed, wallet-interface)",
|
|
286
|
-
),
|
|
287
|
-
component: z
|
|
288
|
-
.string()
|
|
289
|
-
.optional()
|
|
290
|
-
.describe("Specific component to generate code for"),
|
|
291
|
-
framework: z
|
|
292
|
-
.enum(["react", "next", "astro"])
|
|
293
|
-
.optional()
|
|
294
|
-
.describe("Framework-specific code generation"),
|
|
295
|
-
listTemplates: z
|
|
296
|
-
.boolean()
|
|
297
|
-
.optional()
|
|
298
|
-
.describe("List all available templates"),
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Register the BigBlocks code generator tool
|
|
303
|
-
*/
|
|
304
|
-
export function registerBigBlocksGeneratorTool(server: McpServer): void {
|
|
305
|
-
server.tool(
|
|
306
|
-
"bigblocks_generate",
|
|
307
|
-
"Generate BigBlocks integration code and boilerplate. Get ready-to-use code snippets for authentication, social features, wallet interfaces, and more.\n\n" +
|
|
308
|
-
"Available templates:\n" +
|
|
309
|
-
"- auth-setup: Complete authentication provider setup\n" +
|
|
310
|
-
"- auth-flow: Authentication flow component\n" +
|
|
311
|
-
"- social-feed: Social media feed interface\n" +
|
|
312
|
-
"- wallet-interface: Complete wallet dashboard\n\n" +
|
|
313
|
-
"Usage examples:\n" +
|
|
314
|
-
'- Generate template: {"template": "auth-setup"}\n' +
|
|
315
|
-
'- Component code: {"component": "auth-flow"}\n' +
|
|
316
|
-
'- List templates: {"listTemplates": true}',
|
|
317
|
-
{ args: generatorSchema },
|
|
318
|
-
async ({ args }) => {
|
|
319
|
-
try {
|
|
320
|
-
const { template, component, framework, listTemplates } = args;
|
|
321
|
-
|
|
322
|
-
// List all templates
|
|
323
|
-
if (listTemplates) {
|
|
324
|
-
let result = "# BigBlocks Code Generator Templates\n\n";
|
|
325
|
-
|
|
326
|
-
for (const [name, data] of Object.entries(TEMPLATES)) {
|
|
327
|
-
result += `## ${name}\n`;
|
|
328
|
-
result += `${data.description}\n\n`;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
result +=
|
|
332
|
-
'Use {"template": "template-name"} to generate specific code.';
|
|
333
|
-
return { content: [{ type: "text", text: result }] };
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Generate specific template
|
|
337
|
-
if (template) {
|
|
338
|
-
const templateData = TEMPLATES[template];
|
|
339
|
-
if (!templateData) {
|
|
340
|
-
const available = Object.keys(TEMPLATES).join(", ");
|
|
341
|
-
return {
|
|
342
|
-
content: [
|
|
343
|
-
{
|
|
344
|
-
type: "text",
|
|
345
|
-
text: `Template "${template}" not found. Available templates: ${available}`,
|
|
346
|
-
},
|
|
347
|
-
],
|
|
348
|
-
isError: true,
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
let result = `# ${template} - ${templateData.description}\n\n`;
|
|
353
|
-
result += "```tsx\n";
|
|
354
|
-
result += templateData.code;
|
|
355
|
-
result += "\n```\n\n";
|
|
356
|
-
|
|
357
|
-
// Add usage instructions
|
|
358
|
-
result += "## Usage Instructions\n\n";
|
|
359
|
-
if (template === "auth-setup") {
|
|
360
|
-
result +=
|
|
361
|
-
"1. Install dependencies: `npm install @tanstack/react-query @radix-ui/themes`\n";
|
|
362
|
-
result += "2. Wrap your app with the AuthProvider component\n";
|
|
363
|
-
result += "3. Configure your authentication API endpoint\n";
|
|
364
|
-
result += "4. Customize the theme and storage options\n";
|
|
365
|
-
} else if (template === "auth-flow") {
|
|
366
|
-
result += "1. Use this component on your login/signup pages\n";
|
|
367
|
-
result += "2. Customize the flow type and callbacks\n";
|
|
368
|
-
result += "3. Handle success/error states appropriately\n";
|
|
369
|
-
} else if (template === "social-feed") {
|
|
370
|
-
result += "1. Implement your posts API endpoint\n";
|
|
371
|
-
result += "2. Configure BMAP integration if needed\n";
|
|
372
|
-
result += "3. Customize the feed appearance and actions\n";
|
|
373
|
-
} else if (template === "wallet-interface") {
|
|
374
|
-
result += "1. Ensure wallet provider is configured\n";
|
|
375
|
-
result += "2. Set up transaction handling\n";
|
|
376
|
-
result += "3. Configure recipient addresses for donations\n";
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return { content: [{ type: "text", text: result }] };
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// Generate code for specific component
|
|
383
|
-
if (component) {
|
|
384
|
-
const registry = loadBigBlocksRegistry();
|
|
385
|
-
if (!registry) {
|
|
386
|
-
return {
|
|
387
|
-
content: [
|
|
388
|
-
{
|
|
389
|
-
type: "text",
|
|
390
|
-
text: "Error: Could not load BigBlocks registry data",
|
|
391
|
-
},
|
|
392
|
-
],
|
|
393
|
-
isError: true,
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
const comp = registry.components.find((c) => c.name === component);
|
|
398
|
-
if (!comp) {
|
|
399
|
-
return {
|
|
400
|
-
content: [
|
|
401
|
-
{
|
|
402
|
-
type: "text",
|
|
403
|
-
text: `Component "${component}" not found in registry`,
|
|
404
|
-
},
|
|
405
|
-
],
|
|
406
|
-
isError: true,
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// Determine the actual component name from files
|
|
411
|
-
const mainFile = comp.files?.[0];
|
|
412
|
-
const componentName = mainFile
|
|
413
|
-
? basename(mainFile, extname(mainFile))
|
|
414
|
-
: component;
|
|
415
|
-
|
|
416
|
-
let result = `# ${componentName} Integration\n\n`;
|
|
417
|
-
result += `**Description:** ${comp.description}\n\n`;
|
|
418
|
-
|
|
419
|
-
// Basic usage example
|
|
420
|
-
result += "## Basic Usage\n\n";
|
|
421
|
-
result += "```tsx\n";
|
|
422
|
-
result += `import { ${componentName}`;
|
|
423
|
-
|
|
424
|
-
// Add dependencies to import
|
|
425
|
-
if (comp.registryDependencies?.length) {
|
|
426
|
-
result += `, ${comp.registryDependencies.join(", ")}`;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
result += " } from 'bigblocks';\n\n";
|
|
430
|
-
|
|
431
|
-
// Generate basic component usage
|
|
432
|
-
result += `export function My${componentName}() {\n`;
|
|
433
|
-
result += " return (\n";
|
|
434
|
-
result += ` <${componentName}\n`;
|
|
435
|
-
result += " // Add your props here\n";
|
|
436
|
-
result += " />\n";
|
|
437
|
-
result += " );\n";
|
|
438
|
-
result += "}\n";
|
|
439
|
-
result += "```\n\n";
|
|
440
|
-
|
|
441
|
-
// Add dependencies info
|
|
442
|
-
if (comp.dependencies?.length) {
|
|
443
|
-
result += `## Dependencies\n\nInstall required packages:\n\`\`\`bash\nnpm install ${comp.dependencies.join(" ")}\n\`\`\`\n\n`;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
return { content: [{ type: "text", text: result }] };
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// Default: show available options
|
|
450
|
-
return {
|
|
451
|
-
content: [
|
|
452
|
-
{
|
|
453
|
-
type: "text",
|
|
454
|
-
text: `# BigBlocks Code Generator
|
|
455
|
-
|
|
456
|
-
Generate ready-to-use BigBlocks integration code.
|
|
457
|
-
|
|
458
|
-
**Available templates:**
|
|
459
|
-
${Object.entries(TEMPLATES)
|
|
460
|
-
.map(([name, data]) => `- **${name}**: ${data.description}`)
|
|
461
|
-
.join("\n")}
|
|
462
|
-
|
|
463
|
-
**Usage:**
|
|
464
|
-
- Generate template: {"template": "template-name"}
|
|
465
|
-
- Component code: {"component": "component-name"}
|
|
466
|
-
- List all templates: {"listTemplates": true}
|
|
467
|
-
|
|
468
|
-
Get started with {"template": "auth-setup"} for authentication or {"template": "wallet-interface"} for wallet functionality.`,
|
|
469
|
-
},
|
|
470
|
-
],
|
|
471
|
-
};
|
|
472
|
-
} catch (error) {
|
|
473
|
-
return {
|
|
474
|
-
content: [
|
|
475
|
-
{
|
|
476
|
-
type: "text",
|
|
477
|
-
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
478
|
-
},
|
|
479
|
-
],
|
|
480
|
-
isError: true,
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
},
|
|
484
|
-
);
|
|
485
|
-
}
|
package/tools/bigblocks/index.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
import { registerBigBlocksComponentTool } from "./components.js";
|
|
3
|
-
import { registerBigBlocksDocsTool } from "./docs.js";
|
|
4
|
-
import { registerBigBlocksExamplesTool } from "./examples.js";
|
|
5
|
-
import { registerBigBlocksGeneratorTool } from "./generator.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Register all BigBlocks tools with the MCP server
|
|
9
|
-
* @param server The MCP server instance
|
|
10
|
-
*/
|
|
11
|
-
export function registerBigBlocksTools(server: McpServer): void {
|
|
12
|
-
// Component discovery and information
|
|
13
|
-
registerBigBlocksComponentTool(server);
|
|
14
|
-
|
|
15
|
-
// Documentation and guides
|
|
16
|
-
registerBigBlocksDocsTool(server);
|
|
17
|
-
|
|
18
|
-
// Code generation helpers
|
|
19
|
-
registerBigBlocksGeneratorTool(server);
|
|
20
|
-
|
|
21
|
-
// Examples and patterns
|
|
22
|
-
registerBigBlocksExamplesTool(server);
|
|
23
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BigBlocks API Client wrapper for MCP tools
|
|
3
|
-
* Leverages the centralized API client from BigBlocks v0.0.13
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Note: In production, this would import from 'bigblocks/src/components/social'
|
|
7
|
-
// For now, we'll maintain our custom implementation but with BigBlocks types
|
|
8
|
-
import type {
|
|
9
|
-
ApiResponse,
|
|
10
|
-
BapIdentity,
|
|
11
|
-
LikeInfo,
|
|
12
|
-
LikesResponse,
|
|
13
|
-
PostMeta,
|
|
14
|
-
PostResponse,
|
|
15
|
-
PostsParams,
|
|
16
|
-
PostsResponse,
|
|
17
|
-
PostTransaction,
|
|
18
|
-
SearchParams,
|
|
19
|
-
} from "bmap-api-types";
|
|
20
|
-
import { BMAP_URL } from "../constants";
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Enhanced API client following BigBlocks v0.0.13 patterns
|
|
24
|
-
*/
|
|
25
|
-
export const bmapApiClient = {
|
|
26
|
-
posts: {
|
|
27
|
-
async search(params: SearchParams) {
|
|
28
|
-
const queryParams = new URLSearchParams();
|
|
29
|
-
queryParams.append("q", params.q);
|
|
30
|
-
queryParams.append("limit", params.limit.toString());
|
|
31
|
-
queryParams.append("offset", params.offset.toString());
|
|
32
|
-
|
|
33
|
-
const response = await fetch(`${BMAP_URL}/posts/search?${queryParams}`);
|
|
34
|
-
if (!response.ok) throw new Error(`Search failed: ${response.status}`);
|
|
35
|
-
return response.json();
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
async byBapId(params: PostsParams & { bapId: string }) {
|
|
39
|
-
const queryParams = new URLSearchParams();
|
|
40
|
-
queryParams.append("bapId", params.bapId);
|
|
41
|
-
if (params.limit) queryParams.append("limit", params.limit.toString());
|
|
42
|
-
if (params.page) queryParams.append("page", params.page.toString());
|
|
43
|
-
|
|
44
|
-
const response = await fetch(`${BMAP_URL}/posts?${queryParams}`);
|
|
45
|
-
if (!response.ok)
|
|
46
|
-
throw new Error(`Posts by BAP ID failed: ${response.status}`);
|
|
47
|
-
return response.json() as Promise<ApiResponse<PostsResponse>>;
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
async byAddress(params: PostsParams & { address: string }) {
|
|
51
|
-
const queryParams = new URLSearchParams();
|
|
52
|
-
queryParams.append("address", params.address);
|
|
53
|
-
if (params.limit) queryParams.append("limit", params.limit.toString());
|
|
54
|
-
if (params.page) queryParams.append("page", params.page.toString());
|
|
55
|
-
|
|
56
|
-
const response = await fetch(`${BMAP_URL}/posts?${queryParams}`);
|
|
57
|
-
if (!response.ok)
|
|
58
|
-
throw new Error(`Posts by address failed: ${response.status}`);
|
|
59
|
-
return response.json() as Promise<ApiResponse<PostsResponse>>;
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
async single(txid: string) {
|
|
63
|
-
const response = await fetch(`${BMAP_URL}/post/${txid}`);
|
|
64
|
-
if (!response.ok)
|
|
65
|
-
throw new Error(`Single post failed: ${response.status}`);
|
|
66
|
-
return response.json() as Promise<ApiResponse<PostResponse>>;
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
async replies(txid: string, page = 1, limit = 20) {
|
|
70
|
-
const queryParams = new URLSearchParams();
|
|
71
|
-
queryParams.append("page", page.toString());
|
|
72
|
-
queryParams.append("limit", limit.toString());
|
|
73
|
-
|
|
74
|
-
const response = await fetch(
|
|
75
|
-
`${BMAP_URL}/post/${txid}/replies?${queryParams}`,
|
|
76
|
-
);
|
|
77
|
-
if (!response.ok) throw new Error(`Replies failed: ${response.status}`);
|
|
78
|
-
return response.json();
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
async trending(
|
|
82
|
-
timeframe: "hour" | "day" | "week" | "month" = "day",
|
|
83
|
-
limit = 20,
|
|
84
|
-
) {
|
|
85
|
-
const queryParams = new URLSearchParams();
|
|
86
|
-
queryParams.append("timeframe", timeframe);
|
|
87
|
-
queryParams.append("limit", limit.toString());
|
|
88
|
-
|
|
89
|
-
const response = await fetch(`${BMAP_URL}/posts/trending?${queryParams}`);
|
|
90
|
-
if (!response.ok)
|
|
91
|
-
throw new Error(`Trending posts failed: ${response.status}`);
|
|
92
|
-
return response.json();
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
likes: {
|
|
97
|
-
async forPost(txid: string): Promise<LikeInfo> {
|
|
98
|
-
const response = await fetch(`${BMAP_URL}/likes/${txid}`);
|
|
99
|
-
if (!response.ok)
|
|
100
|
-
throw new Error(`Likes for post failed: ${response.status}`);
|
|
101
|
-
return response.json() as Promise<LikeInfo>;
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
async byUser(bapId: string, page = 1, limit = 20): Promise<LikesResponse> {
|
|
105
|
-
const queryParams = new URLSearchParams();
|
|
106
|
-
queryParams.append("page", page.toString());
|
|
107
|
-
queryParams.append("limit", limit.toString());
|
|
108
|
-
|
|
109
|
-
const response = await fetch(
|
|
110
|
-
`${BMAP_URL}/users/${bapId}/likes?${queryParams}`,
|
|
111
|
-
);
|
|
112
|
-
if (!response.ok)
|
|
113
|
-
throw new Error(`User likes failed: ${response.status}`);
|
|
114
|
-
return response.json() as Promise<LikesResponse>;
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
follows: {
|
|
119
|
-
async getFollowers(bapId: string, page = 1, limit = 20) {
|
|
120
|
-
const queryParams = new URLSearchParams();
|
|
121
|
-
queryParams.append("page", page.toString());
|
|
122
|
-
queryParams.append("limit", limit.toString());
|
|
123
|
-
|
|
124
|
-
const response = await fetch(
|
|
125
|
-
`${BMAP_URL}/users/${bapId}/followers?${queryParams}`,
|
|
126
|
-
);
|
|
127
|
-
if (!response.ok)
|
|
128
|
-
throw new Error(`Get followers failed: ${response.status}`);
|
|
129
|
-
return response.json();
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
async getFollowing(bapId: string, page = 1, limit = 20) {
|
|
133
|
-
const queryParams = new URLSearchParams();
|
|
134
|
-
queryParams.append("page", page.toString());
|
|
135
|
-
queryParams.append("limit", limit.toString());
|
|
136
|
-
|
|
137
|
-
const response = await fetch(
|
|
138
|
-
`${BMAP_URL}/users/${bapId}/following?${queryParams}`,
|
|
139
|
-
);
|
|
140
|
-
if (!response.ok)
|
|
141
|
-
throw new Error(`Get following failed: ${response.status}`);
|
|
142
|
-
return response.json();
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
identity: {
|
|
147
|
-
async search(query: string, limit = 10) {
|
|
148
|
-
const queryParams = new URLSearchParams();
|
|
149
|
-
queryParams.append("q", query);
|
|
150
|
-
queryParams.append("limit", limit.toString());
|
|
151
|
-
|
|
152
|
-
const response = await fetch(
|
|
153
|
-
`${BMAP_URL}/identity/search?${queryParams}`,
|
|
154
|
-
);
|
|
155
|
-
if (!response.ok)
|
|
156
|
-
throw new Error(`Identity search failed: ${response.status}`);
|
|
157
|
-
return response.json();
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
async byBapId(bapId: string) {
|
|
161
|
-
const response = await fetch(`${BMAP_URL}/identity/${bapId}`);
|
|
162
|
-
if (!response.ok)
|
|
163
|
-
throw new Error(`Identity by BAP ID failed: ${response.status}`);
|
|
164
|
-
return response.json();
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Error handling wrapper that follows BigBlocks patterns
|
|
171
|
-
*/
|
|
172
|
-
export class BmapApiError extends Error {
|
|
173
|
-
constructor(
|
|
174
|
-
public code: string,
|
|
175
|
-
message: string,
|
|
176
|
-
public details?: Record<string, unknown>,
|
|
177
|
-
) {
|
|
178
|
-
super(message);
|
|
179
|
-
this.name = "BmapApiError";
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
static fromError(error: unknown, code = "UNKNOWN_ERROR"): BmapApiError {
|
|
183
|
-
if (error instanceof BmapApiError) return error;
|
|
184
|
-
if (error instanceof Error) {
|
|
185
|
-
return new BmapApiError(code, error.message, { originalError: error });
|
|
186
|
-
}
|
|
187
|
-
return new BmapApiError(code, String(error));
|
|
188
|
-
}
|
|
189
|
-
}
|