bsv-mcp 0.2.14 → 0.3.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +90 -10
  2. package/README.md +13 -13
  3. package/dist/app.html +483 -106
  4. package/dist/index.js +265787 -155292
  5. package/index.ts +505 -70
  6. package/package.json +24 -15
  7. package/prompts/bsvSdk/auth.ts +1 -1
  8. package/prompts/bsvSdk/cryptography.ts +1 -1
  9. package/prompts/bsvSdk/overview.ts +1 -1
  10. package/prompts/bsvSdk/primitives.ts +1 -1
  11. package/prompts/bsvSdk/script.ts +1 -1
  12. package/prompts/bsvSdk/transaction.ts +1 -1
  13. package/prompts/bsvSdk/wallet.ts +1 -1
  14. package/prompts/ordinals.ts +1 -1
  15. package/test-mcp-server.ts +26 -4
  16. package/tools/a2b/discover.ts +2 -2
  17. package/tools/bap/friend.ts +17 -24
  18. package/tools/bap/generate.test.ts +34 -32
  19. package/tools/bap/generate.ts +48 -43
  20. package/tools/bap/getCurrentAddress.ts +1 -3
  21. package/tools/bap/getId.test.ts +18 -10
  22. package/tools/bap/getId.ts +8 -6
  23. package/tools/bap/utils.ts +1 -1
  24. package/tools/bsocial/bmapReadPosts.ts +16 -2
  25. package/tools/bsocial/createPost.ts +21 -10
  26. package/tools/bsocial/readPosts.ts +10 -4
  27. package/tools/bsv/decodeTransaction.ts +1 -1
  28. package/tools/bsv/explore.ts +0 -4
  29. package/tools/bsv/getPrice.ts +1 -1
  30. package/tools/bsv/token.ts +14 -6
  31. package/tools/constants.ts +6 -2
  32. package/tools/index.ts +10 -10
  33. package/tools/mnee/getBalance.ts +1 -1
  34. package/tools/mnee/parseTx.ts +1 -1
  35. package/tools/mnee/sendMnee.ts +30 -8
  36. package/tools/ordinals/getInscription.ts +1 -3
  37. package/tools/ordinals/getTokenByIdOrTicker.ts +1 -3
  38. package/tools/ordinals/index.ts +4 -1
  39. package/tools/ordinals/marketListings.ts +1 -1
  40. package/tools/ordinals/marketSales.ts +1 -1
  41. package/tools/ordinals/searchInscriptions.ts +1 -1
  42. package/tools/utils/aip.ts +31 -22
  43. package/tools/utils/installAgentMaster.ts +8 -9
  44. package/tools/utils/toolRegistration.ts +21 -22
  45. package/tools/utils/transactionBuilder.ts +21 -14
  46. package/tools/wallet/a2bPublishMcp.ts +15 -5
  47. package/tools/wallet/brc100.ts +541 -310
  48. package/tools/wallet/cancelListing.ts +29 -37
  49. package/tools/wallet/createOrdinals.ts +43 -27
  50. package/tools/wallet/fetchPaymentUtxos.ts +7 -5
  51. package/tools/wallet/gatherCollectionInfo.ts +3 -5
  52. package/tools/wallet/getAddress.ts +1 -4
  53. package/tools/wallet/getBalance.ts +15 -15
  54. package/tools/wallet/{getBalanceDroplet.ts → getBalanceDroplit.ts} +6 -6
  55. package/tools/wallet/getBsv21Balances.ts +20 -14
  56. package/tools/wallet/getLockData.ts +11 -11
  57. package/tools/wallet/getOrdinals.ts +26 -20
  58. package/tools/wallet/integratedWallet.ts +55 -53
  59. package/tools/wallet/listOrdinal.ts +40 -39
  60. package/tools/wallet/listTokens.ts +18 -17
  61. package/tools/wallet/lockBsv.ts +36 -22
  62. package/tools/wallet/mintCollection.ts +15 -10
  63. package/tools/wallet/opnsDeregister.ts +29 -39
  64. package/tools/wallet/opnsRegister.ts +29 -39
  65. package/tools/wallet/purchaseListing.test.ts +27 -0
  66. package/tools/wallet/purchaseListing.ts +59 -40
  67. package/tools/wallet/refreshUtxos.ts +1 -1
  68. package/tools/wallet/schemas.ts +0 -13
  69. package/tools/wallet/sendAllBsv.ts +26 -20
  70. package/tools/wallet/sendBsv.ts +107 -0
  71. package/tools/wallet/setupDroplit.ts +157 -0
  72. package/tools/wallet/signBsm.ts +18 -18
  73. package/tools/wallet/sweepBsv.ts +48 -27
  74. package/tools/wallet/sweepBsv21.ts +42 -28
  75. package/tools/wallet/sweepOrdinals.ts +38 -26
  76. package/tools/wallet/tools.ts +11 -13
  77. package/tools/wallet/transactionHelper.ts +13 -5
  78. package/tools/wallet/transferOrdToken.ts +72 -84
  79. package/tools/wallet/unlockBsv.ts +23 -17
  80. package/tools/wallet/utxo.ts +1 -0
  81. package/tools/wallet/wallet.ts +1 -13
  82. package/tools/wallet/sendToAddress.ts +0 -74
  83. package/tools/wallet/setupDroplet.ts +0 -161
