bsv-mcp 0.0.7 → 0.0.8
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/Dockerfile +20 -0
- package/README.md +8 -2
- package/package.json +1 -1
- package/smithery.yaml +10 -10
- package/tools/wallet/schemas.ts +14 -0
- package/tools/wallet/tools.ts +36 -31
- package/tools/wallet/wallet.ts +10 -1
package/Dockerfile
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Use the official Bun image
|
|
2
|
+
FROM oven/bun:1
|
|
3
|
+
|
|
4
|
+
# Set working directory
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
# Copy all application code first
|
|
8
|
+
COPY . .
|
|
9
|
+
|
|
10
|
+
# Install dependencies
|
|
11
|
+
RUN bun install --frozen-lockfile
|
|
12
|
+
|
|
13
|
+
# Set user for security
|
|
14
|
+
USER bun
|
|
15
|
+
|
|
16
|
+
# Expose port (if needed)
|
|
17
|
+
EXPOSE 3000
|
|
18
|
+
|
|
19
|
+
# Run the application
|
|
20
|
+
CMD ["bun", "run", "index.ts"]
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Bitcoin SV MCP Server
|
|
2
2
|
|
|
3
|
+
[](https://smithery.ai/server/@b-open-io/bsv-mcp)
|
|
4
|
+
|
|
3
5
|
> **⚠️ NOTICE: Experimental Work in Progress**
|
|
4
6
|
> This project is in an early experimental stage. Features may change, and the API is not yet stable.
|
|
5
7
|
> Contributions, feedback, and bug reports are welcome! Feel free to open issues or submit pull requests.
|
|
@@ -141,8 +143,7 @@ Wallet tools provide core BSV wallet functionality:
|
|
|
141
143
|
| `wallet_getPublicKey` | Retrieves a public key for a specified protocol and key ID |
|
|
142
144
|
| `wallet_createSignature` | Creates a cryptographic signature for the provided data |
|
|
143
145
|
| `wallet_verifySignature` | Verifies a cryptographic signature against the provided data |
|
|
144
|
-
| `
|
|
145
|
-
| `wallet_decrypt` | Decrypts data using a specified protocol and key |
|
|
146
|
+
| `wallet_encryption` | Combined tool for encrypting and decrypting data using the wallet's cryptographic keys (replaces separate encrypt/decrypt tools) |
|
|
146
147
|
| `wallet_getAddress` | Returns a BSV address for the current wallet or a derived path |
|
|
147
148
|
| `wallet_sendToAddress` | Sends BSV to a specified address (supports BSV or USD amounts) |
|
|
148
149
|
| `wallet_purchaseListing` | Purchases NFTs or BSV-20/BSV-21 tokens from marketplace listings |
|
|
@@ -185,6 +186,8 @@ Once connected, you can use natural language to interact with Bitcoin SV through
|
|
|
185
186
|
- "Get my Bitcoin SV address"
|
|
186
187
|
- "Send 0.01 BSV to 1ExampleBsvAddressXXXXXXXXXXXXXXXXX"
|
|
187
188
|
- "Send $5 USD worth of BSV to 1ExampleBsvAddressXXXXXXXXXXXXXXXXX"
|
|
189
|
+
- "Encrypt this message using my wallet's keys"
|
|
190
|
+
- "Decrypt this data that was previously encrypted for me"
|
|
188
191
|
- "Purchase this NFT listing: txid_vout"
|
|
189
192
|
- "Purchase this BSV-20 token listing: txid_vout"
|
|
190
193
|
|
|
@@ -230,6 +233,9 @@ For Cursor, check the Cursor MCP logs in Settings → Extensions → Model Conte
|
|
|
230
233
|
|
|
231
234
|
## Recent Updates
|
|
232
235
|
|
|
236
|
+
### Unified Encryption Tool
|
|
237
|
+
- **Combined Wallet Encryption**: The `wallet_encrypt` and `wallet_decrypt` tools have been merged into a single `wallet_encryption` tool with a mode parameter to switch between encryption and decryption operations.
|
|
238
|
+
|
|
233
239
|
### Enhanced Marketplace Tools
|
|
234
240
|
- **Unified Market Listings**: The `ordinals_marketListings` tool now supports NFTs, BSV-20, and BSV-21 tokens through a single interface with appropriate filtering.
|
|
235
241
|
- **Improved Market Sales**: The `ordinals_marketSales` tool (renamed from `ordinals_bsv20MarketSales`) now supports both BSV-20 and BSV-21 token sales.
|
package/package.json
CHANGED
package/smithery.yaml
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
build:
|
|
2
|
+
dockerBuildPath: ./
|
|
3
|
+
|
|
1
4
|
startCommand:
|
|
2
5
|
type: stdio
|
|
3
6
|
configSchema:
|
|
@@ -7,15 +10,12 @@ startCommand:
|
|
|
7
10
|
properties:
|
|
8
11
|
privateKeyWif:
|
|
9
12
|
type: string
|
|
10
|
-
description: "
|
|
13
|
+
description: "The private key WIF (Wallet Import Format) for Bitcoin SV transactions. This key is used to sign transactions and is required for wallet operations."
|
|
11
14
|
commandFunction: |
|
|
12
|
-
(config) => ({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"env": {
|
|
19
|
-
"PRIVATE_KEY_WIF": config.privateKeyWif
|
|
20
|
-
}
|
|
15
|
+
(config) => ({
|
|
16
|
+
command: 'bun',
|
|
17
|
+
args: ['run', 'index.ts'],
|
|
18
|
+
env: {
|
|
19
|
+
PRIVATE_KEY_WIF: config.privateKeyWif
|
|
20
|
+
}
|
|
21
21
|
})
|
package/tools/wallet/schemas.ts
CHANGED
|
@@ -72,6 +72,19 @@ export const walletDecryptArgsSchema = z.object({
|
|
|
72
72
|
privileged: z.boolean().optional(),
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
+
// Combined wallet encryption/decryption args
|
|
76
|
+
export const walletEncryptionArgsSchema = z.object({
|
|
77
|
+
mode: z.enum(["encrypt", "decrypt"]).describe("Operation mode: 'encrypt' to encrypt data or 'decrypt' to decrypt data"),
|
|
78
|
+
data: z.array(z.number()).describe("Data to process: plaintext for encryption or ciphertext for decryption"),
|
|
79
|
+
protocolID: walletProtocolSchema,
|
|
80
|
+
keyID: z.string(),
|
|
81
|
+
privilegedReason: z.string().optional(),
|
|
82
|
+
counterparty: z
|
|
83
|
+
.union([z.string(), z.literal("self"), z.literal("anyone")])
|
|
84
|
+
.optional(),
|
|
85
|
+
privileged: z.boolean().optional(),
|
|
86
|
+
}).describe("Combined schema for encryption and decryption operations, with a mode parameter to switch between functions");
|
|
87
|
+
|
|
75
88
|
// Create HMAC arguments
|
|
76
89
|
export const createHmacArgsSchema = z.object({
|
|
77
90
|
message: z.string(),
|
|
@@ -296,3 +309,4 @@ export const purchaseListingArgsSchema = z.object({
|
|
|
296
309
|
// Export types
|
|
297
310
|
export type SendToAddressArgs = z.infer<typeof sendToAddressArgsSchema>;
|
|
298
311
|
export type PurchaseListingArgs = z.infer<typeof purchaseListingArgsSchema>;
|
|
312
|
+
export type WalletEncryptionArgs = z.infer<typeof walletEncryptionArgsSchema>;
|
package/tools/wallet/tools.ts
CHANGED
|
@@ -31,8 +31,7 @@ import {
|
|
|
31
31
|
type purchaseListingArgsSchema,
|
|
32
32
|
type sendToAddressArgsSchema,
|
|
33
33
|
verifySignatureArgsSchema,
|
|
34
|
-
|
|
35
|
-
walletEncryptArgsSchema,
|
|
34
|
+
walletEncryptionArgsSchema,
|
|
36
35
|
} from "./schemas";
|
|
37
36
|
|
|
38
37
|
import { registerCreateOrdinalsTool } from "./createOrdinals";
|
|
@@ -46,8 +45,7 @@ type ToolArgSchemas = {
|
|
|
46
45
|
wallet_getPublicKey: typeof getPublicKeyArgsSchema;
|
|
47
46
|
wallet_createSignature: typeof createSignatureArgsSchema;
|
|
48
47
|
wallet_verifySignature: typeof verifySignatureArgsSchema;
|
|
49
|
-
|
|
50
|
-
wallet_decrypt: typeof walletDecryptArgsSchema;
|
|
48
|
+
wallet_encryption: typeof walletEncryptionArgsSchema;
|
|
51
49
|
wallet_listActions: typeof listActionsArgsSchema;
|
|
52
50
|
wallet_listOutputs: typeof listOutputsArgsSchema;
|
|
53
51
|
wallet_getNetwork: typeof emptyArgsSchema;
|
|
@@ -94,11 +92,12 @@ export function registerWalletTools(
|
|
|
94
92
|
// Handle tools registration with properly typed parameters
|
|
95
93
|
function registerTool<T extends z.ZodType>(
|
|
96
94
|
name: keyof ToolArgSchemas,
|
|
95
|
+
description: string,
|
|
97
96
|
schema: { args: T },
|
|
98
97
|
handler: ToolCallback<{ args: T }>,
|
|
99
98
|
): void {
|
|
100
99
|
// Register all tools normally
|
|
101
|
-
server.tool(name, schema, handler);
|
|
100
|
+
server.tool(name, description, schema, handler);
|
|
102
101
|
handlers[name] = handler as ToolHandler;
|
|
103
102
|
}
|
|
104
103
|
|
|
@@ -117,6 +116,7 @@ export function registerWalletTools(
|
|
|
117
116
|
// Register wallet_getPublicKey
|
|
118
117
|
registerTool(
|
|
119
118
|
"wallet_getPublicKey",
|
|
119
|
+
"Retrieves the current wallet's public key. This public key can be used for cryptographic operations like signature verification or encryption.",
|
|
120
120
|
{ args: getPublicKeyArgsSchema },
|
|
121
121
|
async (
|
|
122
122
|
{ args }: { args: z.infer<typeof getPublicKeyArgsSchema> },
|
|
@@ -135,6 +135,7 @@ export function registerWalletTools(
|
|
|
135
135
|
// Register wallet_createSignature
|
|
136
136
|
registerTool(
|
|
137
137
|
"wallet_createSignature",
|
|
138
|
+
"Creates a cryptographic signature using the wallet's private key. This tool enables secure message signing and transaction authorization, supporting various signature protocols.",
|
|
138
139
|
{ args: createSignatureArgsSchema },
|
|
139
140
|
async (
|
|
140
141
|
{ args }: { args: z.infer<typeof createSignatureArgsSchema> },
|
|
@@ -153,6 +154,7 @@ export function registerWalletTools(
|
|
|
153
154
|
// Register wallet_verifySignature
|
|
154
155
|
registerTool(
|
|
155
156
|
"wallet_verifySignature",
|
|
157
|
+
"Verifies a cryptographic signature against a message or data. This tool supports various verification protocols and can validate signatures from both the wallet's own keys and external public keys.",
|
|
156
158
|
{ args: verifySignatureArgsSchema },
|
|
157
159
|
async (
|
|
158
160
|
{ args }: { args: z.infer<typeof verifySignatureArgsSchema> },
|
|
@@ -168,16 +170,38 @@ export function registerWalletTools(
|
|
|
168
170
|
},
|
|
169
171
|
);
|
|
170
172
|
|
|
171
|
-
// Register
|
|
173
|
+
// Register combined wallet_encryption tool
|
|
172
174
|
registerTool(
|
|
173
|
-
"
|
|
174
|
-
|
|
175
|
+
"wallet_encryption",
|
|
176
|
+
"Combined tool for encrypting and decrypting data using the wallet's cryptographic keys. Supports both encryption of plaintext data and decryption of previously encrypted content. Use the 'mode' parameter to switch between operations.",
|
|
177
|
+
{ args: walletEncryptionArgsSchema },
|
|
175
178
|
async (
|
|
176
|
-
{ args }: { args: z.infer<typeof
|
|
179
|
+
{ args }: { args: z.infer<typeof walletEncryptionArgsSchema> },
|
|
177
180
|
extra: RequestHandlerExtra,
|
|
178
181
|
) => {
|
|
179
182
|
try {
|
|
180
|
-
|
|
183
|
+
let result: { ciphertext?: number[]; plaintext?: number[] };
|
|
184
|
+
if (args.mode === "encrypt") {
|
|
185
|
+
// For encryption, the data is treated as plaintext
|
|
186
|
+
result = await wallet.encrypt({
|
|
187
|
+
plaintext: args.data,
|
|
188
|
+
protocolID: args.protocolID,
|
|
189
|
+
keyID: args.keyID,
|
|
190
|
+
privilegedReason: args.privilegedReason,
|
|
191
|
+
counterparty: args.counterparty,
|
|
192
|
+
privileged: args.privileged,
|
|
193
|
+
});
|
|
194
|
+
} else {
|
|
195
|
+
// For decryption, the data is treated as ciphertext
|
|
196
|
+
result = await wallet.decrypt({
|
|
197
|
+
ciphertext: args.data,
|
|
198
|
+
protocolID: args.protocolID,
|
|
199
|
+
keyID: args.keyID,
|
|
200
|
+
privilegedReason: args.privilegedReason,
|
|
201
|
+
counterparty: args.counterparty,
|
|
202
|
+
privileged: args.privileged,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
181
205
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
182
206
|
} catch (err: unknown) {
|
|
183
207
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -186,27 +210,8 @@ export function registerWalletTools(
|
|
|
186
210
|
},
|
|
187
211
|
);
|
|
188
212
|
|
|
189
|
-
// Register
|
|
190
|
-
registerTool(
|
|
191
|
-
"wallet_decrypt",
|
|
192
|
-
{ args: walletDecryptArgsSchema },
|
|
193
|
-
async (
|
|
194
|
-
{ args }: { args: z.infer<typeof walletDecryptArgsSchema> },
|
|
195
|
-
extra: RequestHandlerExtra,
|
|
196
|
-
) => {
|
|
197
|
-
try {
|
|
198
|
-
const result = await wallet.decrypt(args);
|
|
199
|
-
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
200
|
-
} catch (err: unknown) {
|
|
201
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
202
|
-
return { content: [{ type: "text", text: msg }], isError: true };
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
// Register ordinals extension tools
|
|
208
|
-
// Register the wallet_createOrdinals tool
|
|
213
|
+
// Register createOrdinals tool
|
|
209
214
|
registerCreateOrdinalsTool(server, wallet);
|
|
210
|
-
|
|
215
|
+
|
|
211
216
|
return handlers;
|
|
212
217
|
}
|
package/tools/wallet/wallet.ts
CHANGED
|
@@ -38,6 +38,7 @@ import type {
|
|
|
38
38
|
ListOutputsResult,
|
|
39
39
|
ProveCertificateArgs,
|
|
40
40
|
ProveCertificateResult,
|
|
41
|
+
PubKeyHex,
|
|
41
42
|
RelinquishCertificateArgs,
|
|
42
43
|
RelinquishCertificateResult,
|
|
43
44
|
RelinquishOutputArgs,
|
|
@@ -127,7 +128,15 @@ export class Wallet extends ProtoWallet implements WalletInterface {
|
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
async getPublicKey(args: GetPublicKeyArgs): Promise<GetPublicKeyResult> {
|
|
130
|
-
|
|
131
|
+
const privateKey = this.getPrivateKey();
|
|
132
|
+
if (!privateKey) {
|
|
133
|
+
throw new Error("No private key available");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const publicKey = privateKey.toPublicKey();
|
|
137
|
+
return {
|
|
138
|
+
publicKey: publicKey.toDER("hex") as PubKeyHex,
|
|
139
|
+
};
|
|
131
140
|
}
|
|
132
141
|
async revealCounterpartyKeyLinkage(
|
|
133
142
|
args: RevealCounterpartyKeyLinkageArgs,
|