bsv-mcp 0.0.16 → 0.0.18
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 +1 -1
- package/index.ts +1 -1
- package/package.json +1 -1
- package/tools/wallet/schemas.ts +7 -11
- package/tools/wallet/tools.ts +57 -32
package/README.md
CHANGED
|
@@ -143,7 +143,7 @@ Wallet tools provide core BSV wallet functionality:
|
|
|
143
143
|
| `wallet_getPublicKey` | Retrieves a public key for a specified protocol and key ID | `{"publicKey":"032d0c73eb9270e9e009fd1f9dd77e19cf764fbad5f799560c4e8fd414e40d6fc2"}` |
|
|
144
144
|
| `wallet_createSignature` | Creates a cryptographic signature for the provided data | `{"signature":[144,124,85,193,226,45,140,249,9,177,11,167,33,215,209,38,...]}` |
|
|
145
145
|
| `wallet_verifySignature` | Verifies a cryptographic signature against the provided data | `{"isValid":true}` |
|
|
146
|
-
| `wallet_encryption` | Combined tool for encrypting and decrypting data using the wallet's cryptographic keys
|
|
146
|
+
| `wallet_encryption` | Combined tool for encrypting and decrypting data using the wallet's cryptographic keys.<br><br>**Examples:**<br>1. Encrypt text: `"Encrypt this message: Hello World"`<br>2. Decrypt data: `"Decrypt this data that was previously encrypted for me"` | Encrypt: `{"ciphertext":[89,32,155,38,125,22,49,226,26,...]}` <br> Decrypt: `{"plaintext":"hello world"}` |
|
|
147
147
|
| `wallet_getAddress` | Returns a BSV address for the current wallet or a derived path | `{"address":"1ExampleBsvAddressXXXXXXXXXXXXXXXXX","status":"ok"}` |
|
|
148
148
|
| `wallet_sendToAddress` | Sends BSV to a specified address (supports BSV or USD amounts) | `{"status":"success","txid":"a1b2c3d4e5f6...","satoshis":1000000}` |
|
|
149
149
|
| `wallet_purchaseListing` | Purchases NFTs or BSV-20/BSV-21 tokens from marketplace listings | `{"status":"success","txid":"a1b2c3d4e5f6...","type":"nft","origin":"abcdef123456..."}` |
|
package/index.ts
CHANGED
package/package.json
CHANGED
package/tools/wallet/schemas.ts
CHANGED
|
@@ -74,17 +74,13 @@ export const walletDecryptArgsSchema = z.object({
|
|
|
74
74
|
|
|
75
75
|
// Combined wallet encryption/decryption args
|
|
76
76
|
export const walletEncryptionArgsSchema = z.object({
|
|
77
|
-
mode: z.enum(["encrypt", "decrypt"]).describe("Operation mode: 'encrypt' to encrypt
|
|
78
|
-
data: z.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.optional()
|
|
85
|
-
.describe("Recipient of encryption. Use 'self' for personal encryption, or provide a specific key for a recipient"),
|
|
86
|
-
privileged: z.boolean().optional().describe("Indicates if operation requires elevated privileges"),
|
|
87
|
-
}).describe("Combined schema for encryption and decryption operations. Use 'mode' to specify the operation type, with required parameters data, protocolID, and keyID.");
|
|
77
|
+
mode: z.enum(["encrypt", "decrypt"]).describe("Operation mode: 'encrypt' to encrypt plaintext or 'decrypt' to decrypt data"),
|
|
78
|
+
data: z.union([
|
|
79
|
+
z.string().describe("Text data to encrypt or decrypt"),
|
|
80
|
+
z.array(z.number()).describe("Binary data to encrypt or decrypt")
|
|
81
|
+
]).describe("Data to process: text/data for encryption or decryption"),
|
|
82
|
+
encoding: z.enum(["utf8", "hex", "base64"]).optional().default("utf8").describe("Encoding of text data (default: utf8)"),
|
|
83
|
+
}).describe("Schema for encryption and decryption operations");
|
|
88
84
|
|
|
89
85
|
// Create HMAC arguments
|
|
90
86
|
export const createHmacArgsSchema = z.object({
|
package/tools/wallet/tools.ts
CHANGED
|
@@ -39,6 +39,7 @@ import type { createOrdinalsArgsSchema } from "./createOrdinals";
|
|
|
39
39
|
import { registerGetAddressTool } from "./getAddress";
|
|
40
40
|
import { registerPurchaseListingTool } from "./purchaseListing";
|
|
41
41
|
import { registerSendToAddressTool } from "./sendToAddress";
|
|
42
|
+
import { Utils, type WalletProtocol } from "@bsv/sdk";
|
|
42
43
|
|
|
43
44
|
// Define mapping from tool names to argument schemas
|
|
44
45
|
type ToolArgSchemas = {
|
|
@@ -176,25 +177,18 @@ export function registerWalletTools(
|
|
|
176
177
|
"Combined tool for encrypting and decrypting data using the wallet's cryptographic keys.\n\n" +
|
|
177
178
|
"PARAMETERS:\n" +
|
|
178
179
|
"- mode: (required) Either \"encrypt\" to encrypt plaintext or \"decrypt\" to decrypt ciphertext\n" +
|
|
179
|
-
"- data: (required)
|
|
180
|
-
"-
|
|
181
|
-
"- keyID: (required) Key identifier (use \"default\" or \"primary\" for default wallet key)\n" +
|
|
182
|
-
"- counterparty: (optional) Set to \"self\" for personal encryption or specific key for recipient\n" +
|
|
183
|
-
"- privileged: (optional) Boolean indicating if operation requires elevated privileges\n\n" +
|
|
180
|
+
"- data: (required) Text string or array of numbers to process\n" +
|
|
181
|
+
"- encoding: (optional) For text input, the encoding format (utf8, hex, base64) - default is utf8\n\n" +
|
|
184
182
|
"EXAMPLES:\n" +
|
|
185
|
-
"1. Encrypt data:\n" +
|
|
183
|
+
"1. Encrypt text data:\n" +
|
|
186
184
|
" {\n" +
|
|
187
185
|
" \"mode\": \"encrypt\",\n" +
|
|
188
|
-
" \"data\":
|
|
189
|
-
" \"protocolID\": \"aes\",\n" +
|
|
190
|
-
" \"keyID\": \"default\"\n" +
|
|
186
|
+
" \"data\": \"Hello World\"\n" +
|
|
191
187
|
" }\n\n" +
|
|
192
188
|
"2. Decrypt previously encrypted data:\n" +
|
|
193
189
|
" {\n" +
|
|
194
190
|
" \"mode\": \"decrypt\",\n" +
|
|
195
|
-
" \"data\": [encrypted bytes from previous response]
|
|
196
|
-
" \"protocolID\": \"aes\",\n" +
|
|
197
|
-
" \"keyID\": \"default\"\n" +
|
|
191
|
+
" \"data\": [encrypted bytes from previous response]\n" +
|
|
198
192
|
" }",
|
|
199
193
|
{ args: walletEncryptionArgsSchema },
|
|
200
194
|
async (
|
|
@@ -202,32 +196,63 @@ export function registerWalletTools(
|
|
|
202
196
|
extra: RequestHandlerExtra,
|
|
203
197
|
) => {
|
|
204
198
|
try {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
199
|
+
const { mode, data, encoding } = args;
|
|
200
|
+
|
|
201
|
+
// Set default values for required parameters
|
|
202
|
+
const protocolID: WalletProtocol = [1, "aes256"];
|
|
203
|
+
const keyID = "default";
|
|
204
|
+
|
|
205
|
+
// Convert string data to binary if needed
|
|
206
|
+
let binaryData: number[];
|
|
207
|
+
if (Array.isArray(data)) {
|
|
208
|
+
binaryData = data;
|
|
209
|
+
} else {
|
|
210
|
+
// String data with encoding
|
|
211
|
+
const { toArray } = Utils;
|
|
212
|
+
binaryData = toArray(data, encoding || "utf8");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let result: { ciphertext?: number[]; plaintext?: number[] | string } = {};
|
|
216
|
+
if (mode === "encrypt") {
|
|
208
217
|
result = await wallet.encrypt({
|
|
209
|
-
plaintext:
|
|
210
|
-
protocolID
|
|
211
|
-
keyID
|
|
212
|
-
privilegedReason: args.privilegedReason,
|
|
213
|
-
counterparty: args.counterparty,
|
|
214
|
-
privileged: args.privileged,
|
|
218
|
+
plaintext: binaryData,
|
|
219
|
+
protocolID,
|
|
220
|
+
keyID,
|
|
215
221
|
});
|
|
216
|
-
} else {
|
|
217
|
-
// For decryption, the data is treated as ciphertext
|
|
222
|
+
} else if (mode === "decrypt") {
|
|
218
223
|
result = await wallet.decrypt({
|
|
219
|
-
ciphertext:
|
|
220
|
-
protocolID
|
|
221
|
-
keyID
|
|
222
|
-
privilegedReason: args.privilegedReason,
|
|
223
|
-
counterparty: args.counterparty,
|
|
224
|
-
privileged: args.privileged,
|
|
224
|
+
ciphertext: binaryData,
|
|
225
|
+
protocolID,
|
|
226
|
+
keyID,
|
|
225
227
|
});
|
|
228
|
+
|
|
229
|
+
// For decryption, convert plaintext back to string if it's likely UTF-8 text
|
|
230
|
+
if (result.plaintext as number[]) {
|
|
231
|
+
try {
|
|
232
|
+
const { toUTF8 } = Utils;
|
|
233
|
+
const textResult = toUTF8(result.plaintext as number[]);
|
|
234
|
+
// If conversion succeeds and seems like valid text, return as string
|
|
235
|
+
if (textResult && textResult.length > 0) {
|
|
236
|
+
return {
|
|
237
|
+
content: [{
|
|
238
|
+
type: "text",
|
|
239
|
+
text: JSON.stringify({ plaintext: textResult })
|
|
240
|
+
}]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
} catch (e) {
|
|
244
|
+
// If UTF-8 conversion fails, continue with binary result
|
|
245
|
+
}
|
|
246
|
+
}
|
|
226
247
|
}
|
|
248
|
+
|
|
227
249
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
228
|
-
} catch (
|
|
229
|
-
const
|
|
230
|
-
return {
|
|
250
|
+
} catch (error) {
|
|
251
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
252
|
+
return {
|
|
253
|
+
content: [{ type: "text", text: `Error during ${args.mode}: ${errorMessage}` }],
|
|
254
|
+
isError: true
|
|
255
|
+
};
|
|
231
256
|
}
|
|
232
257
|
},
|
|
233
258
|
);
|