@@ -1,31 +1,21 @@
1
- import type { OneSatContext } from '@1sat/actions'
2
- import { sendBsv21, transferOrdinals } from '@1sat/actions'
3
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
4
- import { z } from 'zod'
5
-
6
- const walletOutputSchema = z.object({
7
- outpoint: z.string(),
8
- satoshis: z.number().optional(),
9
- tags: z.array(z.string()).optional(),
10
- customInstructions: z.string().optional(),
11
- lockingScript: z.string().optional(),
12
- })
1
+ import type { OneSatContext } from "@1sat/actions";
2
+ import { sendBsv21, sendOrdinals } from "@1sat/actions";
3
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { z } from "zod";
5
+ import { assertBroadcastAllowed } from "../../utils/broadcastGuard";
13
6
 
14
7
  export const transferOrdTokenArgsSchema = z.object({
15
- type: z.enum(['ordinal', 'bsv21']).describe(
16
- "'ordinal' to transfer an inscription/NFT, 'bsv21' to send fungible BSV21 tokens",
17
- ),
18
- // ordinal fields
19
- ordinal: walletOutputSchema
20
- .optional()
8
+ type: z
9
+ .enum(["ordinal", "bsv21"])
21
10
  .describe(
22
- "WalletOutput of the ordinal to transfer (from wallet_getOrdinals). Required when type='ordinal'",
11
+ "'ordinal' to transfer an inscription/NFT, 'bsv21' to send fungible BSV21 tokens",
23
12
  ),
24
- inputBEEF: z
25
- .array(z.number())
13
+ // ordinal fields
14
+ id: z
15
+ .string()
26
16
  .optional()
27
17
  .describe(
28
- "BEEF bytes from listOutputs (include: 'entire transactions'). Required when type='ordinal'",
18
+ "Tracking id of the ordinal in the ordinals basket (the 'id:' tag from wallet_getOrdinals). Required when type='ordinal'",
29
19
  ),
30
20
  // bsv21 fields
31
21
  tokenId: z
@@ -35,130 +25,128 @@ export const transferOrdTokenArgsSchema = z.object({
35
25
  amount: z
36
26
  .string()
37
27
  .optional()
38
- .describe("Amount of tokens to send as a string integer. Required when type='bsv21'"),
28
+ .describe(
29
+ "Amount of tokens to send as a string integer. Required when type='bsv21'",
30
+ ),
39
31
  // shared destination fields
40
- address: z.string().optional().describe('Recipient P2PKH address'),
32
+ address: z.string().optional().describe("Recipient P2PKH address"),
41
33
  counterparty: z
42
34
  .string()
43
35
  .optional()
44
- .describe('Recipient identity public key (hex)'),
45
- })
36
+ .describe("Recipient identity public key (hex)"),
37
+ });
46
38
 
47
- export type TransferOrdTokenArgs = z.infer<typeof transferOrdTokenArgsSchema>
39
+ export type TransferOrdTokenArgs = z.infer<typeof transferOrdTokenArgsSchema>;
48
40
 
