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.
Files changed (52) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/index.js +87272 -70728
  3. package/index.ts +409 -22
  4. package/package.json +28 -24
  5. package/tools/a2b/discover.ts +13 -13
  6. package/tools/bap/friend.ts +2 -3
  7. package/tools/bap/generate.ts +7 -9
  8. package/tools/bap/getCurrentAddress.ts +1 -8
  9. package/tools/bap/getId.ts +3 -3
  10. package/tools/bsocial/bmapFollow.ts +3 -7
  11. package/tools/bsocial/bmapLikes.ts +3 -3
  12. package/tools/bsocial/bmapReadPosts.ts +3 -3
  13. package/tools/bsocial/createPost.ts +3 -3
  14. package/tools/bsocial/readPosts.ts +3 -3
  15. package/tools/bsv/decodeTransaction.ts +2 -5
  16. package/tools/bsv/explore.ts +2 -3
  17. package/tools/bsv/getPrice.ts +1 -9
  18. package/tools/bsv/token.ts +14 -26
  19. package/tools/index.ts +0 -13
  20. package/tools/mnee/getBalance.ts +2 -4
  21. package/tools/mnee/parseTx.ts +3 -3
  22. package/tools/mnee/sendMnee.ts +5 -5
  23. package/tools/ordinals/getInscription.ts +2 -3
  24. package/tools/ordinals/getTokenByIdOrTicker.ts +6 -3
  25. package/tools/ordinals/marketListings.ts +2 -18
  26. package/tools/ordinals/marketSales.ts +2 -4
  27. package/tools/ordinals/searchInscriptions.ts +2 -4
  28. package/tools/utils/index.ts +14 -16
  29. package/tools/wallet/a2bPublishAgent.ts +18 -27
  30. package/tools/wallet/a2bPublishMcp.ts +17 -22
  31. package/tools/wallet/createOrdinals.ts +11 -20
  32. package/tools/wallet/fetchPaymentUtxos.ts +9 -1
  33. package/tools/wallet/gatherCollectionInfo.ts +9 -13
  34. package/tools/wallet/getAddress.ts +1 -9
  35. package/tools/wallet/getBalance.ts +2 -14
  36. package/tools/wallet/getBalanceDroplet.ts +2 -13
  37. package/tools/wallet/getPublicKey.ts +3 -16
  38. package/tools/wallet/mintCollection.ts +17 -22
  39. package/tools/wallet/purchaseListing.ts +19 -29
  40. package/tools/wallet/refreshUtxos.ts +2 -14
  41. package/tools/wallet/sendOrdinals.ts +11 -20
  42. package/tools/wallet/sendToAddress.ts +2 -22
  43. package/tools/wallet/setupDroplet.ts +7 -18
  44. package/tools/wallet/tools.ts +10 -80
  45. package/tools/wallet/transferOrdToken.ts +12 -20
  46. package/vite.config.ts +15 -0
  47. package/tools/bigblocks/components.ts +0 -304
  48. package/tools/bigblocks/docs.ts +0 -488
  49. package/tools/bigblocks/examples.ts +0 -527
  50. package/tools/bigblocks/generator.ts +0 -485
  51. package/tools/bigblocks/index.ts +0 -23
  52. package/tools/bsocial/bigblocksApiClient.ts +0 -189
