bsv-mcp 0.0.17 → 0.0.19
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 +22 -3
- package/index.ts +1 -1
- package/package.json +1 -1
- package/tools/bsv/explore.ts +113 -5
- package/tools/wallet/schemas.ts +5 -13
- package/tools/wallet/tools.ts +13 -15
package/README.md
CHANGED
|
@@ -267,6 +267,15 @@ The tool supports the following endpoint categories and specific endpoints:
|
|
|
267
267
|
| `block_by_hash` | Complete block data via hash | `blockHash` | `{"hash":"000000000000...","confirmations":1000,"size":1000000,...}` |
|
|
268
268
|
| `block_by_height` | Complete block data via height | `blockHeight` | `{"hash":"000000000000...","confirmations":1000,"size":1000000,...}` |
|
|
269
269
|
| `tag_count_by_height` | Stats on tag count for a specific block | `blockHeight` | `{"tags":{"amp":3,"bitkey":5,"metanet":12,"planaria":7,"b":120}}` |
|
|
270
|
+
| `block_headers` | Retrieves the last 10 block headers | None | `[{"hash":"000000000000...","height":826458,"version":536870912,...},...]` |
|
|
271
|
+
| `block_pages` | Retrieves pages of transaction IDs for large blocks | `blockHash`, optional: `pageNumber` | `["tx1hash","tx2hash","tx3hash",...]` |
|
|
272
|
+
|
|
273
|
+
#### Stats Data
|
|
274
|
+
| Endpoint | Description | Required Parameters | Example Response |
|
|
275
|
+
|----------|-------------|---------------------|------------------|
|
|
276
|
+
| `block_stats_by_height` | Block statistics for a specific height | `blockHeight` | `{"size":123456,"txCount":512,"outputTotal":54.12345678,"outputTotalUsd":2345.67,...}` |
|
|
277
|
+
| `block_miner_stats` | Block mining statistics for a time period | optional: `days` (default 7) | `{"blocks":{"miner1":412,"miner2":208,...},"total":1008}` |
|
|
278
|
+
| `miner_summary_stats` | Summary of mining statistics | optional: `days` (default 7) | `{"totalBlocks":1008,"totalFees":1.23456789,"totalFeesUsd":53.67,...}` |
|
|
270
279
|
|
|
271
280
|
#### Transaction Data
|
|
272
281
|
| Endpoint | Description | Required Parameters | Example Response |
|
|
@@ -274,6 +283,7 @@ The tool supports the following endpoint categories and specific endpoints:
|
|
|
274
283
|
| `tx_by_hash` | Detailed transaction data | `txHash` | `{"txid":"a1b2c3d4e5f6...","version":1,"locktime":0,"size":225,...}` |
|
|
275
284
|
| `tx_raw` | Raw transaction hex data | `txHash` | `"01000000012345abcdef..."` |
|
|
276
285
|
| `tx_receipt` | Transaction receipt | `txHash` | `{"blockHash":"000000000000...","blockHeight":800000,"confirmations":26458}` |
|
|
286
|
+
| `bulk_tx_details` | Retrieve multiple transactions in one request | `txids` (array) | `[{"txid":"a1b2c3d4e5f6...","version":1,...}, {"txid":"b2c3d4e5f6a7...","version":1,...}]` |
|
|
277
287
|
|
|
278
288
|
#### Address Data
|
|
279
289
|
| Endpoint | Description | Required Parameters | Example Response |
|
|
@@ -298,6 +308,12 @@ The `bsv_explore` tool can be used with natural language prompts like:
|
|
|
298
308
|
"Get unspent outputs for my wallet address"
|
|
299
309
|
"Check transaction details for txid a1b2c3d4e5f6..."
|
|
300
310
|
"What is the current BSV circulating supply?"
|
|
311
|
+
"Show me the latest block headers"
|
|
312
|
+
"Get transaction IDs for page 2 of a large block"
|
|
313
|
+
"Show me block statistics for height 800000"
|
|
314
|
+
"What are the mining statistics for the last 14 days?"
|
|
315
|
+
"Get a summary of mining activity over the past 30 days"
|
|
316
|
+
"Retrieve details for multiple transactions in a single query"
|
|
301
317
|
```
|
|
302
318
|
|
|
303
319
|
Under the hood, the tool accepts parameters to specify which data to retrieve:
|
|
@@ -305,9 +321,12 @@ Under the hood, the tool accepts parameters to specify which data to retrieve:
|
|
|
305
321
|
- `endpoint`: The specific WhatsOnChain endpoint to query (e.g., `chain_info`, `tx_by_hash`)
|
|
306
322
|
- `network`: The BSV network to use (`main` or `test`)
|
|
307
323
|
- Additional parameters as required by the specific endpoint:
|
|
308
|
-
- `blockHash`: For block_by_hash
|
|
309
|
-
- `blockHeight`: For block_by_height
|
|
310
|
-
- `
|
|
324
|
+
- `blockHash`: For block_by_hash and block_pages endpoints
|
|
325
|
+
- `blockHeight`: For block_by_height, tag_count_by_height, and block_stats_by_height endpoints
|
|
326
|
+
- `pageNumber`: For block_pages endpoint (pagination)
|
|
327
|
+
- `days`: For block_miner_stats and miner_summary_stats endpoints (defaults to 7)
|
|
328
|
+
- `txHash`: For transaction-related endpoints (tx_by_hash, tx_raw, tx_receipt)
|
|
329
|
+
- `txids`: For bulk_tx_details endpoint (array of transaction IDs)
|
|
311
330
|
- `address`: For address-related endpoints
|
|
312
331
|
- `limit`: Optional pagination limit for address_history
|
|
313
332
|
|
package/index.ts
CHANGED
package/package.json
CHANGED
package/tools/bsv/explore.ts
CHANGED
|
@@ -17,12 +17,20 @@ enum ExploreEndpoint {
|
|
|
17
17
|
// Block endpoints
|
|
18
18
|
BLOCK_BY_HASH = "block_by_hash",
|
|
19
19
|
BLOCK_BY_HEIGHT = "block_by_height",
|
|
20
|
+
BLOCK_HEADERS = "block_headers",
|
|
21
|
+
BLOCK_PAGES = "block_pages",
|
|
22
|
+
|
|
23
|
+
// Stats endpoints
|
|
20
24
|
TAG_COUNT_BY_HEIGHT = "tag_count_by_height",
|
|
25
|
+
BLOCK_STATS_BY_HEIGHT = "block_stats_by_height",
|
|
26
|
+
BLOCK_MINER_STATS = "block_miner_stats",
|
|
27
|
+
MINER_SUMMARY_STATS = "miner_summary_stats",
|
|
21
28
|
|
|
22
29
|
// Transaction endpoints
|
|
23
30
|
TX_BY_HASH = "tx_by_hash",
|
|
24
31
|
TX_RAW = "tx_raw",
|
|
25
32
|
TX_RECEIPT = "tx_receipt",
|
|
33
|
+
BULK_TX_DETAILS = "bulk_tx_details",
|
|
26
34
|
ADDRESS_HISTORY = "address_history",
|
|
27
35
|
ADDRESS_UTXOS = "address_utxos",
|
|
28
36
|
|
|
@@ -42,10 +50,13 @@ const exploreArgsSchema = z.object({
|
|
|
42
50
|
|
|
43
51
|
// Parameters for specific endpoints
|
|
44
52
|
blockHash: z.string().optional().describe("Block hash (required for block_by_hash endpoint)"),
|
|
45
|
-
blockHeight: z.number().optional().describe("Block height (required for block_by_height
|
|
53
|
+
blockHeight: z.number().optional().describe("Block height (required for block_by_height and block_stats_by_height endpoints)"),
|
|
46
54
|
txHash: z.string().optional().describe("Transaction hash (required for tx_by_hash, tx_raw, and tx_receipt endpoints)"),
|
|
55
|
+
txids: z.array(z.string()).optional().describe("Array of transaction IDs for bulk_tx_details endpoint"),
|
|
47
56
|
address: z.string().optional().describe("Bitcoin address (required for address_history and address_utxos endpoints)"),
|
|
48
57
|
limit: z.number().optional().describe("Limit for paginated results (optional for address_history)"),
|
|
58
|
+
pageNumber: z.number().optional().describe("Page number for block_pages endpoint (defaults to 1)"),
|
|
59
|
+
days: z.number().optional().describe("Number of days for miner stats endpoints (defaults to 7)"),
|
|
49
60
|
});
|
|
50
61
|
|
|
51
62
|
// Type for the tool arguments
|
|
@@ -67,11 +78,18 @@ export function registerExploreTool(server: McpServer): void {
|
|
|
67
78
|
"BLOCK DATA:\n" +
|
|
68
79
|
"- block_by_hash: Complete block data via hash (requires blockHash parameter)\n" +
|
|
69
80
|
"- block_by_height: Complete block data via height (requires blockHeight parameter)\n" +
|
|
70
|
-
"- tag_count_by_height: Stats on tag count for a specific block via height (requires blockHeight parameter)\n
|
|
81
|
+
"- tag_count_by_height: Stats on tag count for a specific block via height (requires blockHeight parameter)\n" +
|
|
82
|
+
"- block_headers: Retrieves the last 10 block headers\n" +
|
|
83
|
+
"- block_pages: Retrieves pages of transaction IDs for large blocks (requires blockHash and optional pageNumber)\n\n" +
|
|
84
|
+
"STATS DATA:\n" +
|
|
85
|
+
"- block_stats_by_height: Block statistics for a specific height (requires blockHeight parameter)\n" +
|
|
86
|
+
"- block_miner_stats: Block mining statistics for a time period (optional days parameter, default 7)\n" +
|
|
87
|
+
"- miner_summary_stats: Summary of mining statistics (optional days parameter, default 7)\n\n" +
|
|
71
88
|
"TRANSACTION DATA:\n" +
|
|
72
89
|
"- tx_by_hash: Detailed transaction data (requires txHash parameter)\n" +
|
|
73
90
|
"- tx_raw: Raw transaction hex data (requires txHash parameter)\n" +
|
|
74
|
-
"- tx_receipt: Transaction receipt (requires txHash parameter)\n
|
|
91
|
+
"- tx_receipt: Transaction receipt (requires txHash parameter)\n" +
|
|
92
|
+
"- bulk_tx_details: Bulk transaction details (requires txids parameter as array of transaction hashes)\n\n" +
|
|
75
93
|
"ADDRESS DATA:\n" +
|
|
76
94
|
"- address_history: Transaction history for address (requires address parameter, optional limit)\n" +
|
|
77
95
|
"- address_utxos: Unspent outputs for address (requires address parameter)\n\n" +
|
|
@@ -99,6 +117,18 @@ export function registerExploreTool(server: McpServer): void {
|
|
|
99
117
|
if ([ExploreEndpoint.ADDRESS_HISTORY, ExploreEndpoint.ADDRESS_UTXOS].includes(params.endpoint) && !params.address) {
|
|
100
118
|
throw new Error("address is required for address endpoints");
|
|
101
119
|
}
|
|
120
|
+
|
|
121
|
+
if (params.endpoint === ExploreEndpoint.BLOCK_PAGES && !params.blockHash) {
|
|
122
|
+
throw new Error("blockHash is required for block_pages endpoint");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (params.endpoint === ExploreEndpoint.BLOCK_STATS_BY_HEIGHT && params.blockHeight === undefined) {
|
|
126
|
+
throw new Error("blockHeight is required for block_stats_by_height endpoint");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (params.endpoint === ExploreEndpoint.BULK_TX_DETAILS && (!params.txids || params.txids.length === 0)) {
|
|
130
|
+
throw new Error("txids array is required for bulk_tx_details endpoint");
|
|
131
|
+
}
|
|
102
132
|
|
|
103
133
|
// Build API URL based on the selected endpoint
|
|
104
134
|
let apiUrl = `${WOC_API_BASE_URL}/${params.network}`;
|
|
@@ -125,6 +155,27 @@ export function registerExploreTool(server: McpServer): void {
|
|
|
125
155
|
case ExploreEndpoint.TAG_COUNT_BY_HEIGHT:
|
|
126
156
|
apiUrl += `/block/tagcount/height/${params.blockHeight}/stats`;
|
|
127
157
|
break;
|
|
158
|
+
case ExploreEndpoint.BLOCK_HEADERS:
|
|
159
|
+
apiUrl += "/block/headers";
|
|
160
|
+
break;
|
|
161
|
+
case ExploreEndpoint.BLOCK_PAGES: {
|
|
162
|
+
const pageNumber = params.pageNumber || 1;
|
|
163
|
+
apiUrl += `/block/hash/${params.blockHash}/page/${pageNumber}`;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case ExploreEndpoint.BLOCK_STATS_BY_HEIGHT:
|
|
167
|
+
apiUrl += `/block/height/${params.blockHeight}/stats`;
|
|
168
|
+
break;
|
|
169
|
+
case ExploreEndpoint.BLOCK_MINER_STATS: {
|
|
170
|
+
const days = params.days !== undefined ? params.days : 7;
|
|
171
|
+
apiUrl += `/miner/blocks/stats?days=${days}`;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case ExploreEndpoint.MINER_SUMMARY_STATS: {
|
|
175
|
+
const days = params.days !== undefined ? params.days : 7;
|
|
176
|
+
apiUrl += `/miner/summary/stats?days=${days}`;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
128
179
|
case ExploreEndpoint.TX_BY_HASH:
|
|
129
180
|
apiUrl += `/tx/hash/${params.txHash}`;
|
|
130
181
|
break;
|
|
@@ -134,6 +185,9 @@ export function registerExploreTool(server: McpServer): void {
|
|
|
134
185
|
case ExploreEndpoint.TX_RECEIPT:
|
|
135
186
|
apiUrl += `/tx/${params.txHash}/receipt`;
|
|
136
187
|
break;
|
|
188
|
+
case ExploreEndpoint.BULK_TX_DETAILS:
|
|
189
|
+
apiUrl += "/txs";
|
|
190
|
+
break;
|
|
137
191
|
case ExploreEndpoint.ADDRESS_HISTORY:
|
|
138
192
|
apiUrl += `/address/${params.address}/history`;
|
|
139
193
|
if (params.limit !== undefined) {
|
|
@@ -150,10 +204,64 @@ export function registerExploreTool(server: McpServer): void {
|
|
|
150
204
|
throw new Error(`Unsupported endpoint: ${params.endpoint}`);
|
|
151
205
|
}
|
|
152
206
|
|
|
153
|
-
//
|
|
207
|
+
// Special handling for bulk_tx_details which requires a POST request
|
|
208
|
+
if (params.endpoint === ExploreEndpoint.BULK_TX_DETAILS) {
|
|
209
|
+
const response = await fetch(apiUrl, {
|
|
210
|
+
method: "POST",
|
|
211
|
+
headers: {
|
|
212
|
+
"Content-Type": "application/json",
|
|
213
|
+
},
|
|
214
|
+
body: JSON.stringify({ txids: params.txids }),
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (!response.ok) {
|
|
218
|
+
let errorMsg = `API error: ${response.status} ${response.statusText}`;
|
|
219
|
+
if (response.status === 404) {
|
|
220
|
+
errorMsg += " - One or more transaction IDs not found";
|
|
221
|
+
}
|
|
222
|
+
throw new Error(errorMsg);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const result = await response.json();
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
content: [
|
|
229
|
+
{
|
|
230
|
+
type: "text",
|
|
231
|
+
text: JSON.stringify(result, null, 2),
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// For all other endpoints, use GET request
|
|
154
238
|
const response = await fetch(apiUrl);
|
|
155
239
|
if (!response.ok) {
|
|
156
|
-
|
|
240
|
+
let errorMsg = `API error: ${response.status} ${response.statusText}`;
|
|
241
|
+
// Provide helpful tips for specific error codes
|
|
242
|
+
if (response.status === 404) {
|
|
243
|
+
switch (params.endpoint) {
|
|
244
|
+
case ExploreEndpoint.BLOCK_BY_HASH:
|
|
245
|
+
errorMsg += ` - Block hash "${params.blockHash}" not found`;
|
|
246
|
+
break;
|
|
247
|
+
case ExploreEndpoint.BLOCK_BY_HEIGHT:
|
|
248
|
+
errorMsg += ` - Block at height ${params.blockHeight} not found`;
|
|
249
|
+
break;
|
|
250
|
+
case ExploreEndpoint.BLOCK_PAGES:
|
|
251
|
+
errorMsg += ` - Block hash "${params.blockHash}" not found or page ${params.pageNumber || 1} does not exist`;
|
|
252
|
+
break;
|
|
253
|
+
case ExploreEndpoint.TX_BY_HASH:
|
|
254
|
+
case ExploreEndpoint.TX_RAW:
|
|
255
|
+
case ExploreEndpoint.TX_RECEIPT:
|
|
256
|
+
errorMsg += ` - Transaction hash "${params.txHash}" not found`;
|
|
257
|
+
break;
|
|
258
|
+
case ExploreEndpoint.ADDRESS_HISTORY:
|
|
259
|
+
case ExploreEndpoint.ADDRESS_UTXOS:
|
|
260
|
+
errorMsg += ` - No data found for address "${params.address}"`;
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
throw new Error(errorMsg);
|
|
157
265
|
}
|
|
158
266
|
|
|
159
267
|
const result = await response.json();
|
package/tools/wallet/schemas.ts
CHANGED
|
@@ -74,21 +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
|
|
77
|
+
mode: z.enum(["encrypt", "decrypt"]).describe("Operation mode: 'encrypt' to encrypt plaintext or 'decrypt' to decrypt data"),
|
|
78
78
|
data: z.union([
|
|
79
|
-
z.string().describe("Text data
|
|
80
|
-
z.array(z.number()).describe("Binary data
|
|
81
|
-
]).describe("Data to process:
|
|
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
82
|
encoding: z.enum(["utf8", "hex", "base64"]).optional().default("utf8").describe("Encoding of text data (default: utf8)"),
|
|
83
|
-
|
|
84
|
-
keyID: z.string().describe("Key identifier - use 'default' or 'primary' for the default wallet key"),
|
|
85
|
-
privilegedReason: z.string().optional().describe("Required reason for privileged operations"),
|
|
86
|
-
counterparty: z
|
|
87
|
-
.union([z.string(), z.literal("self"), z.literal("anyone")])
|
|
88
|
-
.optional()
|
|
89
|
-
.describe("Recipient of encryption. Use 'self' for personal encryption, or provide a specific key for a recipient"),
|
|
90
|
-
privileged: z.boolean().optional().describe("Indicates if operation requires elevated privileges"),
|
|
91
|
-
}).describe("Combined schema for encryption and decryption operations. Use 'mode' to specify the operation type, with required parameters data, protocolID, and keyID.");
|
|
83
|
+
}).describe("Schema for encryption and decryption operations");
|
|
92
84
|
|
|
93
85
|
// Create HMAC arguments
|
|
94
86
|
export const createHmacArgsSchema = z.object({
|
package/tools/wallet/tools.ts
CHANGED
|
@@ -39,7 +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 } from "@bsv/sdk";
|
|
42
|
+
import { Utils, type WalletProtocol } from "@bsv/sdk";
|
|
43
43
|
|
|
44
44
|
// Define mapping from tool names to argument schemas
|
|
45
45
|
type ToolArgSchemas = {
|
|
@@ -177,24 +177,18 @@ export function registerWalletTools(
|
|
|
177
177
|
"Combined tool for encrypting and decrypting data using the wallet's cryptographic keys.\n\n" +
|
|
178
178
|
"PARAMETERS:\n" +
|
|
179
179
|
"- mode: (required) Either \"encrypt\" to encrypt plaintext or \"decrypt\" to decrypt ciphertext\n" +
|
|
180
|
-
"- data: (required) Text string or array of numbers to process
|
|
181
|
-
"- encoding: (optional) For text input, the encoding format (utf8, hex, base64) - default is utf8\n" +
|
|
182
|
-
"- protocolID: (required) Protocol identifier - common values are 'aes' for symmetric encryption or 'ecies' for asymmetric encryption\n" +
|
|
183
|
-
"- keyID: (required) Key identifier - use 'default' or 'primary' for the default wallet key\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
183
|
"1. Encrypt text data:\n" +
|
|
186
184
|
" {\n" +
|
|
187
185
|
" \"mode\": \"encrypt\",\n" +
|
|
188
|
-
" \"data\": \"Hello World\"
|
|
189
|
-
" \"protocolID\": [1, \"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\": [1, \"aes\"],\n" +
|
|
197
|
-
" \"keyID\": \"default\"\n" +
|
|
191
|
+
" \"data\": [encrypted bytes from previous response]\n" +
|
|
198
192
|
" }",
|
|
199
193
|
{ args: walletEncryptionArgsSchema },
|
|
200
194
|
async (
|
|
@@ -202,7 +196,11 @@ export function registerWalletTools(
|
|
|
202
196
|
extra: RequestHandlerExtra,
|
|
203
197
|
) => {
|
|
204
198
|
try {
|
|
205
|
-
const { mode, data,
|
|
199
|
+
const { mode, data, encoding } = args;
|
|
200
|
+
|
|
201
|
+
// Set default values for required parameters
|
|
202
|
+
const protocolID: WalletProtocol = [1, "aes256"];
|
|
203
|
+
const keyID = "default";
|
|
206
204
|
|
|
207
205
|
// Convert string data to binary if needed
|
|
208
206
|
let binaryData: number[];
|
|
@@ -214,7 +212,7 @@ export function registerWalletTools(
|
|
|
214
212
|
binaryData = toArray(data, encoding || "utf8");
|
|
215
213
|
}
|
|
216
214
|
|
|
217
|
-
let result: { ciphertext?: number[]; plaintext?: number[] } = {};
|
|
215
|
+
let result: { ciphertext?: number[]; plaintext?: number[] | string } = {};
|
|
218
216
|
if (mode === "encrypt") {
|
|
219
217
|
result = await wallet.encrypt({
|
|
220
218
|
plaintext: binaryData,
|
|
@@ -229,10 +227,10 @@ export function registerWalletTools(
|
|
|
229
227
|
});
|
|
230
228
|
|
|
231
229
|
// For decryption, convert plaintext back to string if it's likely UTF-8 text
|
|
232
|
-
if (result.plaintext) {
|
|
230
|
+
if (result.plaintext as number[]) {
|
|
233
231
|
try {
|
|
234
232
|
const { toUTF8 } = Utils;
|
|
235
|
-
const textResult = toUTF8(result.plaintext);
|
|
233
|
+
const textResult = toUTF8(result.plaintext as number[]);
|
|
236
234
|
// If conversion succeeds and seems like valid text, return as string
|
|
237
235
|
if (textResult && textResult.length > 0) {
|
|
238
236
|
return {
|