49
41
  export function registerTransferOrdTokenTool(
50
42
  server: McpServer,
51
43
  ctx: OneSatContext | undefined,
52
44
  ) {
53
45
  server.tool(
54
- 'wallet_transferOrdToken',
55
- "Transfer an ordinal inscription or send BSV21 fungible tokens. Use type='ordinal' to transfer an NFT/inscription (requires the WalletOutput from wallet_getOrdinals and the BEEF). Use type='bsv21' to send fungible tokens by token ID and amount.",
46
+ "wallet_transferOrdToken",
47
+ "Transfer an ordinal inscription or send BSV21 fungible tokens. Use type='ordinal' to transfer an NFT/inscription by its ordinals-basket tracking id (from wallet_getOrdinals). Use type='bsv21' to send fungible tokens by token ID and amount.",
56
48
  { ...transferOrdTokenArgsSchema.shape },
57
- async ({ type, ordinal, inputBEEF, tokenId, amount, address, counterparty }) => {
49
+ async ({ type, id, tokenId, amount, address, counterparty }) => {
58
50
  if (!ctx) {
59
51
  return {
60
52
  content: [
61
53
  {
62
- type: 'text',
63
- text: 'Wallet not initialized. Please configure a wallet before transferring.',
54
+ type: "text",
55
+ text: "Wallet not initialized. Please configure a wallet before transferring.",
64
56
  },
65
57
  ],
66
58
  isError: true,
67
- }
59
+ };
68
60
  }
69
61
 
70
62
  try {
71
- if (type === 'ordinal') {
72
- if (!ordinal) {
73
- return {
74
- content: [{ type: 'text', text: "ordinal is required when type='ordinal'" }],
75
- isError: true,
76
- }
77
- }
78
- if (!inputBEEF) {
79
- return {
80
- content: [{ type: 'text', text: "inputBEEF is required when type='ordinal'" }],
81
- isError: true,
82
- }
83
- }
84
- if (!address && !counterparty) {
63
+ assertBroadcastAllowed("wallet_transferOrdToken");
64
+ if (!address && !counterparty) {
65
+ return {
66
+ content: [
67
+ { type: "text", text: "address or counterparty is required" },
68
+ ],
69
+ isError: true,
70
+ };
71
+ }
72
+
73
+ if (type === "ordinal") {
74
+ if (!id) {
85
75
  return {
86
- content: [{ type: 'text', text: 'address or counterparty is required' }],
76
+ content: [
77
+ {
78
+ type: "text",
79
+ text: "id is required when type='ordinal'",
80
+ },
81
+ ],
87
82
  isError: true,
88
- }
83
+ };
89
84
  }
90
85
 
91
- const result = await transferOrdinals.execute(ctx, {
92
- transfers: [
93
- {
94
- ordinal: ordinal as Parameters<typeof transferOrdinals.execute>[1]['transfers'][0]['ordinal'],
95
- address,
96
- counterparty,
97
- },
98
- ],
99
- inputBEEF,
100
- })
86
+ const result = await sendOrdinals.execute(ctx, {
87
+ transfers: [{ id, address, counterparty }],
88
+ });
101
89
 
102
90
  if (result.error) {
103
91
  return {
104
- content: [{ type: 'text', text: result.error }],
92
+ content: [{ type: "text", text: result.error }],
105
93
  isError: true,
106
- }
94
+ };
107
95
  }
108
96
 
109
97
  return {
110
- content: [{ type: 'text', text: JSON.stringify({ txid: result.txid }) }],
111
- }
98
+ content: [
99
+ { type: "text", text: JSON.stringify({ txid: result.txid }) },
100
+ ],
101
+ };
112
102
  }
113
103
 
114
104
  // bsv21
115
105
  if (!tokenId) {
116
106
  return {
117
- content: [{ type: 'text', text: "tokenId is required when type='bsv21'" }],
107
+ content: [
108
+ { type: "text", text: "tokenId is required when type='bsv21'" },
109
+ ],
118
110
  isError: true,
119
- }
111
+ };
120
112
  }
121
113
  if (!amount) {
122
114
  return {
123
- content: [{ type: 'text', text: "amount is required when type='bsv21'" }],
124
- isError: true,
125
- }
126
- }
127
- if (!address && !counterparty) {
128
- return {
129
- content: [{ type: 'text', text: 'address or counterparty is required' }],
115
+ content: [
116
+ { type: "text", text: "amount is required when type='bsv21'" },
117
+ ],
130
118
  isError: true,
131
- }
119
+ };
132
120
  }
133
121
 
134
122
  const result = await sendBsv21.execute(ctx, {
135
123
  tokenId,
136
- amount,
137
- address,
138
- counterparty,
139
- })
124
+ recipients: [{ amount, destination: { address, counterparty } }],
125
+ });
140
126
 
