bsv-mcp 0.0.1 → 0.0.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 BSV-MCP Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Bitcoin SV MCP Server
2
2
 
3
+ > **⚠️ NOTICE: Experimental Work in Progress**
4
+ > This project is in an early experimental stage. Features may change, and the API is not yet stable.
5
+ > Contributions, feedback, and bug reports are welcome! Feel free to open issues or submit pull requests.
6
+
3
7
  A collection of Bitcoin SV (BSV) tools for the Model Context Protocol (MCP) framework. This library provides wallet, ordinals, and utility functions for BSV blockchain interaction.
4
8
 
5
9
  ## Installation
@@ -150,7 +154,8 @@ Wallet tools provide core BSV wallet functionality:
150
154
  | `wallet_decrypt` | Decrypts data using a specified protocol and key |
151
155
  | `wallet_getAddress` | Returns a BSV address for the current wallet or a derived path |
152
156
  | `wallet_sendToAddress` | Sends BSV to a specified address (supports BSV or USD amounts) |
153
- | `wallet_purchaseListing` | Purchases an NFT from a marketplace listing |
157
+ | `wallet_purchaseListing` | Purchases NFTs or BSV-20/BSV-21 tokens from marketplace listings |
158
+ | `wallet_createOrdinals` | Creates and inscribes ordinals on the BSV blockchain |
154
159
 
155
160
  ### BSV Tools
156
161
 
@@ -169,8 +174,8 @@ Tools for working with ordinals (NFTs) on BSV:
169
174
  |-----------|-------------|
170
175
  | `ordinals_getInscription` | Retrieves detailed information about a specific inscription |
171
176
  | `ordinals_searchInscriptions` | Searches for inscriptions based on various criteria |
172
- | `ordinals_marketListings` | Retrieves current marketplace listings for inscriptions |
173
- | `ordinals_bsv20MarketSales` | Gets information about BSV20 token market sales |
177
+ | `ordinals_marketListings` | Retrieves market listings for NFTs, BSV-20, and BSV-21 tokens with unified interface |
178
+ | `ordinals_marketSales` | Gets information about BSV-20 and BSV-21 token market sales |
174
179
  | `ordinals_getBsv20ById` | Retrieves details about a specific BSV20 token by ID |
175
180
 
176
181
  ### Utility Tools
@@ -189,11 +194,15 @@ Once connected, you can use natural language to interact with Bitcoin SV through
189
194
  - "Get my Bitcoin SV address"
190
195
  - "Send 0.01 BSV to 1ExampleBsvAddressXXXXXXXXXXXXXXXXX"
191
196
  - "Send $5 USD worth of BSV to 1ExampleBsvAddressXXXXXXXXXXXXXXXXX"
197
+ - "Purchase this NFT listing: txid_vout"
198
+ - "Purchase this BSV-20 token listing: txid_vout"
192
199
 
193
200
  ### Ordinals (NFTs)
194
201
  - "Show me information about the NFT with outpoint 6a89047af2cfac96da17d51ae8eb62c5f1d982be2bc4ba0d0cd2084b7ffed325_0"
195
202
  - "Search for Pixel Zoide NFTs"
196
203
  - "Show me the current marketplace listings for BSV NFTs"
204
+ - "Show me BSV-20 token listings for ticker PEPE"
205
+ - "Get recent BSV-20 token sales"
197
206
 
198
207
  ### Blockchain Operations
199
208
  - "What is the current BSV price?"
@@ -228,6 +237,17 @@ tail -n 20 -f ~/Library/Logs/Claude/mcp*.log
228
237
 
229
238
  For Cursor, check the Cursor MCP logs in Settings → Extensions → Model Context Protocol.
230
239
 
240
+ ## Recent Updates
241
+
242
+ ### Enhanced Marketplace Tools
243
+ - **Unified Market Listings**: The `ordinals_marketListings` tool now supports NFTs, BSV-20, and BSV-21 tokens through a single interface with appropriate filtering.
244
+ - **Improved Market Sales**: The `ordinals_marketSales` tool (renamed from `ordinals_bsv20MarketSales`) now supports both BSV-20 and BSV-21 token sales.
245
+ - **Token Purchases**: The `wallet_purchaseListing` tool has been enhanced to support purchasing both NFTs and BSV-20/BSV-21 tokens.
246
+
247
+ ### API Refinements
248
+ - Standardized endpoint structure for interactions with the GorillaPool API.
249
+ - Improved parameter handling for different token types and marketplace actions.
250
+
231
251
  ## Development
232
252
 
233
253
  This project was created using `bun init` in bun v1.2.9. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
@@ -255,4 +275,4 @@ bun test
255
275
 
256
276
  ## License
257
277
 
258
- [Include your license information here]
278
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
package/index.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import {
3
- PrivateKey,
4
- } from "@bsv/sdk";
2
+ import { PrivateKey } from "@bsv/sdk";
5
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
5
  import { registerAllTools } from "./tools";
@@ -10,7 +8,7 @@ import { Wallet } from "./tools/wallet/wallet";
10
8
 
11
9
  const server = new McpServer({
12
10
  name: "Bitcoin SV MCP",
13
- version: "1.0.0",
11
+ version: "0.0.1",
14
12
  });
15
13
 
16
14
  // Singleton wallet instance (for demo, could be replaced with real key management)
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "bsv-mcp",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.0.1",
5
+ "version": "0.0.3",
6
6
  "bin": {
7
7
  "bsv-mcp": "./index.ts"
8
8
  },
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Constants for BSV MCP Tools
3
+ */
4
+
5
+ /**
6
+ * Market fee percentage applied to all marketplace purchases
7
+ * Expressed as a decimal (e.g., 0.03 = 3%)
8
+ */
9
+ export const MARKET_FEE_PERCENTAGE = 0.03;
10
+
11
+ /**
12
+ * Market wallet address where fees are sent
13
+ * This is the recipient address for marketplace fees
14
+ */
15
+ export const MARKET_WALLET_ADDRESS = "15q8YQSqUa9uTh6gh4AVixxq29xkpBBP9z";
16
+
17
+ /**
18
+ * Minimum fee in satoshis
19
+ * Market fee will never be less than this amount
20
+ */
21
+ export const MINIMUM_MARKET_FEE_SATOSHIS = 10000; // 10000 satoshis = 0.0001 BSV
@@ -1,8 +1,8 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { registerBsv20MarketSalesTool } from "./bsv20MarketSales";
3
2
  import { registerGetBsv20ByIdTool } from "./getBsv20ById";