@@ -1,527 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { z } from "zod";
3
-
4
- const EXAMPLES = {
5
- "next-auth": {
6
- title: "Next.js Authentication Setup",
7
- description: "Complete BigBlocks authentication integration for Next.js",
8
- tags: ["nextjs", "authentication", "setup"],
9
- files: {
10
- "app/providers.tsx": `'use client';
11
-
12
- import { BitcoinAuthProvider, BitcoinThemeProvider, BitcoinQueryProvider } from 'bigblocks';
13
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
14
- import { Theme } from '@radix-ui/themes';
15
- import '@radix-ui/themes/styles.css';
16
-
17
- const queryClient = new QueryClient();
18
-
19
- export function Providers({ children }: { children: React.ReactNode }) {
20
- return (
21
- <QueryClientProvider client={queryClient}>
22
- <Theme appearance="dark" accentColor="amber">
23
- <BitcoinThemeProvider>
24
- <BitcoinQueryProvider>
25
- <BitcoinAuthProvider config={{
26
- apiUrl: '/api/auth',
27
- storageNamespace: 'my-app',
28
- oauthProviders: ['google', 'github']
29
- }}>
30
- {children}
31
- </BitcoinAuthProvider>
32
- </BitcoinQueryProvider>
33
- </BitcoinThemeProvider>
34
- </Theme>
35
- </QueryClientProvider>
36
- );
37
- }`,
38
- "app/layout.tsx": `import { Providers } from './providers';
39
-
40
- export default function RootLayout({
41
- children,
42
- }: {
43
- children: React.ReactNode;
44
- }) {
45
- return (
46
- <html lang="en">
47
- <body>
48
- <Providers>
49
- {children}
50
- </Providers>
51
- </body>
52
- </html>
53
- );
54
- }`,
55
- "app/auth/page.tsx": `import { AuthFlowOrchestrator } from 'bigblocks';
56
-
57
- export default function AuthPage() {
58
- return (
59
- <div className="min-h-screen flex items-center justify-center">
60
- <AuthFlowOrchestrator
61
- flowType="unified"
62
- enableOAuth={true}
63
- onSuccess={() => {
64
- window.location.href = '/dashboard';
65
- }}
66
- />
67
- </div>
68
- );
69
- }`,
70
- },
71
- },
72
- "social-app": {
73
- title: "Social Media App",
74
- description: "Twitter-like social app using BigBlocks social components",
75
- tags: ["social", "posts", "feed"],
76
- files: {
77
- "components/SocialApp.tsx": `import {
78
- SocialFeed,
79
- PostButton,
80
- LikeButton,
81
- FollowButton,
82
- ProfileCard
83
- } from 'bigblocks';
84
- import { useState, useEffect } from 'react';
85
-
86
- export function SocialApp() {
87
- const [posts, setPosts] = useState([]);
88
- const [user, setUser] = useState(null);
89
-
90
- const handleNewPost = (txid: string) => {
91
- // Post created successfully
92
- loadPosts();
93
- };
94
-
95
- const loadPosts = async () => {
96
- try {
97
- const response = await fetch('/api/posts');
98
- const data = await response.json();
99
- setPosts(data.posts || []);
100
- } catch (error) {
101
- console.error('Failed to load posts:', error);
102
- }
103
- };
104
-
105
- useEffect(() => {
106
- loadPosts();
107
- }, []);
108
-
109
- return (
110
- <div className="max-w-4xl mx-auto">
111
- <div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
112
- {/* Profile Sidebar */}
113
- <div className="lg:col-span-1">
114
- <ProfileCard
115
- profile={user}
116
- showActions={false}
117
- editable={false}
118
- />
119
- </div>
120
-
121
- {/* Main Feed */}
122
- <div className="lg:col-span-3">
123
- {/* Post Creation */}
124
- <div className="mb-6 p-4 border rounded-lg">
125
- <PostButton
126
- onSuccess={handleNewPost}
127
- placeholder="What's happening?"
128
- encryption={false}
129
- />
130
- </div>
131
-
132
- {/* Social Feed */}
133
- <SocialFeed
134
- posts={posts}
135
- showActions={true}
136
- onLoadMore={loadPosts}
137
- />
138
- </div>
139
- </div>
140
- </div>
141
- );
142
- }`,
143
- "pages/api/posts.ts": `import type { NextApiRequest, NextApiResponse } from 'next';
144
-
145
- export default async function handler(
146
- req: NextApiRequest,
147
- res: NextApiResponse
148
- ) {
149
- if (req.method === 'GET') {
150
- // Fetch posts from BMAP API or your database
151
- const posts = await fetchPosts();
152
- res.status(200).json({ posts });
153
- } else {
154
- res.setHeader('Allow', ['GET']);
155
- res.status(405).end('Method not allowed');
156
- }
157
- }
158
-
159
- async function fetchPosts() {
160
- // Implementation to fetch posts from BMAP or database
161
- return [];
162
- }`,
163
- },
164
- },
165
- "wallet-dashboard": {
166
- title: "Wallet Dashboard",
167
- description: "Complete Bitcoin wallet interface with all features",
168
- tags: ["wallet", "payments", "dashboard"],
169
- files: {
170
- "components/WalletDashboard.tsx": `import {
171
- WalletOverview,
172
- SendBSVButton,
173
- TokenBalance,
174
- QuickSendButton,
175
- useBitcoinAuth,
176
- useBitcoinWallet
177
- } from 'bigblocks';
178
- import { useState } from 'react';
179
-
180
- export function WalletDashboard() {
181
- const { user, isAuthenticated } = useBitcoinAuth();
182
- const { balance, transactions, refreshBalance } = useBitcoinWallet();
183
- const [selectedAmount, setSelectedAmount] = useState(0.001);
184
-
185
- const handleSendSuccess = (txid: string) => {
186
- console.log('Payment sent:', txid);
187
- refreshBalance();
188
- };
189
-
190
- if (!isAuthenticated) {
191
- return <div>Please sign in to access your wallet.</div>;
192
- }
193
-
194
- return (
195
- <div className="max-w-6xl mx-auto p-6">
196
- <h1 className="text-3xl font-bold mb-8">Wallet Dashboard</h1>
197
-
198
- {/* Balance Overview */}
199
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
200
- <div className="md:col-span-2">
201
- <WalletOverview
202
- showHistory={true}
203
- showTokens={true}
204
- />
205
- </div>
206
-
207
- <div>
208
- <TokenBalance
209
- showUSD={true}
210
- refreshInterval={30000}
211
- />
212
- </div>
213
- </div>
214
-
215
- {/* Actions */}
216
- <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
217
- <div className="space-y-4">
218
- <h2 className="text-xl font-semibold">Send Bitcoin</h2>
219
-
220
- <SendBSVButton
221
- amount={selectedAmount}
222
- onSuccess={handleSendSuccess}
223
- confirmRequired={true}
224
- />
225
-
226
- <QuickSendButton
227
- presetAmounts={[0.001, 0.01, 0.1, 1]}
228
- onSend={handleSendSuccess}
229
- />
230
- </div>
231
-
232
- <div className="space-y-4">
233
- <h2 className="text-xl font-semibold">Recent Transactions</h2>
234
- <div className="space-y-2">
235
- {transactions?.slice(0, 5).map((tx, index) => (
236
- <div key={index} className="p-3 border rounded">
237
- <div className="flex justify-between">
238
- <span className="font-mono text-sm">{tx.txid?.slice(0, 16)}...</span>
239
- <span className={tx.amount > 0 ? 'text-green-600' : 'text-red-600'}>
240
- {tx.amount > 0 ? '+' : ''}{tx.amount} BSV
241
- </span>
242
- </div>
243
- </div>
244
- ))}
245
- </div>
246
- </div>
247
- </div>
248
- </div>
249
- );
250
- }`,
251
- },
252
- },
253
- marketplace: {
254
- title: "NFT Marketplace",
255
- description: "Complete marketplace with buying, selling, and browsing",
256
- tags: ["marketplace", "nft", "trading"],
257
- files: {
258
- "components/Marketplace.tsx": `import {
259
- MarketTable,
260
- CreateListingButton,
261
- BuyListingButton,
262
- useMarketplace
263
- } from 'bigblocks';
264
- import { useState, useEffect } from 'react';
265
-
266
- export function Marketplace() {
267
- const { listings, createListing, buyListing } = useMarketplace();
268
- const [selectedAsset, setSelectedAsset] = useState(null);
269
- const [showCreateForm, setShowCreateForm] = useState(false);
270
-
271
- const handleCreateListing = async (data: any) => {
272
- try {
273
- const txid = await createListing(data);
274
- console.log('Listing created:', txid);
275
- setShowCreateForm(false);
276
- } catch (error) {
277
- console.error('Failed to create listing:', error);
278
- }
279
- };
280
-
281
- const handleBuyListing = async (listing: any) => {
282
- try {
283
- const txid = await buyListing(listing);
284
- console.log('Purchase successful:', txid);
285
- } catch (error) {
286
- console.error('Purchase failed:', error);
287
- }
288
- };
289
-
290
- return (
291
- <div className="max-w-7xl mx-auto p-6">
292
- <div className="flex justify-between items-center mb-8">
293
- <h1 className="text-3xl font-bold">NFT Marketplace</h1>
294
-
295
- <CreateListingButton
296
- onList={handleCreateListing}
297
- asset={selectedAsset}
298
- />
299
- </div>
300
-
301
- {/* Marketplace Table */}
302
- <MarketTable
303
- listings={listings}
304
- onSelect={setSelectedAsset}
305
- sortBy="price"
306
- showActions={true}
307
- customActions={(listing) => (
308
- <BuyListingButton
309
- listing={listing}
310
- onBuy={() => handleBuyListing(listing)}
311
- confirmRequired={true}
312
- />
313
- )}
314
- />
315
- </div>
316
- );
317
- }`,
318
- },
319
- },
320
- };
321
-
322
- const examplesSchema = z.object({
323
- example: z
324
- .string()
325
- .optional()
326
- .describe(
327
- "Specific example to view (next-auth, social-app, wallet-dashboard, marketplace)",
328
- ),
329
- tag: z
330
- .string()
331
- .optional()
332
- .describe(
333
- "Filter examples by tag (nextjs, authentication, social, wallet, marketplace, nft)",
334
- ),
335
- file: z.string().optional().describe("View specific file from an example"),
336
- listAll: z.boolean().optional().describe("List all available examples"),
337
- });
338
-
339
- /**
340
- * Register the BigBlocks examples tool
341
- */
342
- export function registerBigBlocksExamplesTool(server: McpServer): void {
343
- server.tool(
344
- "bigblocks_examples",
345
- "Browse real-world BigBlocks integration examples and patterns. See complete applications built with BigBlocks components.\n\n" +
346
- "Available examples:\n" +
347
- "- next-auth: Next.js authentication setup\n" +
348
- "- social-app: Twitter-like social media app\n" +
349
- "- wallet-dashboard: Complete wallet interface\n" +
350
- "- marketplace: NFT marketplace with trading\n\n" +
351
- "Usage examples:\n" +
352
- '- View example: {"example": "next-auth"}\n' +
353
- '- Filter by tag: {"tag": "authentication"}\n' +
354
- '- View specific file: {"example": "social-app", "file": "components/SocialApp.tsx"}\n' +
355
- '- List all: {"listAll": true}',
356
- { args: examplesSchema },
357
- async ({ args }) => {
358
- try {
359
- const { example, tag, file, listAll } = args;
360
-
361
- // List all examples
362
- if (listAll) {
363
- let result = "# BigBlocks Integration Examples\n\n";
364
-
365
- for (const [name, data] of Object.entries(EXAMPLES)) {
366
- result += `## ${data.title}\n`;
367
- result += `**ID:** ${name}\n`;
368
- result += `**Description:** ${data.description}\n`;
369
- result += `**Tags:** ${data.tags.join(", ")}\n`;
370
- result += `**Files:** ${Object.keys(data.files).length} files\n\n`;
371
- }
372
-
373
- result += 'Use {"example": "example-id"} to view a complete example.';
374
- return { content: [{ type: "text", text: result }] };
375
- }
376
-
377
- // Filter by tag
378
- if (tag && !example) {
379
- const filtered = Object.entries(EXAMPLES).filter(([_, data]) =>
380
- data.tags.includes(tag.toLowerCase()),
381
- );
382
-
383
- if (filtered.length === 0) {
384
- const allTags = Array.from(
385
- new Set(Object.values(EXAMPLES).flatMap((e) => e.tags)),
386
- ).join(", ");
387
- return {
388
- content: [
389
- {
390
- type: "text",
391
- text: `No examples found with tag "${tag}". Available tags: ${allTags}`,
392
- },
393
- ],
394
- isError: true,
395
- };
396
- }
397
-
398
- let result = `# BigBlocks Examples: ${tag}\n\n`;
399
- for (const [name, data] of filtered) {
400
- result += `## ${data.title}\n`;
401
- result += `**ID:** ${name}\n`;
402
- result += `${data.description}\n\n`;
403
- }
404
-
405
- return { content: [{ type: "text", text: result }] };
406
- }
407
-
408
- // View specific example
409
- if (example) {
410
- const exampleData = EXAMPLES[example];
411
- if (!exampleData) {
412
- const available = Object.keys(EXAMPLES).join(", ");
413
- return {
414
- content: [
415
- {
416
- type: "text",
417
- text: `Example "${example}" not found. Available examples: ${available}`,
418
- },
419
- ],
420
- isError: true,
421
- };
422
- }
423
-
424
- // View specific file
425
- if (file) {
426
- const fileContent = exampleData.files[file];
427
- if (!fileContent) {
428
- const availableFiles = Object.keys(exampleData.files).join(", ");
429
- return {
430
- content: [
431
- {
432
- type: "text",
433
- text: `File "${file}" not found in example "${example}". Available files: ${availableFiles}`,
434
- },
435
- ],
436
- isError: true,
437
- };
438
- }
439
-
440
- let result = `# ${exampleData.title} - ${file}\n\n`;
441
- result += "```tsx\n";
442
- result += fileContent;
443
- result += "\n```";
444
-
445
- return { content: [{ type: "text", text: result }] };
446
- }
447
-
448
- // View complete example
449
- let result = `# ${exampleData.title}\n\n`;
450
- result += `${exampleData.description}\n\n`;
451
- result += `**Tags:** ${exampleData.tags.join(", ")}\n\n`;
452
-
453
- // Show all files
454
- for (const [fileName, fileContent] of Object.entries(
455
- exampleData.files,
456
- )) {
457
- result += `## ${fileName}\n\n`;
458
- result += "```tsx\n";
459
- result += fileContent;
460
- result += "\n```\n\n";
461
- }
462
-
463
- // Add setup instructions
464
- result += "## Setup Instructions\n\n";
465
- if (example === "next-auth") {
466
- result +=
467
- "1. Install dependencies: `npm install bigblocks @tanstack/react-query @radix-ui/themes`\n";
468
- result += "2. Add the providers to your app\n";
469
- result += "3. Create authentication pages\n";
470
- result += "4. Configure your API routes\n";
471
- } else if (example === "social-app") {
472
- result += "1. Set up authentication first\n";
473
- result += "2. Implement posts API endpoint\n";
474
- result += "3. Configure BMAP integration\n";
475
- result += "4. Style components as needed\n";
476
- } else if (example === "wallet-dashboard") {
477
- result += "1. Ensure authentication is working\n";
478
- result += "2. Configure wallet provider\n";
479
- result += "3. Set up transaction monitoring\n";
480
- result += "4. Add error handling\n";
481
- } else if (example === "marketplace") {
482
- result += "1. Set up wallet functionality\n";
483
- result += "2. Configure marketplace API\n";
484
- result += "3. Implement asset management\n";
485
- result += "4. Add payment processing\n";
486
- }
487
-
488
- return { content: [{ type: "text", text: result }] };
489
- }
490
-
491
- // Default: show overview
492
- return {
493
- content: [
494
- {
495
- type: "text",
496
- text: `# BigBlocks Integration Examples
497
-
498
- Browse complete application examples built with BigBlocks:
499
-
500
- ${Object.entries(EXAMPLES)
501
- .map(([name, data]) => `- **${data.title}** (${name}): ${data.description}`)
502
- .join("\n")}
503
-
504
- **Usage:**
505
- - View example: {"example": "example-id"}
506
- - Filter by tag: {"tag": "authentication"}
507
- - View specific file: {"example": "social-app", "file": "components/SocialApp.tsx"}
508
- - List all examples: {"listAll": true}
509
-
510
- These examples show complete, production-ready patterns for building Bitcoin applications with BigBlocks.`,
511
- },
512
- ],
513
- };
514
- } catch (error) {
515
- return {
516
- content: [
517
- {
518
- type: "text",
519
- text: `Error: ${error instanceof Error ? error.message : String(error)}`,
520
- },
521
- ],
522
- isError: true,
523
- };
524
- }
525
- },
526
- );
527
- }