141
127
  if (result.error) {
142
128
  return {
143
- content: [{ type: 'text', text: result.error }],
129
+ content: [{ type: "text", text: result.error }],
144
130
  isError: true,
145
- }
131
+ };
146
132
  }
147
133
 
148
134
  return {
149
- content: [{ type: 'text', text: JSON.stringify({ txid: result.txid }) }],
150
- }
135
+ content: [
136
+ { type: "text", text: JSON.stringify({ txid: result.txid }) },
137
+ ],
138
+ };
151
139
  } catch (err: unknown) {
152
140
  return {
153
141
  content: [
154
142
  {
155
- type: 'text',
143
+ type: "text",
156
144
  text: err instanceof Error ? err.message : String(err),
157
145
  },
158
146
  ],
159
147
  isError: true,
160
- }
148
+ };
161
149
  }
162
150
  },
163
- )
151
+ );
164
152
  }
@@ -1,57 +1,63 @@
1
- import type { OneSatContext } from '@1sat/actions'
2
- import { unlockBsv } from '@1sat/actions'
3
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
1
+ import type { OneSatContext } from "@1sat/actions";
2
+ import { unlockBsv } from "@1sat/actions";
3
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { assertBroadcastAllowed } from "../../utils/broadcastGuard";
4
5
 
5
6
  export function registerUnlockBsvTool(
6
7
  server: McpServer,
7
8
  ctx: OneSatContext | undefined,
8
9
  ) {
9
10
  server.tool(
10
- 'wallet_unlockBsv',
11
- 'Unlock all matured time-locked BSV',
11
+ "wallet_unlockBsv",
12
+ "Unlock all matured time-locked BSV",
12
13
  {},
13
14
  async () => {
14
15
  if (!ctx) {
15
16
  return {
16
17
  content: [
17
18
  {
18
- type: 'text',
19
- text: 'Wallet not initialized. Please configure a wallet before unlocking.',
19
+ type: "text",
20
+ text: "Wallet not initialized. Please configure a wallet before unlocking.",
20
21
  },
21
22
  ],
22
23
  isError: true,
23
- }
24
+ };
24
25
  }
25
26
 
26
27
  try {
27
- const result = await unlockBsv.execute(ctx, {})
28
+ assertBroadcastAllowed("wallet_unlockBsv");
29
+ const result = await unlockBsv.execute(ctx, {});
28
30
 
29
31
  if (result.error) {
30
32
  return {
31
- content: [{ type: 'text', text: result.error }],
33
+ content: [{ type: "text", text: result.error }],
32
34
  isError: true,
33
- }
35
+ };
34
36
  }
35
37
 
36
38
  return {
37
39
  content: [
38
40
  {
39
- type: 'text',
40
- text: JSON.stringify(result, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2),
41
+ type: "text",
42
+ text: JSON.stringify(
43
+ result,
44
+ (_, v) => (typeof v === "bigint" ? v.toString() : v),
45
+ 2,
46
+ ),
41
47
  },
42
48
  ],
43
- }
49
+ };
44
50
  } catch (err: unknown) {
45
51
  return {
46
52
  content: [
47
53
  {
48
- type: 'text',
54
+ type: "text",
49
55
  text: err instanceof Error ? err.message : String(err),
50
56
  },
51
57
  ],
52
58
  isError: true,
53
- }
59
+ };
54
60
  }
55
61
  },
56
- )
62
+ );
57
63
  }
@@ -1,4 +1,5 @@
1
1
  import { Transaction } from "@bsv/sdk";
2
+ import { arrayBufferToUint8Array } from "../../utils/buffer";
2
3
 