4
3
  import { registerGetInscriptionTool } from "./getInscription";
5
4
  import { registerMarketListingsTool } from "./marketListings";
5
+ import { registerMarketSalesTool } from "./marketSales";
6
6
  import { registerSearchInscriptionsTool } from "./searchInscriptions";
7
7
 
8
8
  /**
@@ -14,6 +14,6 @@ export function registerOrdinalsTools(server: McpServer): void {
14
14
  registerGetInscriptionTool(server);
15
15
  registerSearchInscriptionsTool(server);
16
16
  registerMarketListingsTool(server);
17
- registerBsv20MarketSalesTool(server);
17
+ registerMarketSalesTool(server);
18
18
  registerGetBsv20ByIdTool(server);
19
19
  }
@@ -2,8 +2,9 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
3
  import { z } from "zod";
4
4
 
5
- // Schema for market listings arguments
5
+ // Enhanced schema for unified market listings arguments
6
6
  export const marketListingsArgsSchema = z.object({
7
+ // Common parameters
7
8
  limit: z
8
9
  .number()
9
10
  .int()
@@ -12,29 +13,47 @@ export const marketListingsArgsSchema = z.object({
12
13
  .default(20)
13
14
  .describe("Number of results (1-100, default 20)"),
14
15
  offset: z.number().int().min(0).default(0).describe("Pagination offset"),
15
- sort: z
16
- .enum(["recent", "price", "num"])
17
- .default("recent")
18
- .describe("Sort method (recent, price, or num)"),
19
16
  dir: z
20
17
  .enum(["asc", "desc"])
21
18
  .default("desc")
22
19
  .describe("Sort direction (asc or desc)"),
23
20
  address: z.string().optional().describe("Bitcoin address"),
21
+
22
+ // NFT-specific parameters
24
23
  origin: z.string().optional().describe("Origin outpoint"),
25
24
  mime: z.string().optional().describe("MIME type filter"),
26
25
  num: z.string().optional().describe("Inscription number"),
26
+
27
+ // General market parameters
27
28
  minPrice: z.number().optional().describe("Minimum price in satoshis"),
28
29
  maxPrice: z.number().optional().describe("Maximum price in satoshis"),
30
+
31
+ // Token-specific parameters
32
+ tokenType: z
33
+ .enum(["nft", "bsv20", "bsv21", "all"])
34
+ .default("all")
35
+ .describe("Type of token to search for (nft, bsv20, bsv21, or all)"),
36
+ sort: z
37
+ .enum(["recent", "price", "num", "height", "price_per_token"])
38
+ .default("recent")
39
+ .describe("Sort method (recent, price, num, height, price_per_token)"),
40
+ bsv20Type: z
41
+ .enum(["v1", "v2", "all"])
42
+ .default("all")
43
+ .optional()
44
+ .describe("BSV20 token type (v1, v2, or all)"),
45
+ id: z.string().optional().describe("Token ID in outpoint format"),
46
+ tick: z.string().optional().describe("Token ticker symbol"),
47
+ pending: z.boolean().default(false).optional().describe("Include pending sales"),
29
48
  });
30
49
 
31
50
  export type MarketListingsArgs = z.infer<typeof marketListingsArgsSchema>;
32
51
 
33
- // Simplified market listing response type
52
+ // Unified response type that covers all token types
34
53
  interface MarketListingResponse {
35
54
  results: Array<{
36
55
  outpoint: string;
37
- origin: {
56
+ origin?: {
38
57
  outpoint: string;
39
58
  data?: {
40
59
  insc?: {
@@ -51,16 +70,26 @@ interface MarketListingResponse {
51
70
  price?: number;
52
71
  payout?: string;
53
72
  sale?: boolean;
73
+ price_per_token?: number;
74
+ };
75
+ bsv20?: {
76
+ id?: string;
77
+ tick?: string;
78
+ sym?: string;
79
+ amt?: string;
80
+ op?: string;
54
81
  };
55
82
  };
56
83
  satoshis?: number;
84
+ height?: number;
57
85
  [key: string]: unknown;
58
86
  }>;
59
87
  total: number;
60
88
  }
61
89
 
62
90
  /**
63
- * Register the Ordinals market listings tool
91
+ * Register the unified Ordinals market listings tool
92
+ * Handles NFTs, BSV20, and BSV21 tokens
64
93
  */
