bsv-mcp 0.0.36 → 0.2.7
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/CHANGELOG.md +124 -0
- package/README.md +233 -4
- package/dist/index.js +120082 -54669
- package/index.ts +1196 -88
- package/next-env.d.ts +6 -0
- package/package.json +58 -15
- package/prompts/bsvSdk/index.ts +5 -5
- package/prompts/bsvSdk/transaction.ts +2 -2
- package/prompts/bsvSdk/wallet.ts +1 -1
- package/prompts/index.ts +1 -1
- package/resources/bitcom.ts +132 -0
- package/resources/resources.ts +7 -3
- package/smithery.yaml +3 -0
- package/test-mcp-server.ts +157 -0
- package/tools/a2b/discover.ts +13 -13
- package/tools/bap/friend.ts +266 -0
- package/tools/bap/generate.test.ts +350 -0
- package/tools/bap/generate.ts +431 -0
- package/tools/bap/getCurrentAddress.ts +69 -0
- package/tools/bap/getId.test.ts +121 -0
- package/tools/bap/getId.ts +169 -0
- package/tools/bap/index.ts +111 -0
- package/tools/bap/types.ts +66 -0
- package/tools/bap/utils.ts +33 -0
- package/tools/bsocial/bmapFollow.ts +121 -0
- package/tools/bsocial/bmapLikes.ts +111 -0
- package/tools/bsocial/bmapReadPosts.ts +148 -0
- package/tools/bsocial/createPost.ts +136 -0
- package/tools/bsocial/index.ts +45 -0
- package/tools/bsocial/readPosts.ts +255 -0
- package/tools/bsv/decodeTransaction.ts +7 -6
- package/tools/bsv/explore.ts +2 -3
- package/tools/bsv/getPrice.ts +1 -9
- package/tools/bsv/token.ts +14 -26
- package/tools/constants.ts +21 -0
- package/tools/index.ts +91 -18
- package/tools/mnee/getBalance.ts +2 -4
- package/tools/mnee/index.ts +8 -0
- package/tools/mnee/parseTx.ts +4 -4
- package/tools/mnee/sendMnee.ts +6 -6
- package/tools/ordinals/getInscription.ts +2 -3
- package/tools/ordinals/getTokenByIdOrTicker.ts +6 -3
- package/tools/ordinals/marketListings.ts +2 -18
- package/tools/ordinals/marketSales.ts +2 -4
- package/tools/ordinals/searchInscriptions.ts +2 -4
- package/tools/utils/aip.ts +46 -0
- package/tools/utils/conversion.ts +1 -0
- package/tools/utils/errorHandler.ts +76 -0
- package/tools/utils/index.ts +56 -14
- package/tools/utils/installAgentMaster.ts +84 -0
- package/tools/utils/logger.ts +20 -0
- package/tools/utils/toolConfig.ts +80 -0
- package/tools/utils/toolRegistration.ts +66 -0
- package/tools/utils/transactionBuilder.ts +196 -0
- package/tools/wallet/a2bPublishAgent.ts +25 -30
- package/tools/wallet/a2bPublishMcp.ts +43 -44
- package/tools/wallet/createOrdinals.ts +13 -20
- package/tools/wallet/fetchPaymentUtxos.ts +48 -39
- package/tools/wallet/gatherCollectionInfo.ts +370 -0
- package/tools/wallet/getAddress.ts +14 -30
- package/tools/wallet/getBalance.ts +54 -0
- package/tools/wallet/getBalanceDroplet.ts +48 -0
- package/tools/wallet/getPublicKey.ts +3 -16
- package/tools/wallet/integratedWallet.ts +120 -0
- package/tools/wallet/mintCollection.ts +373 -0
- package/tools/wallet/purchaseListing.ts +21 -31
- package/tools/wallet/refreshUtxos.ts +2 -14
- package/tools/wallet/schemas.ts +18 -249
- package/tools/wallet/sendOrdinals.ts +14 -21
- package/tools/wallet/sendToAddress.ts +2 -18
- package/tools/wallet/setupDroplet.ts +161 -0
- package/tools/wallet/tools.ts +55 -210
- package/tools/wallet/transactionHelper.ts +121 -0
- package/tools/wallet/transferOrdToken.ts +19 -24
- package/tools/wallet/utxo.ts +62 -0
- package/tools/wallet/wallet.ts +237 -234
- package/vite.config.ts +15 -0
- package/tools/a2b/call.ts +0 -32
package/tools/bsv/token.ts
CHANGED
|
@@ -17,14 +17,11 @@ export function registerTokenTools(server: McpServer): void {
|
|
|
17
17
|
server.tool(
|
|
18
18
|
"bsv_toSatoshi",
|
|
19
19
|
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
23
|
-
}),
|
|
20
|
+
bitcoin: z.union([z.number(), z.string()]),
|
|
21
|
+
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
24
22
|
},
|
|
25
|
-
async ({
|
|
23
|
+
async ({ bitcoin, returnType }) => {
|
|
26
24
|
try {
|
|
27
|
-
const { bitcoin, returnType } = args;
|
|
28
25
|
let result: number | string | bigint;
|
|
29
26
|
|
|
30
27
|
switch (returnType) {
|
|
@@ -49,14 +46,11 @@ export function registerTokenTools(server: McpServer): void {
|
|
|
49
46
|
server.tool(
|
|
50
47
|
"bsv_toBitcoin",
|
|
51
48
|
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
55
|
-
}),
|
|
49
|
+
satoshis: z.union([z.number(), z.string(), z.bigint()]),
|
|
50
|
+
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
56
51
|
},
|
|
57
|
-
async ({
|
|
52
|
+
async ({ satoshis, returnType }) => {
|
|
58
53
|
try {
|
|
59
|
-
const { satoshis, returnType } = args;
|
|
60
54
|
let result: number | string | bigint;
|
|
61
55
|
|
|
62
56
|
switch (returnType) {
|
|
@@ -93,15 +87,12 @@ export function registerTokenTools(server: McpServer): void {
|
|
|
93
87
|
server.tool(
|
|
94
88
|
"bsv_toTokenSatoshi",
|
|
95
89
|
{
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
100
|
-
}),
|
|
90
|
+
token: z.union([z.number(), z.string(), z.bigint()]),
|
|
91
|
+
decimals: z.number().int().min(0),
|
|
92
|
+
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
101
93
|
},
|
|
102
|
-
async ({
|
|
94
|
+
async ({ token, decimals, returnType }) => {
|
|
103
95
|
try {
|
|
104
|
-
const { token, decimals, returnType } = args;
|
|
105
96
|
let result: number | string | bigint;
|
|
106
97
|
|
|
107
98
|
switch (returnType) {
|
|
@@ -126,15 +117,12 @@ export function registerTokenTools(server: McpServer): void {
|
|
|
126
117
|
server.tool(
|
|
127
118
|
"bsv_toToken",
|
|
128
119
|
{
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
133
|
-
}),
|
|
120
|
+
tokenSatoshi: z.union([z.number(), z.string(), z.bigint()]),
|
|
121
|
+
decimals: z.number().int().min(0),
|
|
122
|
+
returnType: z.enum(["number", "string", "bigint"]).optional(),
|
|
134
123
|
},
|
|
135
|
-
async ({
|
|
124
|
+
async ({ tokenSatoshi, decimals, returnType }) => {
|
|
136
125
|
try {
|
|
137
|
-
const { tokenSatoshi, decimals, returnType } = args;
|
|
138
126
|
let result: number | string | bigint;
|
|
139
127
|
|
|
140
128
|
switch (returnType) {
|
package/tools/constants.ts
CHANGED
|
@@ -19,3 +19,24 @@ export const MARKET_WALLET_ADDRESS = "15q8YQSqUa9uTh6gh4AVixxq29xkpBBP9z";
|
|
|
19
19
|
* Market fee will never be less than this amount
|
|
20
20
|
*/
|
|
21
21
|
export const MINIMUM_MARKET_FEE_SATOSHIS = 10000; // 10000 satoshis = 0.0001 BSV
|
|
22
|
+
|
|
23
|
+
export const BAP_PREFIX = "1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT";
|
|
24
|
+
export const B_PREFIX = "19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut";
|
|
25
|
+
export const MAP_PREFIX = "1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5";
|
|
26
|
+
export const AIP_PREFIX = "1HPcP7a4kQjpJzyV4HWHKagon76KC3BsZA";
|
|
27
|
+
export const STORAGE_MNEMONIC_KEY = "id_mnemonic";
|
|
28
|
+
export const PUBLIC_URL = process.env.PUBLIC_URL || "";
|
|
29
|
+
export const BMAP_URL =
|
|
30
|
+
process.env.PUBLIC_BMAP_URL || "https://bmap-api-production.up.railway.app";
|
|
31
|
+
|
|
32
|
+
export const ORDFS_URL =
|
|
33
|
+
process.env.PUBLIC_ORDFS_URL || "https://ordfs.network";
|
|
34
|
+
export const YOURS_INSTALL_URL =
|
|
35
|
+
"https://chromewebstore.google.com/detail/yours-wallet/mlbnicldlpdimbjdcncnklfempedeipj";
|
|
36
|
+
|
|
37
|
+
// export const BSOCIAL_API_URL =
|
|
38
|
+
// process.env.PUBLIC_BSOCIAL_API_URL ||
|
|
39
|
+
// "https://bsocial-overlay-production.up.railway.app/api/v1";
|
|
40
|
+
|
|
41
|
+
export const BSOCIAL_API_URL = "https://api.sigmaidentity.com/v1";
|
|
42
|
+
export const V5_API_URL = "https://ordinals.1sat.app/v5";
|
package/tools/index.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import type { PrivateKey } from "@bsv/sdk";
|
|
1
2
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
import { registerA2aCallTool } from "./a2b/call";
|
|
3
3
|
import { registerA2bDiscoverTool } from "./a2b/discover";
|
|
4
|
+
import { registerBapTools } from "./bap";
|
|
5
|
+
import { registerBsocialTools } from "./bsocial";
|
|
4
6
|
import { registerBsvTools } from "./bsv";
|
|
7
|
+
import { registerMneeTools } from "./mnee";
|
|
5
8
|
import { registerOrdinalsTools } from "./ordinals";
|
|
6
9
|
import { registerUtilsTools } from "./utils";
|
|
10
|
+
import { registerWalletGetBalanceDropletTool } from "./wallet/getBalanceDroplet";
|
|
11
|
+
import type { IntegratedWallet } from "./wallet/integratedWallet";
|
|
12
|
+
import { registerSetupDropletTool } from "./wallet/setupDroplet";
|
|
13
|
+
import { registerWalletTools } from "./wallet/tools";
|
|
14
|
+
import type { Wallet } from "./wallet/wallet";
|
|
7
15
|
|
|
8
16
|
/**
|
|
9
17
|
* Configuration options for tools
|
|
@@ -12,13 +20,27 @@ import { registerUtilsTools } from "./utils";
|
|
|
12
20
|
* - enableBsvTools: controlled by DISABLE_BSV_TOOLS
|
|
13
21
|
* - enableOrdinalsTools: controlled by DISABLE_ORDINALS_TOOLS
|
|
14
22
|
* - enableUtilsTools: controlled by DISABLE_UTILS_TOOLS
|
|
15
|
-
* - enableA2bTools: controlled by
|
|
23
|
+
* - enableA2bTools: controlled by ENABLE_A2B_TOOLS (disabled by default)
|
|
24
|
+
* - enableBapTools: controlled by DISABLE_BAP_TOOLS
|
|
25
|
+
* - enableBsocialTools: controlled by DISABLE_BSOCIAL_TOOLS
|
|
26
|
+
* - enableWalletTools: controlled by DISABLE_WALLET_TOOLS
|
|
27
|
+
* - enableMneeTools: controlled by DISABLE_MNEE_TOOLS
|
|
16
28
|
*/
|
|
17
29
|
export interface ToolsConfig {
|
|
18
30
|
enableBsvTools?: boolean;
|
|
19
31
|
enableOrdinalsTools?: boolean;
|
|
20
32
|
enableUtilsTools?: boolean;
|
|
21
33
|
enableA2bTools?: boolean;
|
|
34
|
+
enableBapTools?: boolean;
|
|
35
|
+
enableBsocialTools?: boolean;
|
|
36
|
+
enableWalletTools?: boolean;
|
|
37
|
+
enableMneeTools?: boolean;
|
|
38
|
+
identityPk?: PrivateKey;
|
|
39
|
+
payPk?: PrivateKey;
|
|
40
|
+
xprv?: string;
|
|
41
|
+
wallet?: Wallet;
|
|
42
|
+
integratedWallet?: IntegratedWallet;
|
|
43
|
+
disableBroadcasting?: boolean; // For wallet tools
|
|
22
44
|
}
|
|
23
45
|
|
|
24
46
|
/**
|
|
@@ -28,20 +50,30 @@ export interface ToolsConfig {
|
|
|
28
50
|
*/
|
|
29
51
|
export function registerAllTools(
|
|
30
52
|
server: McpServer,
|
|
31
|
-
config: ToolsConfig = {
|
|
32
|
-
enableBsvTools: true,
|
|
33
|
-
enableOrdinalsTools: true,
|
|
34
|
-
enableUtilsTools: true,
|
|
35
|
-
enableA2bTools: false,
|
|
36
|
-
},
|
|
53
|
+
config: ToolsConfig = {},
|
|
37
54
|
): void {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
// Ensure defaults are true unless explicitly set to false via env vars or config
|
|
56
|
+
const enableBsvTools =
|
|
57
|
+
process.env.DISABLE_BSV_TOOLS !== "true" && config.enableBsvTools !== false;
|
|
58
|
+
const enableOrdinalsTools =
|
|
59
|
+
process.env.DISABLE_ORDINALS_TOOLS !== "true" &&
|
|
60
|
+
config.enableOrdinalsTools !== false;
|
|
61
|
+
const enableUtilsTools =
|
|
62
|
+
process.env.DISABLE_UTILS_TOOLS !== "true" &&
|
|
63
|
+
config.enableUtilsTools !== false; // Ensure Utils are enabled by default
|
|
64
|
+
const enableA2bTools =
|
|
65
|
+
process.env.ENABLE_A2B_TOOLS === "true" && config.enableA2bTools !== false;
|
|
66
|
+
const enableBapTools =
|
|
67
|
+
process.env.DISABLE_BAP_TOOLS !== "true" && config.enableBapTools !== false;
|
|
68
|
+
const enableWalletTools =
|
|
69
|
+
process.env.DISABLE_WALLET_TOOLS !== "true" &&
|
|
70
|
+
config.enableWalletTools !== false;
|
|
71
|
+
const enableMneeTools =
|
|
72
|
+
process.env.DISABLE_MNEE_TOOLS !== "true" &&
|
|
73
|
+
config.enableMneeTools !== false;
|
|
74
|
+
const enableBsocialTools =
|
|
75
|
+
process.env.DISABLE_BSOCIAL_TOOLS !== "true" &&
|
|
76
|
+
config.enableBsocialTools !== false;
|
|
45
77
|
// Register BSV-related tools
|
|
46
78
|
if (enableBsvTools) {
|
|
47
79
|
registerBsvTools(server);
|
|
@@ -59,11 +91,52 @@ export function registerAllTools(
|
|
|
59
91
|
|
|
60
92
|
// Register agent-to-blockchain tools
|
|
61
93
|
if (enableA2bTools) {
|
|
62
|
-
// Register agent-to-blockchain discovery tool
|
|
63
94
|
registerA2bDiscoverTool(server);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Register BAP tools
|
|
98
|
+
if (enableBapTools) {
|
|
99
|
+
const bapConfig: import("./bap").BapToolsConfig = {
|
|
100
|
+
disableBroadcasting: config.disableBroadcasting,
|
|
101
|
+
identityPk: config.identityPk,
|
|
102
|
+
masterXprv: config.xprv,
|
|
103
|
+
wallet: config.wallet,
|
|
104
|
+
};
|
|
105
|
+
registerBapTools(server, bapConfig);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Register BSocial tools
|
|
109
|
+
if (enableBsocialTools && config.wallet) {
|
|
110
|
+
registerBsocialTools(server, { wallet: config.wallet });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Register Wallet tools themselves
|
|
114
|
+
if (enableWalletTools) {
|
|
115
|
+
if (config.integratedWallet?.isDropletMode) {
|
|
116
|
+
// Register Droplet-mode wallet tools
|
|
117
|
+
const dropletClient = config.integratedWallet.getDropletClient();
|
|
118
|
+
if (dropletClient) {
|
|
119
|
+
// Register Droplet-specific tools
|
|
120
|
+
registerWalletGetBalanceDropletTool(server, dropletClient);
|
|
121
|
+
if (config.integratedWallet) {
|
|
122
|
+
registerSetupDropletTool(server, config.integratedWallet);
|
|
123
|
+
}
|
|
124
|
+
console.error("Registered Droplet mode wallet tools");
|
|
125
|
+
}
|
|
126
|
+
} else if (config.wallet) {
|
|
127
|
+
// Register normal wallet tools
|
|
128
|
+
const walletToolOptions = {
|
|
129
|
+
disableBroadcasting: config.disableBroadcasting === true, // Default to false if undefined
|
|
130
|
+
enableA2bTools: enableA2bTools, // Use the already determined enableA2bTools value
|
|
131
|
+
identityPk: config.identityPk,
|
|
132
|
+
};
|
|
133
|
+
registerWalletTools(server, config.wallet, walletToolOptions);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
64
136
|
|
|
65
|
-
|
|
66
|
-
|
|
137
|
+
// Register MNEE tools
|
|
138
|
+
if (enableMneeTools) {
|
|
139
|
+
registerMneeTools(server);
|
|
67
140
|
}
|
|
68
141
|
|
|
69
142
|
// Add more tool categories as needed
|
package/tools/mnee/getBalance.ts
CHANGED
|
@@ -19,11 +19,9 @@ export function registerGetBalanceTool(
|
|
|
19
19
|
server.tool(
|
|
20
20
|
"mnee_getBalance",
|
|
21
21
|
"Retrieves the current MNEE token balance for the wallet. Returns the balance in MNEE tokens.",
|
|
22
|
-
{
|
|
23
|
-
args: getBalanceArgsSchema,
|
|
24
|
-
},
|
|
22
|
+
{},
|
|
25
23
|
async (
|
|
26
|
-
|
|
24
|
+
_params,
|
|
27
25
|
extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
|
|
28
26
|
) => {
|
|
29
27
|
try {
|
package/tools/mnee/index.ts
CHANGED
|
@@ -7,15 +7,23 @@ import { registerSendMneeTool } from "./sendMnee";
|
|
|
7
7
|
const mnee = new Mnee({
|
|
8
8
|
environment: "production",
|
|
9
9
|
});
|
|
10
|
+
|
|
11
|
+
const mneeToolsRegistered = new WeakSet<McpServer>();
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Register all MNEE tools with the MCP server
|
|
12
15
|
* @param server The MCP server instance
|
|
13
16
|
*/
|
|
14
17
|
export function registerMneeTools(server: McpServer): void {
|
|
18
|
+
if (mneeToolsRegistered.has(server)) {
|
|
19
|
+
// console.warn("WARN: MNEE tools already registered for this server instance. Skipping.");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
15
22
|
// Register MNEE-related tools
|
|
16
23
|
registerGetBalanceTool(server, mnee);
|
|
17
24
|
|
|
18
25
|
registerSendMneeTool(server, mnee);
|
|
19
26
|
|
|
20
27
|
registerParseTxTool(server, mnee);
|
|
28
|
+
mneeToolsRegistered.add(server);
|
|
21
29
|
}
|
package/tools/mnee/parseTx.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
3
|
-
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
4
3
|
import type {
|
|
4
|
+
CallToolResult,
|
|
5
5
|
ServerNotification,
|
|
6
6
|
ServerRequest,
|
|
7
7
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -24,13 +24,13 @@ export function registerParseTxTool(
|
|
|
24
24
|
server.tool(
|
|
25
25
|
"mnee_parseTx",
|
|
26
26
|
"Parse an MNEE transaction to get detailed information about its operations and amounts. All amounts are in atomic units with 5 decimal precision (e.g. 1000 atomic units = 0.01 MNEE).",
|
|
27
|
-
{
|
|
27
|
+
{ ...parseTxArgsSchema.shape },
|
|
28
28
|
async (
|
|
29
|
-
{
|
|
29
|
+
{ txid },
|
|
30
30
|
extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
|
|
31
31
|
): Promise<CallToolResult> => {
|
|
32
32
|
try {
|
|
33
|
-
const result: ParseTxResponse = await mnee.parseTx(
|
|
33
|
+
const result: ParseTxResponse = await mnee.parseTx(txid);
|
|
34
34
|
|
|
35
35
|
return {
|
|
36
36
|
content: [
|
package/tools/mnee/sendMnee.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
3
|
-
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
4
3
|
import type {
|
|
4
|
+
CallToolResult,
|
|
5
5
|
ServerNotification,
|
|
6
6
|
ServerRequest,
|
|
7
7
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -42,18 +42,18 @@ export function registerSendMneeTool(server: McpServer, mnee: Mnee): void {
|
|
|
42
42
|
server.tool(
|
|
43
43
|
"mnee_sendMnee",
|
|
44
44
|
"Send MNEE tokens to a specified address",
|
|
45
|
-
{
|
|
45
|
+
{ ...sendMneeArgsSchema.shape },
|
|
46
46
|
async (
|
|
47
|
-
{
|
|
47
|
+
{ address, amount, currency },
|
|
48
48
|
extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
|
|
49
49
|
): Promise<CallToolResult> => {
|
|
50
50
|
try {
|
|
51
51
|
// Since 1 MNEE = $1, the amount is the same in both currencies
|
|
52
|
-
const mneeAmount =
|
|
52
|
+
const mneeAmount = amount;
|
|
53
53
|
|
|
54
54
|
const transferRequest: SendMNEE[] = [
|
|
55
55
|
{
|
|
56
|
-
address
|
|
56
|
+
address,
|
|
57
57
|
amount: mneeAmount,
|
|
58
58
|
},
|
|
59
59
|
];
|
|
@@ -101,7 +101,7 @@ export function registerSendMneeTool(server: McpServer, mnee: Mnee): void {
|
|
|
101
101
|
rawtx: result.rawtx,
|
|
102
102
|
mneeAmount: mneeAmount,
|
|
103
103
|
usdAmount: formatUSD(mneeAmount),
|
|
104
|
-
recipient:
|
|
104
|
+
recipient: address,
|
|
105
105
|
},
|
|
106
106
|
null,
|
|
107
107
|
2,
|
|
@@ -42,14 +42,13 @@ export function registerGetInscriptionTool(server: McpServer): void {
|
|
|
42
42
|
"ordinals_getInscription",
|
|
43
43
|
"Retrieves detailed information about a specific ordinal inscription by its outpoint. Returns complete inscription data including content type, file information, inscription origin, and current status. Useful for verifying NFT authenticity or retrieving metadata about digital artifacts.",
|
|
44
44
|
{
|
|
45
|
-
|
|
45
|
+
...getInscriptionArgsSchema.shape,
|
|
46
46
|
},
|
|
47
47
|
async (
|
|
48
|
-
{
|
|
48
|
+
{ outpoint },
|
|
49
49
|
extra: RequestHandlerExtra,
|
|
50
50
|
) => {
|
|
51
51
|
try {
|
|
52
|
-
const { outpoint } = args;
|
|
53
52
|
|
|
54
53
|
// Validate outpoint format
|
|
55
54
|
if (!/^[0-9a-f]{64}_\d+$/i.test(outpoint)) {
|
|
@@ -43,14 +43,17 @@ export function registerGetTokenByIdOrTickerTool(server: McpServer): void {
|
|
|
43
43
|
"ordinals_getTokenByIdOrTicker",
|
|
44
44
|
"Retrieves detailed information about a specific BSV-20 token by its ID or ticker symbol. Returns complete token data including ticker symbol, supply information, decimals, and current status. This tool is useful for verifying token authenticity or checking supply metrics.",
|
|
45
45
|
{
|
|
46
|
-
|
|
46
|
+
id: z
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("BSV20 token ID in outpoint format (txid_vout)"),
|
|
50
|
+
tick: z.string().optional().describe("BSV20 token ticker symbol"),
|
|
47
51
|
},
|
|
48
52
|
async (
|
|
49
|
-
{
|
|
53
|
+
{ id, tick },
|
|
50
54
|
extra: RequestHandlerExtra,
|
|
51
55
|
) => {
|
|
52
56
|
try {
|
|
53
|
-
const { id, tick } = args;
|
|
54
57
|
|
|
55
58
|
// Validate that at least one of id or tick is provided
|
|
56
59
|
if (!id && !tick) {
|
|
@@ -95,29 +95,13 @@ export function registerMarketListingsTool(server: McpServer): void {
|
|
|
95
95
|
"ordinals_marketListings",
|
|
96
96
|
"Retrieves current marketplace listings for Bitcoin SV ordinals with flexible filtering. Supports multiple asset types (NFTs, BSV-20 tokens, BSV-21 tokens) through a unified interface. Results include listing prices, details about the assets, and seller information.",
|
|
97
97
|
{
|
|
98
|
-
|
|
98
|
+
...marketListingsArgsSchema.shape,
|
|
99
99
|
},
|
|
100
100
|
async (
|
|
101
|
-
{
|
|
101
|
+
{ limit, offset, sort, dir, address, origin, mime, num, minPrice, maxPrice, tokenType, id, tick, pending },
|
|
102
102
|
extra: RequestHandlerExtra,
|
|
103
103
|
) => {
|
|
104
104
|
try {
|
|
105
|
-
const {
|
|
106
|
-
limit,
|
|
107
|
-
offset,
|
|
108
|
-
sort,
|
|
109
|
-
dir,
|
|
110
|
-
address,
|
|
111
|
-
origin,
|
|
112
|
-
mime,
|
|
113
|
-
num,
|
|
114
|
-
minPrice,
|
|
115
|
-
maxPrice,
|
|
116
|
-
tokenType,
|
|
117
|
-
id,
|
|
118
|
-
tick,
|
|
119
|
-
pending,
|
|
120
|
-
} = args;
|
|
121
105
|
|
|
122
106
|
// Determine the API endpoint based on tokenType
|
|
123
107
|
let baseUrl = "https://ordinals.gorillapool.io/api";
|
|
@@ -73,12 +73,10 @@ export function registerMarketSalesTool(server: McpServer): void {
|
|
|
73
73
|
"ordinals_marketSales",
|
|
74
74
|
"Retrieves recent sales data for BSV-20 and BSV-21 tokens on the ordinals marketplace. This tool provides insights into market activity, including sale prices, transaction details, and token information. Supports filtering by token ID, ticker symbol, or seller address to help analyze market trends and track specific token sales.",
|
|
75
75
|
{
|
|
76
|
-
|
|
76
|
+
...marketSalesArgsSchema.shape,
|
|
77
77
|
},
|
|
78
|
-
async ({
|
|
78
|
+
async ({ limit, offset, dir, tokenType, id, tick, pending, address }, extra: RequestHandlerExtra) => {
|
|
79
79
|
try {
|
|
80
|
-
const { limit, offset, dir, tokenType, id, tick, pending, address } =
|
|
81
|
-
args;
|
|
82
80
|
|
|
83
81
|
// Determine the API endpoint based on tokenType
|
|
84
82
|
let baseUrl = "https://ordinals.gorillapool.io/api";
|
|
@@ -59,15 +59,13 @@ export function registerSearchInscriptionsTool(server: McpServer): void {
|
|
|
59
59
|
"ordinals_searchInscriptions",
|
|
60
60
|
"Searches for Bitcoin SV ordinal inscriptions using flexible criteria. This powerful search tool supports filtering by address, inscription content, MIME type, MAP fields, and other parameters. Results include detailed information about each matched inscription. Ideal for discovering NFTs and exploring the ordinals ecosystem.",
|
|
61
61
|
{
|
|
62
|
-
|
|
62
|
+
...searchInscriptionsArgsSchema.shape,
|
|
63
63
|
},
|
|
64
64
|
async (
|
|
65
|
-
{
|
|
65
|
+
{ limit, offset, dir, num, origin, address, map, terms, mime },
|
|
66
66
|
extra: RequestHandlerExtra,
|
|
67
67
|
) => {
|
|
68
68
|
try {
|
|
69
|
-
const { limit, offset, dir, num, origin, address, map, terms, mime } =
|
|
70
|
-
args;
|
|
71
69
|
|
|
72
70
|
// Build the URL with query parameters
|
|
73
71
|
const url = new URL(
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { BSM, type PrivateKey, Utils } from "@bsv/sdk";
|
|
2
|
+
import { AIP_PREFIX } from "../constants";
|
|
3
|
+
|
|
4
|
+
const { toArray, toBase64, toUTF8 } = Utils;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Sign OP_RETURN data with AIP (Author Identity Protocol)
|
|
8
|
+
* @param dataArrays - Array of data arrays to sign
|
|
9
|
+
* @param signingKey - Private key to sign with
|
|
10
|
+
* @param signingAddress - Address associated with the signing key
|
|
11
|
+
* @returns Object containing signed data array
|
|
12
|
+
*/
|
|
13
|
+
export async function signOpReturnWithAIP(
|
|
14
|
+
dataArrays: Uint8Array[],
|
|
15
|
+
signingKey: PrivateKey,
|
|
16
|
+
signingAddress: string,
|
|
17
|
+
): Promise<{ signedData: Uint8Array[] }> {
|
|
18
|
+
// Concatenate all data arrays to create message to sign
|
|
19
|
+
let messageToSign = new Uint8Array();
|
|
20
|
+
for (const data of dataArrays) {
|
|
21
|
+
const temp = new Uint8Array(messageToSign.length + data.length);
|
|
22
|
+
temp.set(messageToSign);
|
|
23
|
+
temp.set(data, messageToSign.length);
|
|
24
|
+
messageToSign = temp;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Create BSM signature
|
|
28
|
+
const signature = BSM.sign(messageToSign, signingKey);
|
|
29
|
+
|
|
30
|
+
// Convert signature to base64
|
|
31
|
+
const signatureBase64 = toBase64(signature.toCompact());
|
|
32
|
+
|
|
33
|
+
// Add AIP data to the arrays
|
|
34
|
+
const aipData: Uint8Array[] = [
|
|
35
|
+
toArray("|", "utf8"), // Separator
|
|
36
|
+
toArray(AIP_PREFIX, "utf8"),
|
|
37
|
+
toArray("BITCOIN_ECDSA", "utf8"),
|
|
38
|
+
toArray(signingAddress, "utf8"),
|
|
39
|
+
toArray(signatureBase64, "utf8"),
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
// Return combined data
|
|
43
|
+
return {
|
|
44
|
+
signedData: [...dataArrays, ...aipData],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Format an error message consistently
|
|
5
|
+
*/
|
|
6
|
+
export function formatError(error: unknown): string {
|
|
7
|
+
if (error instanceof Error) {
|
|
8
|
+
return error.message;
|
|
9
|
+
}
|
|
10
|
+
return String(error);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Create a standardized error response for MCP tools
|
|
15
|
+
*/
|
|
16
|
+
export function createErrorResponse(error: unknown): CallToolResult {
|
|
17
|
+
return {
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: "text",
|
|
21
|
+
text: formatError(error),
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
isError: true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create a standardized success response for MCP tools
|
|
30
|
+
*/
|
|
31
|
+
export function createSuccessResponse(data: unknown): CallToolResult {
|
|
32
|
+
const text = typeof data === "string" ? data : JSON.stringify(data, null, 2);
|
|
33
|
+
return {
|
|
34
|
+
content: [
|
|
35
|
+
{
|
|
36
|
+
type: "text",
|
|
37
|
+
text,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
isError: false,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Create a response based on a result object with success field
|
|
46
|
+
*/
|
|
47
|
+
export function createResponse(result: {
|
|
48
|
+
success: boolean;
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}): CallToolResult {
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: JSON.stringify(result, null, 2),
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
isError: !result.success,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Wrap an async function with standard error handling
|
|
64
|
+
*/
|
|
65
|
+
export function withErrorHandler<
|
|
66
|
+
T extends (...args: unknown[]) => Promise<unknown>,
|
|
67
|
+
>(fn: T): (...args: Parameters<T>) => Promise<CallToolResult> {
|
|
68
|
+
return async (...args: Parameters<T>): Promise<CallToolResult> => {
|
|
69
|
+
try {
|
|
70
|
+
const result = await fn(...args);
|
|
71
|
+
return createSuccessResponse(result);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return createErrorResponse(error);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|