3
4
  export async function getTransactionById(
4
5
  txid: string,
@@ -8,7 +8,6 @@
8
8
 
9
9
  import type { GetPublicKeyArgs, GetPublicKeyResult, PubKeyHex } from "@bsv/sdk";
10
10
  import {
11
- Beef,
12
11
  type BroadcastFailure,
13
12
  type BroadcastResponse,
14
13
  fromUtxo,
@@ -16,7 +15,6 @@ import {
16
15
  isBroadcastResponse,
17
16
  P2PKH,
18
17
  PrivateKey,
19
- type PublicKey,
20
18
  SatoshisPerKilobyte,
21
19
  Script,
22
20
  Transaction,
@@ -26,16 +24,6 @@ import { fetchNftUtxos, type NftUtxo, type Utxo } from "js-1sat-ord";
26
24
  import { V5Broadcaster } from "../../utils/broadcaster";
27
25
  import { fetchPaymentUtxosFromV5 } from "./fetchPaymentUtxos";
28
26
 
29
- // Local interface for what encrypt/decrypt expect, will be mapped from Zod schema
30
- interface InternalEncryptionArgs {
31
- data: number[];
32
- recipientPublicKey?: PublicKey; // For encryption
33
- }
34
-
35
- interface InternalDecryptionArgs {
36
- data: number[];
37
- }
38
-
39
27
  export class Wallet {
40
28
  private paymentUtxos: Utxo[] = [];
41
29
  private nftUtxos: NftUtxo[] = [];
@@ -146,7 +134,7 @@ export class Wallet {
146
134
  return this.getPaymentKey()?.toAddress();
147
135
  }
148
136
 
149
- async getPublicKey(args?: GetPublicKeyArgs): Promise<GetPublicKeyResult> {
137
+ async getPublicKey(_args?: GetPublicKeyArgs): Promise<GetPublicKeyResult> {
150
138
  const currentPaymentKey = this.getPaymentKey();
151
139
  if (!currentPaymentKey) {
152
140
  throw new Error("No payment key available to derive public key.");
@@ -1,74 +0,0 @@
1
- import type { OneSatContext } from '@1sat/actions'
2
- import { sendBsv } from '@1sat/actions'
3
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
4
- import { toSatoshi } from 'satoshi-token'
5
- import { getBsvPriceWithCache } from '../bsv/getPrice'
6
- import { sendToAddressArgsSchema } from './schemas'
7
-
8
- export function registerSendToAddressTool(
9
- server: McpServer,
10
- ctx: OneSatContext | undefined,
11
- ) {
12
- server.tool(
13
- 'wallet_sendToAddress',
14
- 'Sends Bitcoin SV (BSV) to a specified address. This tool supports payments in both BSV and USD amounts (with automatic conversion using current exchange rates). Transaction fees are automatically calculated and a confirmation with transaction ID is returned upon success.',
15
- { ...sendToAddressArgsSchema.shape },
16
- async ({ address, amount, currency = 'BSV', description = 'Send to address' }) => {
17
- if (!ctx) {
18
- return {
19
- content: [
20
- {
21
- type: 'text',
22
- text: 'Wallet not initialized. Please configure a wallet before sending.',
23
- },
24
- ],
25
- isError: true,
26
- }
27
- }
28
-
29
- try {
30
- let satoshis: number
31
- if (currency === 'USD') {
32
- const bsvPriceUsd = await getBsvPriceWithCache()
33
- satoshis = toSatoshi(amount / bsvPriceUsd)
34
- } else {
35
- satoshis = toSatoshi(amount)
36
- }
37
-
38
- const result = await sendBsv.execute(ctx, {
39
- requests: [{ address, satoshis }],
40
- })
41
-
42
- if (result.error) {
43
- return {
44
- content: [{ type: 'text', text: result.error }],
45
- isError: true,
46
- }
47
- }
48
-
49
- return {
50
- content: [
51
- {
52
- type: 'text',
53
- text: JSON.stringify({
54
- status: 'success',
55
- txid: result.txid,
56
- satoshis,
57
- }),
58
- },
59
- ],
60
- }
61
- } catch (error) {
62
- return {
63
- content: [
64
- {
65
- type: 'text',
66
- text: error instanceof Error ? error.message : String(error),
67
- },
68
- ],
69
- isError: true,
70
- }
71
- }
72
- },
73
- )
74
- }
@@ -1,161 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { z } from "zod";
3
- import type { IntegratedWallet } from "./integratedWallet";
4
-
5
- const setupDropletArgsSchema = z.object({
6
- action: z.enum(["register_key", "create_faucet", "check_status"]),
7
- faucetName: z.string().optional(),
8
- fixedDropSats: z.number().optional(),
9
- });
10
-
11
- export type SetupDropletArgs = z.infer<typeof setupDropletArgsSchema>;
12
-
13
- /**
14
- * Register the setupDroplet tool for Droplet API initialization
15
- */
16
- export function registerSetupDropletTool(
17
- server: McpServer,
18
- integratedWallet: IntegratedWallet,
19
- ) {
20
- server.tool(
21
- "wallet_setupDroplet",
22
- "Setup and manage Droplet API integration. Actions: register_key (registers your public key), create_faucet (creates a new faucet), check_status (checks faucet status)",
23
- { ...setupDropletArgsSchema.shape },
24
- async ({ action, faucetName, fixedDropSats }) => {
25
- try {
26
- const dropletClient = integratedWallet.getDropletClient();
27
- if (!dropletClient) {
28
- throw new Error("Droplet client not configured");
29
- }
30
-
31
- const config = dropletClient.getConfig();
32
- const apiUrl = config.apiUrl;
33
- const authKey = config.authKey;
34
-
35
- switch (action) {
36
- case "register_key": {
37
- if (!authKey) {
38
- throw new Error("No auth key configured");
39
- }
40
-
41
- const pubkey = authKey.toPublicKey().toString();
42
-
43
- // Register the key with the Droplet API
44
- const response = await fetch(`${apiUrl}/auth/register`, {
45
- method: "POST",
46
- headers: {
47
- "Content-Type": "application/json",
48
- },
49
- body: JSON.stringify({ publicKey: pubkey }),
50
- });
51
-
52
- if (!response.ok) {
53
- const error = await response.text();
54
- throw new Error(`Failed to register key: ${error}`);
55
- }
56
-
57
- return {
58
- content: [
59
- {
60
- type: "text",
61
- text: JSON.stringify({
62
- status: "success",
63
- message: "Key registered successfully",
64
- publicKey: pubkey,
65
- }),
66
- },
67
- ],
68
- };
69
- }
70
-
71
- case "create_faucet": {
72
- if (!faucetName) {
73
- throw new Error(
74
- "faucetName is required for create_faucet action",
75
- );
76
- }
77
-
78
- // First, ensure the key is registered
79
- if (authKey) {
80
- const pubkey = authKey.toPublicKey().toString();
81
- await fetch(`${apiUrl}/auth/register`, {
82
- method: "POST",
83
- headers: {
84
- "Content-Type": "application/json",
85
- },
86
- body: JSON.stringify({ publicKey: pubkey }),
87
- });
88
- }
89
-
90
- // Create the faucet
91
- const body = {
92
- name: faucetName,
93
- fixed_drop_sats: fixedDropSats || 1000,
94
- max_consolidation_inputs: 20,
95
- };
96
-
97
- const headers = authKey
98
- ? await dropletClient.getAuthHeaders("POST", "/faucets", body)
99
- : {};
100
-
101
- const response = await fetch(`${apiUrl}/faucets`, {
102
- method: "POST",
103
- headers: {
104
- "Content-Type": "application/json",
105
- ...headers,
106
- },
107
- body: JSON.stringify(body),
108
- });
109
-
110
- if (!response.ok) {
111
- const error = await response.text();
112
- throw new Error(`Failed to create faucet: ${error}`);
113
- }
114
-
115
- const result = await response.json();
116
- return {
117
- content: [
118
- {
119
- type: "text",
120
- text: JSON.stringify({
121
- status: "success",
122
- message: "Faucet created successfully",
123
- faucet: result,
124
- }),
125
- },
126
- ],
127
- };
128
- }
129
-
130
- case "check_status": {
131
- const status = await dropletClient.getFaucetStatus();
132
- return {
133
- content: [
134
- {
135
- type: "text",
136
- text: JSON.stringify({
137
- status: "success",
138
- faucetStatus: status,
139
- }),
140
- },
141
- ],
142
- };
143
- }
144
-
145
- default:
146
- throw new Error(`Unknown action: ${action}`);
147
- }
148
- } catch (error) {
149
- return {
150
- content: [
151
- {
152
- type: "text",
153
- text: error instanceof Error ? error.message : String(error),
154
- },
155
- ],
156
- isError: true,
157
- };
158
- }
159
- },
160
- );
161
- }