65
94
  export function registerMarketListingsTool(server: McpServer): void {
66
95
  server.tool(
@@ -84,25 +113,68 @@ export function registerMarketListingsTool(server: McpServer): void {
84
113
  num,
85
114
  minPrice,
86
115
  maxPrice,
116
+ tokenType,
117
+ bsv20Type,
118
+ id,
119
+ tick,
120
+ pending,
87
121
  } = args;
88
122
 
123
+ // Determine the API endpoint based on tokenType
124
+ let baseUrl = "https://ordinals.gorillapool.io/api";
125
+ let useTokenParams = false;
126
+
127
+ if (tokenType === "bsv20") {
128
+ baseUrl += "/bsv20/market";
129
+ useTokenParams = true;
130
+ } else if (tokenType === "bsv21") {
131
+ baseUrl += "/bsv21/market"; // Assuming BSV21 endpoint follows similar pattern
132
+ useTokenParams = true;
133
+ } else if (tokenType === "nft" || tokenType === "all") {
134
+ baseUrl += "/market";
135
+ }
136
+
89
137
  // Build the URL with query parameters
90
- const url = new URL("https://ordinals.gorillapool.io/api/market");
138
+ const url = new URL(baseUrl);
91
139
  url.searchParams.append("limit", limit.toString());
92
140
  url.searchParams.append("offset", offset.toString());
93
- url.searchParams.append("sort", sort);
94
141
  url.searchParams.append("dir", dir);
95
-
142
+
143
+ // Add sort parameter based on token type
144
+ if (useTokenParams) {
145
+ // BSV20/BSV21 specific sort options
146
+ if (sort === "height" || sort === "price" || sort === "price_per_token") {
147
+ url.searchParams.append("sort", sort);
148
+ }
149
+ // Add token-specific parameters
150
+ if (bsv20Type && bsv20Type !== "all") {
151
+ url.searchParams.append("type", bsv20Type);
152
+ }
153
+ if (id) url.searchParams.append("id", id);
154
+ if (tick) url.searchParams.append("tick", tick);
155
+ if (pending !== undefined) url.searchParams.append("pending", pending.toString());
156
+ // For BSV20/21, min/max price parameters have slightly different names
157
+ if (minPrice !== undefined) url.searchParams.append("min_price", minPrice.toString());
158
+ if (maxPrice !== undefined) url.searchParams.append("max_price", maxPrice.toString());
159
+ } else {
160
+ // NFT specific sort options
161
+ if (sort === "recent" || sort === "price" || sort === "num") {
162
+ url.searchParams.append("sort", sort);
163
+ }
164
+ // Add NFT-specific parameters
165
+ if (origin) url.searchParams.append("origin", origin);
166
+ if (mime) url.searchParams.append("mime", mime);
167
+ if (num) url.searchParams.append("num", num);
168
+ // For NFTs, min/max price parameters use short names
169
+ if (minPrice !== undefined) url.searchParams.append("min", minPrice.toString());
170
+ if (maxPrice !== undefined) url.searchParams.append("max", maxPrice.toString());
171
+ }
172
+
173
+ // Add common parameters
96
174
  if (address) url.searchParams.append("address", address);
97
- if (origin) url.searchParams.append("origin", origin);
98
- if (mime) url.searchParams.append("mime", mime);
99
- if (num) url.searchParams.append("num", num);
100
- if (minPrice !== undefined)
101
- url.searchParams.append("min", minPrice.toString());
102
- if (maxPrice !== undefined)
103
- url.searchParams.append("max", maxPrice.toString());
104
175
 
105
- // Fetch market listings from GorillaPool API
176
+ // Make the fetch request
177
+ console.log(`Fetching market listings from: ${url.toString()}`);
106
178
  const response = await fetch(url.toString());
107
179
 
108
180
  if (!response.ok) {
@@ -2,8 +2,9 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
3
  import { z } from "zod";
4
4
 
5
- // Schema for BSV20 market sales arguments
6
- export const bsv20MarketSalesArgsSchema = z.object({
5
+ // Schema for unified market sales arguments
6
+ export const marketSalesArgsSchema = z.object({
7
+ // Common parameters
7
8
  limit: z
8
9
  .number()
9
10
  .int()
@@ -16,20 +17,27 @@ export const bsv20MarketSalesArgsSchema = z.object({
16
17
  .enum(["asc", "desc"])
17
18
  .default("desc")
18
19
  .describe("Sort direction (asc or desc)"),
19
- type: z
20
+ address: z.string().optional().describe("Bitcoin address"),
21
+
22
+ // Token-specific parameters
23
+ tokenType: z
24
+ .enum(["bsv20", "bsv21", "all"])
25
+ .default("bsv20")
26
+ .describe("Type of token to search for (bsv20, bsv21, or all)"),
27
+ bsv20Type: z
20
28
  .enum(["v1", "v2", "all"])
21
29
  .default("all")
22
- .describe("Token type (v1, v2, or all)"),
30
+ .optional()
31
+ .describe("BSV20 token type (v1, v2, or all)"),
23
32
  id: z.string().optional().describe("Token ID in outpoint format"),
24
33
  tick: z.string().optional().describe("Token ticker symbol"),
25
- pending: z.boolean().default(false).describe("Include pending sales"),
26
- address: z.string().optional().describe("Bitcoin address"),
34
+ pending: z.boolean().default(false).optional().describe("Include pending sales"),
27
35
  });
28
36
 
29
- export type Bsv20MarketSalesArgs = z.infer<typeof bsv20MarketSalesArgsSchema>;
37
+ export type MarketSalesArgs = z.infer<typeof marketSalesArgsSchema>;
30
38
 
31
- // Simplified BSV20 sale response type
32
- interface Bsv20SaleResponse {
39
+ // Unified response type for token sales
40
+ interface MarketSaleResponse {
33
41
  results: Array<{
34
42
  outpoint: string;
35
43
  data?: {
@@ -48,42 +56,70 @@ interface Bsv20SaleResponse {
48
56
  };
49
57
  satoshis?: number;
50
58
  height?: number;
59
+ owner?: string;
60
+ spend?: string;
61
+ spendHeight?: number;
62
+ spendIdx?: string;
51
63
  [key: string]: unknown;
52
64
  }>;
53
65
  total: number;
54
66
  }
55
67
 
56
68
  /**
57
- * Register the BSV20 market sales tool
69
+ * Register the unified market sales tool
70
+ * Handles BSV20 and BSV21 token sales
58
71
  */
59
- export function registerBsv20MarketSalesTool(server: McpServer): void {
72
+ export function registerMarketSalesTool(server: McpServer): void {
60
73
  server.tool(
61
- "ordinals_bsv20MarketSales",
74
+ "ordinals_marketSales",
62
75
  {
63
- args: bsv20MarketSalesArgsSchema,
76
+ args: marketSalesArgsSchema,
64
77
  },
65
78
  async (
66
- { args }: { args: Bsv20MarketSalesArgs },
79
+ { args }: { args: MarketSalesArgs },
67
80
  extra: RequestHandlerExtra,
68
81
  ) => {
69
82
  try {
70
- const { limit, offset, dir, type, id, tick, pending, address } = args;
83
+ const {
84
+ limit,
85
+ offset,
86
+ dir,
87
+ tokenType,
88
+ bsv20Type,
89
+ id,
90
+ tick,
91
+ pending,
92
+ address
93
+ } = args;
94
+
95
+ // Determine the API endpoint based on tokenType
96
+ let baseUrl = "https://ordinals.gorillapool.io/api";
97
+
98
+ if (tokenType === "bsv21") {
99
+ baseUrl += "/bsv21/market/sales";
100
+ } else {
101
+ // Default to BSV20 for "bsv20" or "all"
102
+ baseUrl += "/bsv20/market/sales";
103
+ }
71
104
 
72
105
  // Build the URL with query parameters
73
- const url = new URL(
74
- "https://ordinals.gorillapool.io/api/bsv20/market/sales",
75
- );
106
+ const url = new URL(baseUrl);
76
107
  url.searchParams.append("limit", limit.toString());
77
108
  url.searchParams.append("offset", offset.toString());
78
109
  url.searchParams.append("dir", dir);
79
- url.searchParams.append("type", type);
80
- url.searchParams.append("pending", pending.toString());
110
+
111
+ // Add type parameter for bsv20 only if specified
112
+ if (bsv20Type && bsv20Type !== "all") {
113
+ url.searchParams.append("type", bsv20Type);
114
+ }
81
115
 
82
116
  if (id) url.searchParams.append("id", id);
83
117
  if (tick) url.searchParams.append("tick", tick);
118
+ if (pending !== undefined) url.searchParams.append("pending", pending.toString());
84
119
  if (address) url.searchParams.append("address", address);
85
120
 
86
- // Fetch BSV20 market sales from GorillaPool API
121
+ // Fetch market sales from GorillaPool API
122
+ console.log(`Fetching market sales from: ${url.toString()}`);
87
123
  const response = await fetch(url.toString());
88
124
 
89
125
  if (!response.ok) {
@@ -92,7 +128,7 @@ export function registerBsv20MarketSalesTool(server: McpServer): void {
92
128
  );
93
129
  }
94
130
 
95
- const data = (await response.json()) as Bsv20SaleResponse;
131
+ const data = (await response.json()) as MarketSaleResponse;
96
132
 
97
133
  return {
98
134
  content: [
@@ -0,0 +1,117 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4
+ import { createOrdinals } from "js-1sat-ord";
5
+ import type {
6
+ ChangeResult,
7
+ Destination,
8
+ Inscription,
9
+ PreMAP,
10
+ CreateOrdinalsCollectionMetadata,
11
+ CreateOrdinalsCollectionItemMetadata
12
+ } from "js-1sat-ord";
13
+ import { z } from "zod";
14
+ import type { Wallet } from "./wallet";
15
+
16
+ /**
17
+ * Schema for the createOrdinals tool arguments.
18
+ * This is a simplified interface compared to the full CreateOrdinalsConfig
19
+ * in js-1sat-ord. The wallet will provide UTXOs, private key, etc.
20
+ */
21
+ export const createOrdinalsArgsSchema = z.object({
22
+ // Base64-encoded data to inscribe
23
+ dataB64: z.string().describe("Base64-encoded content to inscribe"),
24
+ // Content type (e.g., "image/jpeg", "text/plain", etc.)
25
+ contentType: z.string().describe("MIME type of the content"),
26
+ // Optional destination address (if not provided, uses the wallet's address)
27
+ destinationAddress: z.string().optional().describe("Optional destination address for the ordinal"),
28
+ // Optional metadata for the inscription
29
+ metadata: z.any().optional().describe("Optional MAP metadata for the inscription")
30
+ });
31
+
32
+ export type CreateOrdinalsArgs = z.infer<typeof createOrdinalsArgsSchema>;
33
+
34
+ /**
35
+ * Registers the wallet_createOrdinals tool for minting ordinals/inscriptions
36
+ */
37
+ export function registerCreateOrdinalsTool(server: McpServer, wallet: Wallet) {
38
+ server.tool(
39
+ "wallet_createOrdinals",
40
+ { args: createOrdinalsArgsSchema },
41
+ async (
42
+ { args }: { args: CreateOrdinalsArgs },
43
+ extra: RequestHandlerExtra,
44
+ ): Promise<CallToolResult> => {
45
+ try {
46
+ // 1. Get private key from wallet
47
+ const paymentPk = wallet.getPrivateKey();
48
+ if (!paymentPk) {
49
+ throw new Error("No private key available in wallet");
50
+ }
51
+
52
+ // 2. Get payment UTXOs from wallet
53
+ const { paymentUtxos } = await wallet.getUtxos();
54
+ if (!paymentUtxos || paymentUtxos.length === 0) {
55
+ throw new Error("No payment UTXOs available to fund this inscription");
56
+ }
57
+
58
+ // 3. Get the wallet address for change/destination if not provided
59
+ const walletAddress = paymentPk.toAddress().toString();
60
+
61
+ // 4. Create the inscription object
62
+ const inscription: Inscription = {
63
+ dataB64: args.dataB64,
64
+ contentType: args.contentType,
65
+ };
66
+
67
+ // 5. Create the destination
68
+ const destinations: Destination[] = [
69
+ {
70
+ address: args.destinationAddress || walletAddress,
71
+ inscription,
72
+ },
73
+ ];
74
+
75
+ // 6. Create and broadcast the transaction
76
+ const result = await createOrdinals({
77
+ utxos: paymentUtxos,
78
+ destinations,
79
+ paymentPk,
80
+ changeAddress: walletAddress,
81
+ metaData: args.metadata as PreMAP | CreateOrdinalsCollectionMetadata | CreateOrdinalsCollectionItemMetadata,
82
+ });
83
+
84
+ const changeResult = result as ChangeResult;
85
+
86
+ // 7. Broadcast the transaction
87
+ await changeResult.tx.broadcast();
88
+
89
+ // 8. Refresh the wallet's UTXOs after spending
90
+ try {
91
+ await wallet.refreshUtxos();
92
+ } catch (refreshError) {
93
+ console.warn("Failed to refresh UTXOs after transaction:", refreshError);
94
+ }
95
+
96
+ // 9. Return transaction details
97
+ return {
98
+ content: [
99
+ {
100
+ type: "text",
101
+ text: JSON.stringify({
102
+ txid: changeResult.tx.id("hex"),
103
+ spentOutpoints: changeResult.spentOutpoints,
104
+ payChange: changeResult.payChange,
105
+ inscriptionAddress: args.destinationAddress || walletAddress,
106
+ contentType: args.contentType,
107
+ }),
108
+ },
109
+ ],
110
+ };
111
+ } catch (err: unknown) {
112
+ const msg = err instanceof Error ? err.message : String(err);
113
+ return { content: [{ type: "text", text: msg }], isError: true };
114
+ }
115
+ },
116
+ );
117
+ }
@@ -1,13 +1,24 @@
1
- import { PrivateKey } from "@bsv/sdk";
1
+ // import { PrivateKey } from "@bsv/sdk"; // not used here
2
2
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
4
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4
5
  import {
6
+ type ChangeResult,
5
7
  type ExistingListing,
8
+ type Payment,
9
+ type TokenUtxo,
6
10
  type Utxo,
11
+ TokenType,
7
12
  oneSatBroadcaster,
8
13
  purchaseOrdListing,
14
+ purchaseOrdTokenListing,
9
15
  } from "js-1sat-ord";
10
16
  import type { z } from "zod";
17
+ import {
18
+ MARKET_FEE_PERCENTAGE,
19
+ MARKET_WALLET_ADDRESS,
20
+ MINIMUM_MARKET_FEE_SATOSHIS,
21
+ } from "../constants";
11
22
  import { purchaseListingArgsSchema } from "./schemas";
12
23
  import type { Wallet } from "./wallet";
13
24
 
@@ -22,6 +33,11 @@ interface ListingResponse {
22
33
  price: number;
23
34
  payout: string;
24
35
  };
36
+ bsv20?: {
37
+ amt?: string;
38
+ tick?: string;
39
+ id?: string;
40
+ };
25
41
  };
26
42
  }
27
43
 
@@ -32,7 +48,7 @@ interface ListingResponse {
32
48
  * 1. Parses the listing outpoint to get the txid and vout
33
49
  * 2. Fetches the listing UTXO from the ordinals API
34
50
  * 3. Gets the wallet's payment UTXOs (using the wallet's internal UTXO management)
35
- * 4. Uses purchaseOrdListing to create a purchase transaction
51
+ * 4. Uses purchaseOrdListing or purchaseOrdTokenListing based on the listing type
36
52
  * 5. Broadcasts the transaction
37
53
  * 6. Returns the transaction details
38
54
  */
@@ -46,9 +62,10 @@ export function registerPurchaseListingTool(server: McpServer, wallet: Wallet) {
46
62
  async (
47
63
  { args }: { args: z.infer<typeof purchaseListingArgsSchema> },
48
64
  extra: RequestHandlerExtra,
49
- ) => {
65
+ ): Promise<CallToolResult> => {
50
66
  try {
51
67
  console.log(`Attempting to purchase listing: ${args.listingOutpoint}`);
68
+ console.log(`Listing type: ${args.listingType}`);
52
69
  console.log("Using wallet instance:", wallet);
53
70
  console.log("Wallet has UTXOs:", await wallet.getUtxos());
54
71
 
@@ -74,6 +91,20 @@ export function registerPurchaseListingTool(server: McpServer, wallet: Wallet) {
74
91
  throw new Error("Listing doesn't have payout information");
75
92
  }
76
93
 
94
+ // Calculate the market fee (3% of listing price)
95
+ const listingPrice = listingData.data.list.price;
96
+ let marketFee = Math.round(listingPrice * MARKET_FEE_PERCENTAGE);
97
+
98
+ // Ensure minimum fee
99
+ if (marketFee < MINIMUM_MARKET_FEE_SATOSHIS) {
100
+ marketFee = MINIMUM_MARKET_FEE_SATOSHIS;
101
+ }
102
+
103
+ console.log(`Listing price: ${listingPrice} satoshis`);
104
+ console.log(
105
+ `Market fee: ${marketFee} satoshis (${MARKET_FEE_PERCENTAGE * 100}%)`,
106
+ );
107
+
77
108
  // Parse the listing outpoint to get txid and vout
78
109
  const [txid, voutStr] = args.listingOutpoint.split("_");
79
110
  if (!txid) {
@@ -81,20 +112,6 @@ export function registerPurchaseListingTool(server: McpServer, wallet: Wallet) {
81
112
  }
82
113
  const vout = Number.parseInt(voutStr || "0", 10);
83
114
 
84
- // Create listing UTXO object in the format required by js-1sat-ord
85
- const listingUtxo: Utxo = {
86
- txid,
87
- vout,
88
- script: listingData.script,
89
- satoshis: listingData.satoshis,
90
- };
91
-
92
- // Create the ExistingListing object
93
- const listing: ExistingListing = {
94
- payout: listingData.data.list.payout,
95
- listingUtxo,
96
- };
97
-
98
115
  // Get private key from the wallet
99
116
  const paymentPk = wallet.getPrivateKey();
100
117
  if (!paymentPk) {
@@ -112,17 +129,96 @@ export function registerPurchaseListingTool(server: McpServer, wallet: Wallet) {
112
129
  throw new Error(
113
130
  `No payment UTXOs available for address ${paymentAddress}.
114
131
  Please fund this wallet address with enough BSV to cover the purchase price
115
- (${listingData.data.list.price} satoshis) plus transaction fees.`,
132
+ (${listingData.data.list.price} satoshis) plus market fee (${marketFee} satoshis) and transaction fees.`,
116
133
  );
117
134
  }
118
135
 
119
- // Create the purchase transaction using the library's config type
120
- const transaction = await purchaseOrdListing({
121
- utxos: paymentUtxos,
122
- paymentPk,
123
- ordAddress: args.ordAddress,
124
- listing,
125
- });
136
+ // Define market fee payment
137
+ const additionalPayments: Payment[] = [
138
+ {
139
+ to: MARKET_WALLET_ADDRESS,
140
+ amount: marketFee,
141
+ },
142
+ ];
143
+
144
+ // Define metadata for the transaction
145
+ const metaData = {
146
+ app: "bsv-mcp",
147
+ type: "ord",
148
+ op: "purchase",
149
+ };
150
+
151
+ // Create the purchase transaction based on listing type
152
+ let transaction: ChangeResult;
153
+
154
+ if (args.listingType === "token") {
155
+ if (!args.tokenProtocol) {
156
+ throw new Error("tokenProtocol is required for token listings");
157
+ }
158
+
159
+ if (!args.tokenID) {
160
+ throw new Error("tokenID is required for token listings");
161
+ }
162
+
163
+ // Validate token data from the listing
164
+ if (!listingData.data.bsv20) {
165
+ throw new Error("This is not a valid BSV-20 token listing");
166
+ }
167
+
168
+ // For BSV-20, the amount should be included in the listing data
169
+ if (!listingData.data.bsv20.amt) {
170
+ throw new Error("Token listing doesn't have an amount specified");
171
+ }
172
+
173
+ // Convert the token protocol to the enum type expected by js-1sat-ord
174
+ const protocol = args.tokenProtocol === "bsv-20"
175
+ ? TokenType.BSV20
176
+ : TokenType.BSV21;
177
+
178
+ // Create a TokenUtxo with the required fields
179
+ const listingUtxo: TokenUtxo = {
180
+ txid,
181
+ vout,
182
+ script: listingData.script,
183
+ satoshis: 1, // TokenUtxo's satoshis must be exactly 1
184
+ amt: listingData.data.bsv20.amt,
185
+ id: args.tokenID,
186
+ };
187
+
188
+ transaction = await purchaseOrdTokenListing({
189
+ protocol,
190
+ tokenID: args.tokenID,
191
+ utxos: paymentUtxos,
192
+ paymentPk,
193
+ listingUtxo,
194
+ ordAddress: args.ordAddress,
195
+ additionalPayments,
196
+ metaData,
197
+ });
198
+ } else {
199
+ // Create a regular Utxo for NFT listing
200
+ const listingUtxo: Utxo = {
201
+ txid,
202
+ vout,
203
+ script: listingData.script,
204
+ satoshis: listingData.satoshis,
205
+ };
206
+
207
+ // Create the ExistingListing object for NFT listings
208
+ const listing: ExistingListing = {
209
+ payout: listingData.data.list.payout,
210
+ listingUtxo,
211
+ };
212
+
213
+ transaction = await purchaseOrdListing({
214
+ utxos: paymentUtxos,
215
+ paymentPk,
216
+ ordAddress: args.ordAddress,
217
+ listing,
218
+ additionalPayments,
219
+ metaData,
220
+ });
221
+ }
126
222
 
127
223
  // After successful transaction creation, refresh the wallet's UTXOs
128
224
  // This ensures the wallet doesn't try to reuse spent UTXOs
@@ -161,7 +257,12 @@ Please fund this wallet address with enough BSV to cover the purchase price
161
257
  txid: transaction.tx.id("hex"),
162
258
  listingOutpoint: args.listingOutpoint,
163
259
  destinationAddress: args.ordAddress,
260
+ listingType: args.listingType,
261
+ tokenProtocol: args.tokenID ? args.tokenProtocol : undefined,
262
+ tokenID: args.tokenID,
164
263
  price: listingData.data.list.price,
264
+ marketFee,
265
+ marketFeeAddress: MARKET_WALLET_ADDRESS,
165
266
  }),
166
267
  },
167
268
  ],
@@ -279,6 +279,18 @@ export const purchaseListingArgsSchema = z.object({
279
279
  .string()
280
280
  .optional()
281
281
  .describe("Optional description for the transaction"),
282
+ listingType: z
283
+ .enum(["nft", "token"])
284
+ .default("nft")
285
+ .describe("Type of listing: 'nft' for ordinal NFTs, 'token' for BSV-20 tokens"),
286
+ tokenProtocol: z
287
+ .enum(["bsv-20", "bsv-21"])
288
+ .optional()
289
+ .describe("Token protocol for token listings (required when listingType is 'token')"),
290
+ tokenID: z
291
+ .string()
292
+ .optional()
293
+ .describe("Token ID for BSV-21 tokens or ticker for BSV-20 tokens (required when listingType is 'token')"),
282
294
  });
283
295
 
284
296
  export type PurchaseListingArgs = z.infer<typeof purchaseListingArgsSchema>;
@@ -0,0 +1,119 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4
+ import { sendOrdinals } from "js-1sat-ord";
5
+ import type { ChangeResult, SendOrdinalsConfig } from "js-1sat-ord";
6
+ import { z } from "zod";
7
+ import type { Wallet } from "./wallet";
8
+
9
+ /**
10
+ * Schema for the sendOrdinals tool arguments
11
+ */
12
+ export const sendOrdinalsArgsSchema = z.object({
13
+ // Outpoint of the inscription to send (txid_vout format)
14
+ inscriptionOutpoint: z.string().describe("Inscription outpoint in format txid_vout"),
15
+ // Destination address to send the inscription to
16
+ destinationAddress: z.string().describe("Destination address for the inscription"),
17
+ // Optional metadata for the ordinal transfer
18
+ metadata: z.any().optional().describe("Optional MAP metadata for the transfer"),
19
+ });
20
+
21
+ export type SendOrdinalsArgs = z.infer<typeof sendOrdinalsArgsSchema>;
22
+
23
+ /**
24
+ * Registers the wallet_sendOrdinals tool for transferring ordinals
25
+ */
26
+ export function registerSendOrdinalsTool(server: McpServer, wallet: Wallet) {
27
+ server.tool(
28
+ "wallet_sendOrdinals",
29
+ { args: sendOrdinalsArgsSchema },
30
+ async (
31
+ { args }: { args: SendOrdinalsArgs },
32
+ extra: RequestHandlerExtra,
33
+ ): Promise<CallToolResult> => {
34
+ try {
35
+ // 1. Get private key from wallet
36
+ const paymentPk = wallet.getPrivateKey();
37
+ if (!paymentPk) {
38
+ throw new Error("No private key available in wallet");
39
+ }
40
+
41
+ // 2. Get payment UTXOs from wallet
42
+ const { paymentUtxos, nftUtxos } = await wallet.getUtxos();
43
+ if (!paymentUtxos || paymentUtxos.length === 0) {
44
+ throw new Error("No payment UTXOs available to fund this transaction");
45
+ }
46
+
47
+ // 3. Get the wallet address for change
48
+ const walletAddress = paymentPk.toAddress().toString();
49
+
50
+ // 4. Parse the inscription outpoint
51
+ const [txid, voutStr] = args.inscriptionOutpoint.split('_');
52
+ if (!txid || !voutStr) {
53
+ throw new Error("Invalid inscription outpoint format. Expected txid_vout");
54
+ }
55
+ const vout = Number.parseInt(voutStr, 10);
56
+
57
+ // 5. Find the inscription in nftUtxos
58
+ const inscription = nftUtxos.find(
59
+ (utxo) => utxo.txid === txid && utxo.vout === vout
60
+ );
61
+
62
+ if (!inscription) {
63
+ throw new Error(
64
+ `Inscription ${args.inscriptionOutpoint} not found in your wallet`
65
+ );
66
+ }
67
+
68
+ // 6. Create config and transfer the inscription
69
+ const sendOrdinalsConfig: SendOrdinalsConfig = {
70
+ paymentPk,
71
+ paymentUtxos,
72
+ ordinals: [inscription],
73
+ destinations: [{ address: args.destinationAddress }],
74
+ changeAddress: walletAddress,
75
+ };
76
+
77
+ // Add metadata if provided
78
+ if (args.metadata) {
79
+ sendOrdinalsConfig.metaData = args.metadata;
80
+ }
81
+
82
+ // Using the wallet's key for both payment and ordinals
83
+ sendOrdinalsConfig.ordPk = paymentPk;
84
+
85
+ const result = await sendOrdinals(sendOrdinalsConfig);
86
+ const changeResult = result as ChangeResult;
87
+
88
+ // 7. Broadcast the transaction
89
+ await changeResult.tx.broadcast();
90
+
91
+ // 8. Refresh the wallet's UTXOs after spending
92
+ try {
93
+ await wallet.refreshUtxos();
94
+ } catch (refreshError) {
95
+ console.warn("Failed to refresh UTXOs after transaction:", refreshError);
96
+ }
97
+
98
+ // 9. Return transaction details
99
+ return {
100
+ content: [
101
+ {
102
+ type: "text",
103
+ text: JSON.stringify({
104
+ txid: changeResult.tx.id("hex"),
105
+ spentOutpoints: changeResult.spentOutpoints,
106
+ payChange: changeResult.payChange,
107
+ inscriptionOutpoint: args.inscriptionOutpoint,
108
+ destinationAddress: args.destinationAddress,
109
+ }),
110
+ },
111
+ ],
112
+ };
113
+ } catch (err: unknown) {
114
+ const msg = err instanceof Error ? err.message : String(err);
115
+ return { content: [{ type: "text", text: msg }], isError: true };
116
+ }
117
+ },
118
+ );
119
+ }
@@ -1,6 +1,7 @@
1
1
  import { P2PKH } from "@bsv/sdk";
2
2
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
4
+ import { toSatoshi } from "satoshi-token";
4
5
  import type { z } from "zod";
5
6
  import { sendToAddressArgsSchema } from "./schemas";
6
7
  import type { Wallet } from "./wallet";
@@ -56,17 +57,20 @@ export function registerSendToAddressTool(server: McpServer, wallet: Wallet) {
56
57
  description = "Send to address",
57
58
  } = args;
58
59
 
59
- // Convert USD to satoshis if needed
60
- let satoshis = amount;
60
+ // Convert to satoshis
61
+ let satoshis: number;
61
62
  if (currency === "USD") {
62
63
  // Get current BSV price
63
64
  const bsvPriceUsd = await getBsvPrice();
64
65
 
65
- // Convert USD to BSV, then to satoshis
66
- satoshis = Math.floor((amount / bsvPriceUsd) * 100000000);
66
+ // Convert USD to BSV
67
+ const bsvAmount = amount / bsvPriceUsd;
68
+
69
+ // Convert BSV to satoshis using the library
70
+ satoshis = toSatoshi(bsvAmount);
67
71
  } else {
68
- // Convert BSV to satoshis
69
- satoshis = Math.floor(amount * 100000000);
72
+ // Convert BSV to satoshis using the library
73
+ satoshis = toSatoshi(amount);
70
74
  }
71
75
 
72
76
  // Create P2PKH script from address
@@ -1,45 +1,46 @@
1
- import type {
2
- McpServer,
3
- ToolCallback,
4
- } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
5
3
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
6
4
  import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
7
5
  import type { z } from "zod";
8
- import { convertData } from "../utils/conversion";
9
- import { registerGetAddressTool } from "./getAddress";
10
- import { registerPurchaseListingTool } from "./purchaseListing";
11
- import {
12
- createSignatureArgsSchema,
13
- type emptyArgsSchema,
14
- getPublicKeyArgsSchema,
15
- verifySignatureArgsSchema,
16
- walletDecryptArgsSchema,
17
- walletEncryptArgsSchema,
18
- } from "./schemas";
19
6
  import type {
20
7
  abortActionArgsSchema,
21
8
  acquireCertificateArgsSchema,
22
9
  createHmacArgsSchema,
23
10
  discoverByAttributesArgsSchema,
24
11
  discoverByIdentityKeyArgsSchema,
25
- getAddressArgsSchema,
26
12
  getHeaderArgsSchema,
27
13
  internalizeActionArgsSchema,
28
14
  listActionsArgsSchema,
29
15
  listCertificatesArgsSchema,
30
16
  listOutputsArgsSchema,
31
17
  proveCertificateArgsSchema,
32
- purchaseListingArgsSchema,
33
18
  relinquishCertificateArgsSchema,
34
19
  relinquishOutputArgsSchema,
35
20
  revealCounterpartyKeyLinkageArgsSchema,
36
21
  revealSpecificKeyLinkageArgsSchema,
37
- sendToAddressArgsSchema,
38
22
  verifyHmacArgsSchema,
39
23
  } from "./schemas";
40
- import { registerSendToAddressTool } from "./sendToAddress";
41
24
  import type { Wallet } from "./wallet";
42
25
 
26
+ import {
27
+ createSignatureArgsSchema,
28
+ type emptyArgsSchema,
29
+ type getAddressArgsSchema,
30
+ getPublicKeyArgsSchema,
31
+ type purchaseListingArgsSchema,
32
+ type sendToAddressArgsSchema,
33
+ verifySignatureArgsSchema,
34
+ walletDecryptArgsSchema,
35
+ walletEncryptArgsSchema,
36
+ } from "./schemas";
37
+
38
+ import { registerCreateOrdinalsTool } from "./createOrdinals";
39
+ import type { createOrdinalsArgsSchema } from "./createOrdinals";
40
+ import { registerGetAddressTool } from "./getAddress";
41
+ import { registerPurchaseListingTool } from "./purchaseListing";
42
+ import { registerSendToAddressTool } from "./sendToAddress";
43
+
43
44
  // Define mapping from tool names to argument schemas
44
45
  type ToolArgSchemas = {
45
46
  wallet_getPublicKey: typeof getPublicKeyArgsSchema;
@@ -70,6 +71,7 @@ type ToolArgSchemas = {
70
71
  wallet_getAddress: typeof getAddressArgsSchema;
71
72
  wallet_sendToAddress: typeof sendToAddressArgsSchema;
72
73
  wallet_purchaseListing: typeof purchaseListingArgsSchema;
74
+ wallet_createOrdinals: typeof createOrdinalsArgsSchema;
73
75
  };
74
76
 
75
77
  // Define a type for the handler function with proper argument types
@@ -202,5 +204,9 @@ export function registerWalletTools(
202
204
  },
203
205
  );
204
206
 
207
+ // Register ordinals extension tools
208
+ // Register the wallet_createOrdinals tool
209
+ registerCreateOrdinalsTool(server, wallet);
210
+
205
211
  return handlers;
206
212
  }
@@ -10,7 +10,6 @@ import {
10
10
  PrivateKey,
11
11
  ProtoWallet,
12
12
  Transaction,
13
- Utils,
14
13
  } from "@bsv/sdk";
15
14
  import type {
16
15
  AbortActionArgs,
@@ -19,10 +18,6 @@ import type {
19
18
  AuthenticatedResult,
20
19
  CreateActionArgs,
21
20
  CreateActionResult,
22
- CreateHmacArgs,
23
- CreateHmacResult,
24
- CreateSignatureArgs,
25
- CreateSignatureResult,
26
21
  DiscoverByAttributesArgs,
27
22
  DiscoverByIdentityKeyArgs,
28
23
  DiscoverCertificatesResult,
@@ -53,15 +48,7 @@ import type {
53
48
  RevealSpecificKeyLinkageResult,
54
49
  SignActionArgs,
55
50
  SignActionResult,
56
- VerifyHmacArgs,
57
- VerifyHmacResult,
58
- VerifySignatureArgs,
59
- VerifySignatureResult,
60
51
  WalletCertificate,
61
- WalletDecryptArgs,
62
- WalletDecryptResult,
63
- WalletEncryptArgs,
64
- WalletEncryptResult,
65
52
  WalletInterface,
66
53
  } from "@bsv/sdk";
67
54
  import {
@@ -152,28 +139,29 @@ export class Wallet extends ProtoWallet implements WalletInterface {
152
139
  ): Promise<RevealSpecificKeyLinkageResult> {
153
140
  return Promise.reject(new Error("Not implemented"));
154
141
  }
155
- async encrypt(args: WalletEncryptArgs): Promise<WalletEncryptResult> {
156
- return Promise.reject(new Error("Not implemented"));
157
- }
158
- async decrypt(args: WalletDecryptArgs): Promise<WalletDecryptResult> {
159
- return Promise.reject(new Error("Not implemented"));
160
- }
161
- async createHmac(args: CreateHmacArgs): Promise<CreateHmacResult> {
162
- return Promise.reject(new Error("Not implemented"));
163
- }
164
- async verifyHmac(args: VerifyHmacArgs): Promise<VerifyHmacResult> {
165
- return Promise.reject(new Error("Not implemented"));
166
- }
167
- async createSignature(
168
- args: CreateSignatureArgs,
169
- ): Promise<CreateSignatureResult> {
170
- return Promise.reject(new Error("Not implemented"));
171
- }
172
- async verifySignature(
173
- args: VerifySignatureArgs,
174
- ): Promise<VerifySignatureResult> {
175
- return Promise.reject(new Error("Not implemented"));
176
- }
142
+ // Implemented by ProtoWallet
143
+ // async encrypt(args: WalletEncryptArgs): Promise<WalletEncryptResult> {
144
+ // return this.encrypt(args);
145
+ // }
146
+ // async decrypt(args: WalletDecryptArgs): Promise<WalletDecryptResult> {
147
+ // return this.decrypt(args);
148
+ // }
149
+ // async createHmac(args: CreateHmacArgs): Promise<CreateHmacResult> {
150
+ // return this.createHmac(args);
151
+ // }
152
+ // async verifyHmac(args: VerifyHmacArgs): Promise<VerifyHmacResult> {
153
+ // return this.verifyHmac(args);
154
+ // }
155
+ // async createSignature(
156
+ // args: CreateSignatureArgs,
157
+ // ): Promise<CreateSignatureResult> {
158
+ // return Promise.reject(new Error("Not implemented"));
159
+ // }
160
+ // async verifySignature(
161
+ // args: VerifySignatureArgs,
162
+ // ): Promise<VerifySignatureResult> {
163
+ // return Promise.reject(new Error("Not implemented"));
164
+ // }
177
165
  async createAction(args: CreateActionArgs): Promise<CreateActionResult> {
178
166
  console.log("createAction called with", args);
179
167