@aibtc/mcp-server 1.70.1 → 1.72.0
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 +45 -8
- package/dist/bridge/index.js +4 -4
- package/dist/config/contracts.d.ts +4 -4
- package/dist/config/contracts.js +2 -2
- package/dist/config/networks.js +4 -1
- package/dist/endpoints/registry.d.ts +8 -26
- package/dist/endpoints/registry.js +7 -932
- package/dist/index.js +118 -42
- package/dist/services/stacking.service.d.ts +144 -45
- package/dist/services/stacking.service.js +416 -123
- package/dist/services/x402-discovery.service.d.ts +81 -0
- package/dist/services/x402-discovery.service.js +170 -0
- package/dist/tools/arxiv-research.tools.d.ts +1 -1
- package/dist/tools/arxiv-research.tools.js +6 -6
- package/dist/tools/at-stake-legion.tools.d.ts +1 -1
- package/dist/tools/at-stake-legion.tools.js +14 -14
- package/dist/tools/at-stake.tools.d.ts +1 -1
- package/dist/tools/at-stake.tools.js +17 -17
- package/dist/tools/bitcoin.tools.d.ts +1 -1
- package/dist/tools/bitcoin.tools.js +12 -12
- package/dist/tools/bitflow.tools.d.ts +1 -1
- package/dist/tools/bitflow.tools.js +21 -21
- package/dist/tools/bns.tools.d.ts +1 -1
- package/dist/tools/bns.tools.js +18 -18
- package/dist/tools/bounty-hint.d.ts +1 -1
- package/dist/tools/bounty-scanner.tools.d.ts +1 -1
- package/dist/tools/bounty-scanner.tools.js +20 -20
- package/dist/tools/child-inscription.tools.d.ts +1 -1
- package/dist/tools/child-inscription.tools.js +6 -6
- package/dist/tools/competition.tools.d.ts +1 -1
- package/dist/tools/competition.tools.js +4 -4
- package/dist/tools/contract.tools.d.ts +1 -1
- package/dist/tools/contract.tools.js +8 -8
- package/dist/tools/credentials.tools.d.ts +1 -1
- package/dist/tools/credentials.tools.js +8 -8
- package/dist/tools/defi.tools.d.ts +1 -1
- package/dist/tools/defi.tools.js +21 -21
- package/dist/tools/dual-stacking.tools.d.ts +1 -1
- package/dist/tools/dual-stacking.tools.js +7 -7
- package/dist/tools/earning.tools.d.ts +1 -1
- package/dist/tools/earning.tools.js +5 -5
- package/dist/tools/endpoint.tools.d.ts +1 -1
- package/dist/tools/endpoint.tools.js +92 -49
- package/dist/tools/identity.tools.d.ts +1 -1
- package/dist/tools/identity.tools.js +19 -19
- package/dist/tools/inbox-x402.tools.d.ts +1 -1
- package/dist/tools/inbox-x402.tools.js +2 -2
- package/dist/tools/inbox.tools.d.ts +1 -1
- package/dist/tools/inbox.tools.js +2 -2
- package/dist/tools/index.d.ts +6 -3
- package/dist/tools/index.js +69 -58
- package/dist/tools/inference-marketplace.tools.d.ts +1 -1
- package/dist/tools/inference-marketplace.tools.js +10 -10
- package/dist/tools/jingswap.tools.d.ts +1 -1
- package/dist/tools/jingswap.tools.js +30 -30
- package/dist/tools/legion.tools.d.ts +1 -1
- package/dist/tools/legion.tools.js +20 -20
- package/dist/tools/lightning.tools.d.ts +1 -1
- package/dist/tools/lightning.tools.js +14 -14
- package/dist/tools/mempool.tools.d.ts +1 -1
- package/dist/tools/mempool.tools.js +5 -5
- package/dist/tools/news.tools.d.ts +1 -1
- package/dist/tools/news.tools.js +2 -1
- package/dist/tools/nft.tools.d.ts +1 -1
- package/dist/tools/nft.tools.js +12 -12
- package/dist/tools/nonce.tools.d.ts +1 -1
- package/dist/tools/nonce.tools.js +8 -8
- package/dist/tools/nostr.tools.d.ts +1 -1
- package/dist/tools/nostr.tools.js +12 -12
- package/dist/tools/openrouter.tools.d.ts +1 -1
- package/dist/tools/openrouter.tools.js +4 -4
- package/dist/tools/ordinals-marketplace.tools.d.ts +1 -1
- package/dist/tools/ordinals-marketplace.tools.js +10 -10
- package/dist/tools/ordinals-p2p.tools.d.ts +1 -1
- package/dist/tools/ordinals-p2p.tools.js +18 -18
- package/dist/tools/ordinals.tools.d.ts +1 -1
- package/dist/tools/ordinals.tools.js +8 -8
- package/dist/tools/pillar-direct.tools.d.ts +1 -1
- package/dist/tools/pillar-direct.tools.js +59 -38
- package/dist/tools/pillar.tools.d.ts +1 -1
- package/dist/tools/pillar.tools.js +28 -26
- package/dist/tools/profiles.d.ts +51 -0
- package/dist/tools/profiles.js +111 -0
- package/dist/tools/psbt.tools.d.ts +1 -1
- package/dist/tools/psbt.tools.js +8 -8
- package/dist/tools/query.tools.d.ts +1 -1
- package/dist/tools/query.tools.js +12 -12
- package/dist/tools/relay-diagnostic.tools.d.ts +1 -1
- package/dist/tools/relay-diagnostic.tools.js +3 -3
- package/dist/tools/reputation.tools.d.ts +1 -1
- package/dist/tools/reputation.tools.js +22 -22
- package/dist/tools/runes.tools.d.ts +1 -1
- package/dist/tools/runes.tools.js +18 -18
- package/dist/tools/sbtc.tools.d.ts +1 -1
- package/dist/tools/sbtc.tools.js +14 -33
- package/dist/tools/scaffold.tools.d.ts +1 -1
- package/dist/tools/scaffold.tools.js +4 -4
- package/dist/tools/settings.tools.d.ts +1 -1
- package/dist/tools/settings.tools.js +9 -9
- package/dist/tools/signing.tools.d.ts +1 -1
- package/dist/tools/signing.tools.js +20 -20
- package/dist/tools/skill-mappings.js +4 -0
- package/dist/tools/souldinals.tools.d.ts +1 -1
- package/dist/tools/souldinals.tools.js +10 -10
- package/dist/tools/stacking-lottery.tools.d.ts +1 -1
- package/dist/tools/stacking-lottery.tools.js +11 -11
- package/dist/tools/stacking.tools.d.ts +1 -1
- package/dist/tools/stacking.tools.js +358 -50
- package/dist/tools/stacks-market.tools.d.ts +1 -1
- package/dist/tools/stacks-market.tools.js +22 -22
- package/dist/tools/styx.tools.d.ts +1 -1
- package/dist/tools/styx.tools.js +11 -11
- package/dist/tools/taproot-multisig.tools.d.ts +1 -1
- package/dist/tools/taproot-multisig.tools.js +5 -5
- package/dist/tools/tenero.tools.d.ts +1 -1
- package/dist/tools/tenero.tools.js +22 -22
- package/dist/tools/tokens.tools.d.ts +1 -1
- package/dist/tools/tokens.tools.js +10 -10
- package/dist/tools/transfer.tools.d.ts +1 -1
- package/dist/tools/transfer.tools.js +4 -4
- package/dist/tools/wallet-management.tools.d.ts +1 -1
- package/dist/tools/wallet-management.tools.js +16 -16
- package/dist/tools/wallet.tools.d.ts +1 -1
- package/dist/tools/wallet.tools.js +2 -2
- package/dist/tools/yield-dashboard.tools.d.ts +1 -1
- package/dist/tools/yield-dashboard.tools.js +18 -27
- package/dist/tools/yield-hunter.tools.d.ts +1 -1
- package/dist/tools/yield-hunter.tools.js +6 -6
- package/dist/utils/bitcoin.d.ts +8 -0
- package/dist/utils/bitcoin.js +24 -0
- package/dist/utils/fee.js +1 -1
- package/package.json +8 -7
- package/skill/SKILL.md +1 -1
- package/skill/references/stacks-defi.md +1 -1
package/dist/tools/sbtc.tools.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as btc from "@scure/btc-signer";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { getAccount, getWalletAddress, NETWORK } from "../services/x402.service.js";
|
|
4
3
|
import { getSbtcService } from "../services/sbtc.service.js";
|
|
@@ -8,26 +7,8 @@ import { getContracts, parseContractId } from "../config/contracts.js";
|
|
|
8
7
|
import { createJsonResponse, createErrorResponse, resolveFee } from "../utils/index.js";
|
|
9
8
|
import { getWalletManager } from "../services/wallet-manager.js";
|
|
10
9
|
import { MempoolApi, getMempoolTxUrl } from "../services/mempool-api.js";
|
|
11
|
-
import { getBtcNetwork } from "../transactions/bitcoin-builder.js";
|
|
12
10
|
import { sponsoredSchema } from "./schemas.js";
|
|
13
|
-
|
|
14
|
-
const decoded = btc.Address(getBtcNetwork(NETWORK)).decode(btcRecipientAddress);
|
|
15
|
-
if (decoded.type === "tr" && decoded.pubkey) {
|
|
16
|
-
return { version: 0x06, hashbytesHex: Buffer.from(decoded.pubkey).toString("hex") };
|
|
17
|
-
}
|
|
18
|
-
switch (decoded.type) {
|
|
19
|
-
case "pkh":
|
|
20
|
-
return { version: 0x00, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
|
|
21
|
-
case "sh":
|
|
22
|
-
return { version: 0x01, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
|
|
23
|
-
case "wpkh":
|
|
24
|
-
return { version: 0x04, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
|
|
25
|
-
case "wsh":
|
|
26
|
-
return { version: 0x05, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
|
|
27
|
-
default:
|
|
28
|
-
throw new Error("Unsupported BTC recipient address type. Supported: P2PKH, P2SH, P2WPKH, P2WSH, P2TR.");
|
|
29
|
-
}
|
|
30
|
-
}
|
|
11
|
+
import { btcAddressToPoxAddr } from "../utils/bitcoin.js";
|
|
31
12
|
function getReadonlySenderAddress() {
|
|
32
13
|
const contracts = getContracts(NETWORK);
|
|
33
14
|
return parseContractId(contracts.SBTC_REGISTRY).address;
|
|
@@ -36,12 +17,12 @@ export function registerSbtcTools(server) {
|
|
|
36
17
|
// Get sBTC balance
|
|
37
18
|
server.registerTool("sbtc_get_balance", {
|
|
38
19
|
description: "Get the sBTC balance for a wallet address.",
|
|
39
|
-
inputSchema: {
|
|
20
|
+
inputSchema: z.object({
|
|
40
21
|
address: z
|
|
41
22
|
.string()
|
|
42
23
|
.optional()
|
|
43
24
|
.describe("Wallet address to check. Uses configured wallet if not provided."),
|
|
44
|
-
},
|
|
25
|
+
}),
|
|
45
26
|
}, async ({ address }) => {
|
|
46
27
|
try {
|
|
47
28
|
const sbtcService = getSbtcService(NETWORK);
|
|
@@ -66,7 +47,7 @@ export function registerSbtcTools(server) {
|
|
|
66
47
|
|
|
67
48
|
sBTC uses 8 decimals (same as Bitcoin).
|
|
68
49
|
Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
|
|
69
|
-
inputSchema: {
|
|
50
|
+
inputSchema: z.object({
|
|
70
51
|
recipient: z.string().describe("The recipient's Stacks address"),
|
|
71
52
|
amount: z.string().describe("Amount in satoshis (0.00000001 sBTC). Example: '100000' for 0.001 sBTC"),
|
|
72
53
|
memo: z.string().optional().describe("Optional memo message"),
|
|
@@ -75,7 +56,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
|
|
|
75
56
|
.optional()
|
|
76
57
|
.describe("Optional fee: 'low' | 'medium' | 'high' preset or micro-STX amount. If omitted, auto-estimated."),
|
|
77
58
|
sponsored: sponsoredSchema,
|
|
78
|
-
},
|
|
59
|
+
}),
|
|
79
60
|
}, async ({ recipient, amount, memo, fee, sponsored }) => {
|
|
80
61
|
try {
|
|
81
62
|
const sbtcService = getSbtcService(NETWORK);
|
|
@@ -107,7 +88,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
|
|
|
107
88
|
const sbtcService = getSbtcService(NETWORK);
|
|
108
89
|
const account = await getAccount();
|
|
109
90
|
const resolvedFee = await resolveFee(fee, NETWORK, "contract_call");
|
|
110
|
-
const recipientTuple =
|
|
91
|
+
const recipientTuple = btcAddressToPoxAddr(btcRecipientAddress, NETWORK);
|
|
111
92
|
const result = await sbtcService.initiateWithdrawal(account, BigInt(amount), BigInt(maxFee), recipientTuple, resolvedFee, sponsored);
|
|
112
93
|
let requestId = null;
|
|
113
94
|
try {
|
|
@@ -118,7 +99,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
|
|
|
118
99
|
}
|
|
119
100
|
return { result, recipientTuple, requestId };
|
|
120
101
|
}
|
|
121
|
-
const withdrawalInputSchema = {
|
|
102
|
+
const withdrawalInputSchema = z.object({
|
|
122
103
|
amount: z
|
|
123
104
|
.number()
|
|
124
105
|
.int()
|
|
@@ -139,7 +120,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
|
|
|
139
120
|
.optional()
|
|
140
121
|
.describe("Optional fee: 'low' | 'medium' | 'high' preset or micro-STX amount."),
|
|
141
122
|
sponsored: sponsoredSchema,
|
|
142
|
-
};
|
|
123
|
+
});
|
|
143
124
|
// Initiate sBTC withdrawal (peg-out to BTC L1)
|
|
144
125
|
server.registerTool("sbtc_initiate_withdrawal", {
|
|
145
126
|
description: `Initiate an sBTC peg-out to a Bitcoin L1 address.
|
|
@@ -242,7 +223,7 @@ Signers later process the request and send BTC on L1.`,
|
|
|
242
223
|
...(txid ? { explorerUrl: getExplorerTxUrl(txid, NETWORK) } : {}),
|
|
243
224
|
});
|
|
244
225
|
}
|
|
245
|
-
const withdrawalStatusInputSchema = {
|
|
226
|
+
const withdrawalStatusInputSchema = z.object({
|
|
246
227
|
requestId: z
|
|
247
228
|
.number()
|
|
248
229
|
.int()
|
|
@@ -253,7 +234,7 @@ Signers later process the request and send BTC on L1.`,
|
|
|
253
234
|
.string()
|
|
254
235
|
.optional()
|
|
255
236
|
.describe("Initiate-withdrawal transaction ID (used to resolve requestId)"),
|
|
256
|
-
};
|
|
237
|
+
});
|
|
257
238
|
// Check withdrawal request status
|
|
258
239
|
server.registerTool("sbtc_withdrawal_status", {
|
|
259
240
|
description: "Check status of an sBTC withdrawal request by requestId or initiating txid.",
|
|
@@ -352,7 +333,7 @@ If the deposit fails, you can reclaim your BTC after the lock time expires.
|
|
|
352
333
|
|
|
353
334
|
By default, only uses cardinal UTXOs (safe to spend - no inscriptions).
|
|
354
335
|
Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`,
|
|
355
|
-
inputSchema: {
|
|
336
|
+
inputSchema: z.object({
|
|
356
337
|
amount: z
|
|
357
338
|
.number()
|
|
358
339
|
.int()
|
|
@@ -386,7 +367,7 @@ Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`
|
|
|
386
367
|
.default(false)
|
|
387
368
|
.describe("Include ordinal UTXOs (contains inscriptions). Default: false (cardinal only). " +
|
|
388
369
|
"WARNING: Setting this to true may destroy valuable inscriptions!"),
|
|
389
|
-
},
|
|
370
|
+
}),
|
|
390
371
|
}, async ({ amount, feeRate, maxSignerFee, reclaimLockTime, includeOrdinals }) => {
|
|
391
372
|
try {
|
|
392
373
|
// Get wallet account (requires unlocked wallet)
|
|
@@ -459,7 +440,7 @@ Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`
|
|
|
459
440
|
// Check sBTC deposit status
|
|
460
441
|
server.registerTool("sbtc_deposit_status", {
|
|
461
442
|
description: "Check the status of an sBTC deposit transaction from Emily API.",
|
|
462
|
-
inputSchema: {
|
|
443
|
+
inputSchema: z.object({
|
|
463
444
|
txid: z.string().describe("Bitcoin transaction ID of the deposit"),
|
|
464
445
|
vout: z
|
|
465
446
|
.number()
|
|
@@ -468,7 +449,7 @@ Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`
|
|
|
468
449
|
.optional()
|
|
469
450
|
.default(0)
|
|
470
451
|
.describe("Output index of the deposit (default: 0)"),
|
|
471
|
-
},
|
|
452
|
+
}),
|
|
472
453
|
}, async ({ txid, vout }) => {
|
|
473
454
|
try {
|
|
474
455
|
const depositService = getSbtcDepositService(NETWORK);
|
|
@@ -91,7 +91,7 @@ cd {projectName}
|
|
|
91
91
|
npm install
|
|
92
92
|
npm run dev
|
|
93
93
|
\`\`\``,
|
|
94
|
-
inputSchema: {
|
|
94
|
+
inputSchema: z.object({
|
|
95
95
|
outputDir: z
|
|
96
96
|
.string()
|
|
97
97
|
.describe("Directory where the project folder will be created (e.g., '/Users/me/projects' or '.')"),
|
|
@@ -135,7 +135,7 @@ npm run dev
|
|
|
135
135
|
.url()
|
|
136
136
|
.optional()
|
|
137
137
|
.describe("Custom relay URL (default: https://x402-relay.aibtc.com)"),
|
|
138
|
-
},
|
|
138
|
+
}),
|
|
139
139
|
}, async ({ outputDir, projectName, endpoints, recipientAddress, network, relayUrl }) => {
|
|
140
140
|
try {
|
|
141
141
|
const projectPath = path.join(outputDir, projectName);
|
|
@@ -210,7 +210,7 @@ npm install
|
|
|
210
210
|
# Edit .dev.vars with RECIPIENT_ADDRESS and OPENROUTER_API_KEY
|
|
211
211
|
npm run dev
|
|
212
212
|
\`\`\``,
|
|
213
|
-
inputSchema: {
|
|
213
|
+
inputSchema: z.object({
|
|
214
214
|
outputDir: z
|
|
215
215
|
.string()
|
|
216
216
|
.describe("Directory where the project folder will be created (e.g., '/Users/me/projects' or '.')"),
|
|
@@ -264,7 +264,7 @@ npm run dev
|
|
|
264
264
|
.optional()
|
|
265
265
|
.default("anthropic/claude-3-haiku")
|
|
266
266
|
.describe("Default OpenRouter model for all endpoints (default: anthropic/claude-3-haiku)"),
|
|
267
|
-
},
|
|
267
|
+
}),
|
|
268
268
|
}, async ({ outputDir, projectName, endpoints, recipientAddress, network, relayUrl, defaultModel, }) => {
|
|
269
269
|
try {
|
|
270
270
|
const projectPath = path.join(outputDir, projectName);
|
|
@@ -16,12 +16,12 @@ export function registerSettingsTools(server) {
|
|
|
16
16
|
description: `Save a Hiro API key to ~/.aibtc/config.json for authenticated Hiro API requests.
|
|
17
17
|
Authenticated requests get higher rate limits than public (unauthenticated) requests.
|
|
18
18
|
Get a free API key at https://platform.hiro.so/`,
|
|
19
|
-
inputSchema: {
|
|
19
|
+
inputSchema: z.object({
|
|
20
20
|
apiKey: z
|
|
21
21
|
.string()
|
|
22
22
|
.min(1)
|
|
23
23
|
.describe("Your Hiro API key - WARNING: sensitive value"),
|
|
24
|
-
},
|
|
24
|
+
}),
|
|
25
25
|
}, async ({ apiKey }) => {
|
|
26
26
|
try {
|
|
27
27
|
await initializeStorage();
|
|
@@ -45,7 +45,7 @@ Get a free API key at https://platform.hiro.so/`,
|
|
|
45
45
|
*/
|
|
46
46
|
server.registerTool("get_hiro_api_key", {
|
|
47
47
|
description: "Check whether a Hiro API key is configured. Shows the key source (stored file or environment variable) and a masked preview.",
|
|
48
|
-
inputSchema: {},
|
|
48
|
+
inputSchema: z.object({}),
|
|
49
49
|
}, async () => {
|
|
50
50
|
try {
|
|
51
51
|
await initializeStorage();
|
|
@@ -81,7 +81,7 @@ Get a free API key at https://platform.hiro.so/`,
|
|
|
81
81
|
*/
|
|
82
82
|
server.registerTool("delete_hiro_api_key", {
|
|
83
83
|
description: "Remove the stored Hiro API key from ~/.aibtc/config.json. If HIRO_API_KEY is set in the environment, that will still be used as a fallback.",
|
|
84
|
-
inputSchema: {},
|
|
84
|
+
inputSchema: z.object({}),
|
|
85
85
|
}, async () => {
|
|
86
86
|
try {
|
|
87
87
|
await initializeStorage();
|
|
@@ -114,12 +114,12 @@ Get a free API key at https://platform.hiro.so/`,
|
|
|
114
114
|
Use this if you run your own stacks-blockchain-api node (default port 3999) or use a third-party provider.
|
|
115
115
|
The URL should serve the same /v2/ and /extended/v1/ endpoints as api.hiro.so.
|
|
116
116
|
Example: http://localhost:3999`,
|
|
117
|
-
inputSchema: {
|
|
117
|
+
inputSchema: z.object({
|
|
118
118
|
url: z
|
|
119
119
|
.string()
|
|
120
120
|
.url()
|
|
121
121
|
.describe("Base URL of your Stacks API node (e.g. http://localhost:3999)"),
|
|
122
|
-
},
|
|
122
|
+
}),
|
|
123
123
|
}, async ({ url }) => {
|
|
124
124
|
try {
|
|
125
125
|
await initializeStorage();
|
|
@@ -143,7 +143,7 @@ Example: http://localhost:3999`,
|
|
|
143
143
|
*/
|
|
144
144
|
server.registerTool("get_stacks_api_url", {
|
|
145
145
|
description: "Show the current Stacks API URL being used for blockchain queries. Indicates whether it's a custom node or the default Hiro API.",
|
|
146
|
-
inputSchema: {},
|
|
146
|
+
inputSchema: z.object({}),
|
|
147
147
|
}, async () => {
|
|
148
148
|
try {
|
|
149
149
|
await initializeStorage();
|
|
@@ -169,7 +169,7 @@ Example: http://localhost:3999`,
|
|
|
169
169
|
*/
|
|
170
170
|
server.registerTool("delete_stacks_api_url", {
|
|
171
171
|
description: "Remove the custom Stacks API URL and revert to the default Hiro API (api.mainnet.hiro.so or api.testnet.hiro.so).",
|
|
172
|
-
inputSchema: {},
|
|
172
|
+
inputSchema: z.object({}),
|
|
173
173
|
}, async () => {
|
|
174
174
|
try {
|
|
175
175
|
await initializeStorage();
|
|
@@ -199,7 +199,7 @@ Example: http://localhost:3999`,
|
|
|
199
199
|
description: `Check the currently running MCP server version and compare with the latest published version on npm.
|
|
200
200
|
Use this to detect if you're running a stale cached version (common with npx).
|
|
201
201
|
If your version is outdated, clear the npx cache and restart your MCP client: npx clear-npx-cache (the client config already points at @latest, so the next launch pulls the newest version).`,
|
|
202
|
-
inputSchema: {},
|
|
202
|
+
inputSchema: z.object({}),
|
|
203
203
|
}, async () => {
|
|
204
204
|
try {
|
|
205
205
|
const currentVersion = packageJson.version;
|
|
@@ -24,6 +24,6 @@
|
|
|
24
24
|
* Bitcoin signatures use BIP-137 format compatible with most Bitcoin wallets.
|
|
25
25
|
* Nostr events are signed with BIP-340 Schnorr and can be published to Nostr relays.
|
|
26
26
|
*/
|
|
27
|
-
import { McpServer } from "@modelcontextprotocol/
|
|
27
|
+
import { McpServer } from "@modelcontextprotocol/server";
|
|
28
28
|
export declare function registerSigningTools(server: McpServer): void;
|
|
29
29
|
//# sourceMappingURL=signing.tools.d.ts.map
|
|
@@ -534,7 +534,7 @@ export function registerSigningTools(server) {
|
|
|
534
534
|
"Creates a signature that can be verified both off-chain and on-chain by smart contracts. " +
|
|
535
535
|
"Use cases: meta-transactions, off-chain voting, permits, proving address control. " +
|
|
536
536
|
"Requires an unlocked wallet.",
|
|
537
|
-
inputSchema: {
|
|
537
|
+
inputSchema: z.object({
|
|
538
538
|
message: z
|
|
539
539
|
.record(z.string(), z.unknown())
|
|
540
540
|
.describe("The structured data to sign as a JSON object. " +
|
|
@@ -547,7 +547,7 @@ export function registerSigningTools(server) {
|
|
|
547
547
|
version: z.string().describe("Application version (e.g., '1.0.0')"),
|
|
548
548
|
})
|
|
549
549
|
.describe("Domain binding for the signature. Prevents cross-app and cross-version replay."),
|
|
550
|
-
},
|
|
550
|
+
}),
|
|
551
551
|
}, async ({ message, domain }) => {
|
|
552
552
|
try {
|
|
553
553
|
const account = requireUnlockedWallet();
|
|
@@ -604,7 +604,7 @@ export function registerSigningTools(server) {
|
|
|
604
604
|
description: "Verify a SIP-018 signature and recover the signer's address. " +
|
|
605
605
|
"Takes the verification hash (from sip018_sign or sip018_hash 'verification' field) and the signature, " +
|
|
606
606
|
"then recovers the public key and derives the signer's Stacks address.",
|
|
607
|
-
inputSchema: {
|
|
607
|
+
inputSchema: z.object({
|
|
608
608
|
messageHash: z
|
|
609
609
|
.string()
|
|
610
610
|
.describe("The SIP-018 verification hash (from sip018_sign/sip018_hash 'verification' field). " +
|
|
@@ -617,7 +617,7 @@ export function registerSigningTools(server) {
|
|
|
617
617
|
.optional()
|
|
618
618
|
.describe("Optional: expected signer address to verify against. " +
|
|
619
619
|
"If provided, returns whether the signature is valid for this signer."),
|
|
620
|
-
},
|
|
620
|
+
}),
|
|
621
621
|
}, async ({ messageHash, signature, expectedSigner }) => {
|
|
622
622
|
try {
|
|
623
623
|
// Recover public key from signature
|
|
@@ -657,7 +657,7 @@ export function registerSigningTools(server) {
|
|
|
657
657
|
"Returns the full encoded hash, domain hash, and message hash. " +
|
|
658
658
|
"Useful for preparing data for on-chain verification or multi-sig coordination. " +
|
|
659
659
|
"Does not require an unlocked wallet.",
|
|
660
|
-
inputSchema: {
|
|
660
|
+
inputSchema: z.object({
|
|
661
661
|
message: z
|
|
662
662
|
.record(z.string(), z.unknown())
|
|
663
663
|
.describe("The structured data as a JSON object. " +
|
|
@@ -673,7 +673,7 @@ export function registerSigningTools(server) {
|
|
|
673
673
|
.describe("Optional chain ID. Defaults to current network (1 for mainnet, 2147483648 for testnet)"),
|
|
674
674
|
})
|
|
675
675
|
.describe("Domain binding for the hash"),
|
|
676
|
-
},
|
|
676
|
+
}),
|
|
677
677
|
}, async ({ message, domain }) => {
|
|
678
678
|
try {
|
|
679
679
|
// Use provided chainId or default to current network
|
|
@@ -726,11 +726,11 @@ export function registerSigningTools(server) {
|
|
|
726
726
|
"The message is prefixed with '\\x17Stacks Signed Message:\\n' before hashing (SIWS-compatible). " +
|
|
727
727
|
"Use cases: proving address ownership, authentication, sign-in flows. " +
|
|
728
728
|
"Requires an unlocked wallet.",
|
|
729
|
-
inputSchema: {
|
|
729
|
+
inputSchema: z.object({
|
|
730
730
|
message: z
|
|
731
731
|
.string()
|
|
732
732
|
.describe("The plain text message to sign. Will be prefixed with Stacks message prefix before signing."),
|
|
733
|
-
},
|
|
733
|
+
}),
|
|
734
734
|
}, async ({ message }) => {
|
|
735
735
|
try {
|
|
736
736
|
const account = requireUnlockedWallet();
|
|
@@ -768,7 +768,7 @@ export function registerSigningTools(server) {
|
|
|
768
768
|
description: "Verify a Stacks message signature and recover the signer's address. " +
|
|
769
769
|
"Takes the original message and signature, applies the Stacks prefix, and verifies. " +
|
|
770
770
|
"Compatible with SIWS (Sign In With Stacks) authentication flows.",
|
|
771
|
-
inputSchema: {
|
|
771
|
+
inputSchema: z.object({
|
|
772
772
|
message: z
|
|
773
773
|
.string()
|
|
774
774
|
.describe("The original plain text message that was signed."),
|
|
@@ -781,7 +781,7 @@ export function registerSigningTools(server) {
|
|
|
781
781
|
.optional()
|
|
782
782
|
.describe("Optional: expected signer address to verify against. " +
|
|
783
783
|
"If provided, returns whether the signature is valid for this signer."),
|
|
784
|
-
},
|
|
784
|
+
}),
|
|
785
785
|
}, async ({ message, signature, expectedSigner }) => {
|
|
786
786
|
try {
|
|
787
787
|
// Hash the message with the Stacks prefix
|
|
@@ -843,7 +843,7 @@ export function registerSigningTools(server) {
|
|
|
843
843
|
"Use addressType 'p2tr' to force signing with the Taproot key. " +
|
|
844
844
|
"Use cases: proving Bitcoin address ownership, authentication, off-chain verification. " +
|
|
845
845
|
"Requires an unlocked wallet with Bitcoin keys.",
|
|
846
|
-
inputSchema: {
|
|
846
|
+
inputSchema: z.object({
|
|
847
847
|
message: z
|
|
848
848
|
.string()
|
|
849
849
|
.describe("The plain text message to sign."),
|
|
@@ -852,7 +852,7 @@ export function registerSigningTools(server) {
|
|
|
852
852
|
.optional()
|
|
853
853
|
.describe("Optional: address type to sign with. 'p2wpkh' uses native SegWit (bc1q, BIP-322), " +
|
|
854
854
|
"'p2tr' uses Taproot (bc1p, BIP-322). If omitted, auto-detects from wallet address type."),
|
|
855
|
-
},
|
|
855
|
+
}),
|
|
856
856
|
}, async ({ message, addressType }) => {
|
|
857
857
|
try {
|
|
858
858
|
const account = requireUnlockedWallet();
|
|
@@ -993,7 +993,7 @@ export function registerSigningTools(server) {
|
|
|
993
993
|
"BIP-137 works for legacy addresses; BIP-322 is required for bc1q and bc1p addresses. " +
|
|
994
994
|
"Takes the original message and signature (hex or base64). " +
|
|
995
995
|
"Compatible with signatures from most Bitcoin wallets.",
|
|
996
|
-
inputSchema: {
|
|
996
|
+
inputSchema: z.object({
|
|
997
997
|
message: z
|
|
998
998
|
.string()
|
|
999
999
|
.describe("The original plain text message that was signed."),
|
|
@@ -1012,7 +1012,7 @@ export function registerSigningTools(server) {
|
|
|
1012
1012
|
.optional()
|
|
1013
1013
|
.describe("Optional: alias for address (backward compatibility). " +
|
|
1014
1014
|
"If address is not provided, this is used instead."),
|
|
1015
|
-
},
|
|
1015
|
+
}),
|
|
1016
1016
|
}, async ({ message, signature, address, expectedSigner }) => {
|
|
1017
1017
|
try {
|
|
1018
1018
|
// Use address param, fall back to expectedSigner for backward compat
|
|
@@ -1188,7 +1188,7 @@ export function registerSigningTools(server) {
|
|
|
1188
1188
|
"you need a BIP-340 Schnorr signature over a pre-computed hash (e.g., BIP-341 sighash). " +
|
|
1189
1189
|
"WARNING: This signs raw digests that cannot be human-verified — use confirmBlindSign=true after reviewing the digest. " +
|
|
1190
1190
|
"Returns a 64-byte signature and the x-only public key. Requires an unlocked wallet.",
|
|
1191
|
-
inputSchema: {
|
|
1191
|
+
inputSchema: z.object({
|
|
1192
1192
|
digest: z
|
|
1193
1193
|
.string()
|
|
1194
1194
|
.length(64)
|
|
@@ -1205,7 +1205,7 @@ export function registerSigningTools(server) {
|
|
|
1205
1205
|
.optional()
|
|
1206
1206
|
.describe("Set to true to confirm you have reviewed the digest and accept the risk of signing a raw hash. " +
|
|
1207
1207
|
"Default is false, which returns a warning with the digest for review before signing."),
|
|
1208
|
-
},
|
|
1208
|
+
}),
|
|
1209
1209
|
}, async ({ digest, auxRand, confirmBlindSign }) => {
|
|
1210
1210
|
try {
|
|
1211
1211
|
// Safety gate: require explicit confirmation before signing a raw digest.
|
|
@@ -1257,7 +1257,7 @@ export function registerSigningTools(server) {
|
|
|
1257
1257
|
description: "Verify a BIP-340 Schnorr signature over a 32-byte digest. " +
|
|
1258
1258
|
"Takes the digest, signature, and public key, returns whether the signature is valid. " +
|
|
1259
1259
|
"Use for verifying Taproot signatures from other agents in multisig coordination.",
|
|
1260
|
-
inputSchema: {
|
|
1260
|
+
inputSchema: z.object({
|
|
1261
1261
|
digest: z
|
|
1262
1262
|
.string()
|
|
1263
1263
|
.length(64)
|
|
@@ -1273,7 +1273,7 @@ export function registerSigningTools(server) {
|
|
|
1273
1273
|
.length(64)
|
|
1274
1274
|
.regex(/^[0-9a-fA-F]+$/)
|
|
1275
1275
|
.describe("32-byte hex-encoded x-only public key of the signer"),
|
|
1276
|
-
},
|
|
1276
|
+
}),
|
|
1277
1277
|
}, async ({ digest, signature, publicKey }) => {
|
|
1278
1278
|
try {
|
|
1279
1279
|
// Decode inputs (Zod schema enforces correct hex lengths:
|
|
@@ -1307,7 +1307,7 @@ export function registerSigningTools(server) {
|
|
|
1307
1307
|
"Computes the NIP-01 event ID (SHA-256 of the canonical serialization) and signs it. " +
|
|
1308
1308
|
"Returns the complete signed event ready to publish to Nostr relays. " +
|
|
1309
1309
|
"Requires an unlocked wallet.",
|
|
1310
|
-
inputSchema: {
|
|
1310
|
+
inputSchema: z.object({
|
|
1311
1311
|
kind: z
|
|
1312
1312
|
.number()
|
|
1313
1313
|
.int()
|
|
@@ -1329,7 +1329,7 @@ export function registerSigningTools(server) {
|
|
|
1329
1329
|
.describe("Key to sign with. 'nostr' (default): NIP-06 derived key (m/44'/1237'/0'/0/0). " +
|
|
1330
1330
|
"'taproot': BIP-86 Taproot internal key. " +
|
|
1331
1331
|
"'segwit': SegWit/P2WPKH key (x-only, 32 bytes)."),
|
|
1332
|
-
},
|
|
1332
|
+
}),
|
|
1333
1333
|
}, async ({ kind, content, tags, created_at, keySource }) => {
|
|
1334
1334
|
try {
|
|
1335
1335
|
const account = requireUnlockedWallet();
|
|
@@ -68,6 +68,10 @@ export const TOOL_SKILL_MAP = {
|
|
|
68
68
|
get_stacking_status: "stacking",
|
|
69
69
|
stack_stx: "stacking",
|
|
70
70
|
extend_stacking: "stacking",
|
|
71
|
+
list_stacking_signers: "stacking",
|
|
72
|
+
unstake_stx: "stacking",
|
|
73
|
+
get_stacking_rewards: "stacking",
|
|
74
|
+
claim_stacking_rewards: "stacking",
|
|
71
75
|
// dual-stacking skill — sBTC Dual Stacking yield protocol
|
|
72
76
|
dual_stacking_status: "dual-stacking",
|
|
73
77
|
dual_stacking_get_rewards: "dual-stacking",
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
* Uses child inscription builders for on-chain provenance (parent-child relationship)
|
|
14
14
|
* and Unisat Ordinals API for listing/loading inscriptions.
|
|
15
15
|
*/
|
|
16
|
-
import { McpServer } from "@modelcontextprotocol/
|
|
16
|
+
import { McpServer } from "@modelcontextprotocol/server";
|
|
17
17
|
export declare function registerSouldinalsTools(server: McpServer): void;
|
|
18
18
|
//# sourceMappingURL=souldinals.tools.d.ts.map
|
|
@@ -200,7 +200,7 @@ export function registerSouldinalsTools(server) {
|
|
|
200
200
|
"This broadcasts the commit tx and returns immediately. After it confirms " +
|
|
201
201
|
"(typically 10-60 min), use `souldinals_reveal_soul` to complete.\n\n" +
|
|
202
202
|
"Returns: commitTxid, revealAmount, contentBase64 (save all for souldinals_reveal_soul)",
|
|
203
|
-
inputSchema: {
|
|
203
|
+
inputSchema: z.object({
|
|
204
204
|
parentInscriptionId: z
|
|
205
205
|
.string()
|
|
206
206
|
.describe("Genesis parent inscription ID (format: {txid}i{index}). You must own this inscription."),
|
|
@@ -211,7 +211,7 @@ export function registerSouldinalsTools(server) {
|
|
|
211
211
|
.union([z.enum(["fast", "medium", "slow"]), z.number().positive()])
|
|
212
212
|
.optional()
|
|
213
213
|
.describe("Fee rate: 'fast' (~10 min), 'medium' (~30 min), 'slow' (~1 hr), or number in sat/vB (default: medium)"),
|
|
214
|
-
},
|
|
214
|
+
}),
|
|
215
215
|
}, async ({ parentInscriptionId, soulContent, feeRate }) => {
|
|
216
216
|
try {
|
|
217
217
|
const walletManager = getWalletManager();
|
|
@@ -303,7 +303,7 @@ export function registerSouldinalsTools(server) {
|
|
|
303
303
|
"The reveal tx spends both the commit output and the parent inscription UTXO, " +
|
|
304
304
|
"returning the parent to your address and creating the child soul inscription.\n\n" +
|
|
305
305
|
"Returns: inscriptionId ({revealTxid}i0) on success",
|
|
306
|
-
inputSchema: {
|
|
306
|
+
inputSchema: z.object({
|
|
307
307
|
commitTxid: z
|
|
308
308
|
.string()
|
|
309
309
|
.length(64)
|
|
@@ -322,7 +322,7 @@ export function registerSouldinalsTools(server) {
|
|
|
322
322
|
.union([z.enum(["fast", "medium", "slow"]), z.number().positive()])
|
|
323
323
|
.optional()
|
|
324
324
|
.describe("Fee rate for reveal tx (default: medium)"),
|
|
325
|
-
},
|
|
325
|
+
}),
|
|
326
326
|
}, async ({ commitTxid, revealAmount, contentBase64, parentInscriptionId, feeRate, }) => {
|
|
327
327
|
try {
|
|
328
328
|
const walletManager = getWalletManager();
|
|
@@ -418,12 +418,12 @@ export function registerSouldinalsTools(server) {
|
|
|
418
418
|
"Queries the Unisat Ordinals API for inscriptions with content type text/markdown.\n" +
|
|
419
419
|
"If no address is provided, uses the current wallet's Taproot address.\n\n" +
|
|
420
420
|
"Returns: array of soul inscriptions with id, number, content type, size, and timestamp.",
|
|
421
|
-
inputSchema: {
|
|
421
|
+
inputSchema: z.object({
|
|
422
422
|
address: z
|
|
423
423
|
.string()
|
|
424
424
|
.optional()
|
|
425
425
|
.describe("Taproot (bc1p...) address to query. Omit to use the current wallet's Taproot address."),
|
|
426
|
-
},
|
|
426
|
+
}),
|
|
427
427
|
}, async ({ address }) => {
|
|
428
428
|
try {
|
|
429
429
|
let taprootAddress = address;
|
|
@@ -466,12 +466,12 @@ export function registerSouldinalsTools(server) {
|
|
|
466
466
|
"Fetches the list of soul inscriptions (text/markdown) and returns the content of the " +
|
|
467
467
|
"oldest one. If no address is provided, uses the current wallet's Taproot address.\n\n" +
|
|
468
468
|
"Returns: inscription metadata and full Markdown content.",
|
|
469
|
-
inputSchema: {
|
|
469
|
+
inputSchema: z.object({
|
|
470
470
|
address: z
|
|
471
471
|
.string()
|
|
472
472
|
.optional()
|
|
473
473
|
.describe("Taproot (bc1p...) address to query. Omit to use the current wallet's Taproot address."),
|
|
474
|
-
},
|
|
474
|
+
}),
|
|
475
475
|
}, async ({ address }) => {
|
|
476
476
|
try {
|
|
477
477
|
let taprootAddress = address;
|
|
@@ -520,11 +520,11 @@ export function registerSouldinalsTools(server) {
|
|
|
520
520
|
"- focusAreas: list items under 'Focus' or 'Focus Areas' sections\n" +
|
|
521
521
|
"- sections: all named H2/H3 sections\n\n" +
|
|
522
522
|
"Also returns raw Markdown content.",
|
|
523
|
-
inputSchema: {
|
|
523
|
+
inputSchema: z.object({
|
|
524
524
|
inscriptionId: z
|
|
525
525
|
.string()
|
|
526
526
|
.describe("Inscription ID (format: {txid}i{index})"),
|
|
527
|
-
},
|
|
527
|
+
}),
|
|
528
528
|
}, async ({ inscriptionId }) => {
|
|
529
529
|
try {
|
|
530
530
|
// Fetch metadata and content in parallel
|
|
@@ -85,7 +85,7 @@ all participants recover their original STX contribution.
|
|
|
85
85
|
Returns each pot's contract ID, configuration, current STX value, and lock status.
|
|
86
86
|
|
|
87
87
|
Note: Stackspot is only available on mainnet.`,
|
|
88
|
-
inputSchema: {},
|
|
88
|
+
inputSchema: z.object({}),
|
|
89
89
|
}, async () => {
|
|
90
90
|
try {
|
|
91
91
|
if (NETWORK !== "mainnet") {
|
|
@@ -142,11 +142,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier
|
|
|
142
142
|
(e.g., "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG").
|
|
143
143
|
|
|
144
144
|
Note: Stackspot is only available on mainnet.`,
|
|
145
|
-
inputSchema: {
|
|
145
|
+
inputSchema: z.object({
|
|
146
146
|
contractName: z
|
|
147
147
|
.string()
|
|
148
148
|
.describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
|
|
149
|
-
},
|
|
149
|
+
}),
|
|
150
150
|
}, async ({ contractName }) => {
|
|
151
151
|
try {
|
|
152
152
|
if (NETWORK !== "mainnet") {
|
|
@@ -197,14 +197,14 @@ Amount must be in micro-STX (1 STX = 1,000,000 micro-STX).
|
|
|
197
197
|
Requires an unlocked wallet with sufficient STX balance.
|
|
198
198
|
|
|
199
199
|
Note: Stackspot is only available on mainnet.`,
|
|
200
|
-
inputSchema: {
|
|
200
|
+
inputSchema: z.object({
|
|
201
201
|
contractName: z
|
|
202
202
|
.string()
|
|
203
203
|
.describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
|
|
204
204
|
amount: z
|
|
205
205
|
.string()
|
|
206
206
|
.describe("Amount to contribute in micro-STX (1 STX = 1,000,000 micro-STX)"),
|
|
207
|
-
},
|
|
207
|
+
}),
|
|
208
208
|
}, async ({ contractName, amount }) => {
|
|
209
209
|
try {
|
|
210
210
|
if (NETWORK !== "mainnet") {
|
|
@@ -278,11 +278,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier.
|
|
|
278
278
|
Requires an unlocked wallet.
|
|
279
279
|
|
|
280
280
|
Note: Stackspot is only available on mainnet.`,
|
|
281
|
-
inputSchema: {
|
|
281
|
+
inputSchema: z.object({
|
|
282
282
|
contractName: z
|
|
283
283
|
.string()
|
|
284
284
|
.describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
|
|
285
|
-
},
|
|
285
|
+
}),
|
|
286
286
|
}, async ({ contractName }) => {
|
|
287
287
|
try {
|
|
288
288
|
if (NETWORK !== "mainnet") {
|
|
@@ -331,11 +331,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier.
|
|
|
331
331
|
Requires an unlocked wallet.
|
|
332
332
|
|
|
333
333
|
Note: Stackspot is only available on mainnet.`,
|
|
334
|
-
inputSchema: {
|
|
334
|
+
inputSchema: z.object({
|
|
335
335
|
contractName: z
|
|
336
336
|
.string()
|
|
337
337
|
.describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
|
|
338
|
-
},
|
|
338
|
+
}),
|
|
339
339
|
}, async ({ contractName }) => {
|
|
340
340
|
try {
|
|
341
341
|
if (NETWORK !== "mainnet") {
|
|
@@ -385,11 +385,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier.
|
|
|
385
385
|
Requires an unlocked wallet.
|
|
386
386
|
|
|
387
387
|
Note: Stackspot is only available on mainnet.`,
|
|
388
|
-
inputSchema: {
|
|
388
|
+
inputSchema: z.object({
|
|
389
389
|
contractName: z
|
|
390
390
|
.string()
|
|
391
391
|
.describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
|
|
392
|
-
},
|
|
392
|
+
}),
|
|
393
393
|
}, async ({ contractName }) => {
|
|
394
394
|
try {
|
|
395
395
|
if (NETWORK !== "mainnet") {
|