@aibtc/mcp-server 1.33.4 → 1.35.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/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +36 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/relay-diagnostic.tools.d.ts.map +1 -1
- package/dist/tools/relay-diagnostic.tools.js +67 -4
- package/dist/tools/relay-diagnostic.tools.js.map +1 -1
- package/dist/tools/skill-mappings.d.ts +15 -0
- package/dist/tools/skill-mappings.d.ts.map +1 -0
- package/dist/tools/skill-mappings.js +229 -0
- package/dist/tools/skill-mappings.js.map +1 -0
- package/dist/tools/styx.tools.d.ts +20 -0
- package/dist/tools/styx.tools.d.ts.map +1 -0
- package/dist/tools/styx.tools.js +401 -0
- package/dist/tools/styx.tools.js.map +1 -0
- package/dist/utils/relay-health.d.ts +28 -0
- package/dist/utils/relay-health.d.ts.map +1 -1
- package/dist/utils/relay-health.js +157 -7
- package/dist/utils/relay-health.js.map +1 -1
- package/package.json +2 -1
- package/skill/SKILL.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqDpE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmExD"}
|
package/dist/tools/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { registerTokenTools } from "./tokens.tools.js";
|
|
|
7
7
|
import { registerNftTools } from "./nft.tools.js";
|
|
8
8
|
import { registerStackingTools } from "./stacking.tools.js";
|
|
9
9
|
import { registerBnsTools } from "./bns.tools.js";
|
|
10
|
+
import { registerStyxTools } from "./styx.tools.js";
|
|
10
11
|
import { registerQueryTools } from "./query.tools.js";
|
|
11
12
|
import { registerEndpointTools } from "./endpoint.tools.js";
|
|
12
13
|
import { registerDefiTools } from "./defi.tools.js";
|
|
@@ -18,10 +19,40 @@ import { registerYieldHunterTools } from "./yield-hunter.tools.js";
|
|
|
18
19
|
import { registerPillarTools } from "./pillar.tools.js";
|
|
19
20
|
import { registerPillarDirectTools } from "./pillar-direct.tools.js";
|
|
20
21
|
import { registerBitcoinTools } from "./bitcoin.tools.js";
|
|
22
|
+
import { registerRelayDiagnosticTools } from "./relay-diagnostic.tools.js";
|
|
23
|
+
import { getSkillForTool } from "./skill-mappings.js";
|
|
24
|
+
/**
|
|
25
|
+
* Wraps server.registerTool to inject _meta.skill from TOOL_SKILL_MAP when a mapping exists.
|
|
26
|
+
* Returns a cleanup function that restores the original method.
|
|
27
|
+
*/
|
|
28
|
+
function withSkillMeta(server) {
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
const original = server.registerTool;
|
|
31
|
+
const hasOwn = Object.prototype.hasOwnProperty.call(server, "registerTool");
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
server.registerTool = function (name, config, cb) {
|
|
34
|
+
const skill = getSkillForTool(name);
|
|
35
|
+
const patched = skill
|
|
36
|
+
? { ...config, _meta: { ...(config._meta ?? {}), skill } }
|
|
37
|
+
: config;
|
|
38
|
+
return original.call(server, name, patched, cb);
|
|
39
|
+
};
|
|
40
|
+
return () => {
|
|
41
|
+
if (hasOwn) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
server.registerTool = original;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
+
delete server.registerTool;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
21
51
|
/**
|
|
22
52
|
* Register all tools with the MCP server
|
|
23
53
|
*/
|
|
24
54
|
export function registerAllTools(server) {
|
|
55
|
+
const restoreRegisterTool = withSkillMeta(server);
|
|
25
56
|
// Wallet & Balance
|
|
26
57
|
registerWalletTools(server);
|
|
27
58
|
// Wallet Management (create, import, unlock, lock, etc.)
|
|
@@ -48,6 +79,8 @@ export function registerAllTools(server) {
|
|
|
48
79
|
registerDefiTools(server);
|
|
49
80
|
// Bitflow DEX (disabled until API key integration is complete)
|
|
50
81
|
// registerBitflowTools(server);
|
|
82
|
+
// Styx BTC→sBTC conversion
|
|
83
|
+
registerStyxTools(server);
|
|
51
84
|
// Scaffolding (generate x402 endpoint projects)
|
|
52
85
|
registerScaffoldTools(server);
|
|
53
86
|
// OpenRouter AI (call AI models directly)
|
|
@@ -60,5 +93,8 @@ export function registerAllTools(server) {
|
|
|
60
93
|
registerPillarDirectTools(server);
|
|
61
94
|
// Bitcoin L1 (read-only: balance, fees, UTXOs)
|
|
62
95
|
registerBitcoinTools(server);
|
|
96
|
+
// Relay Diagnostics (sponsor relay health, nonce status, stuck transactions)
|
|
97
|
+
registerRelayDiagnosticTools(server);
|
|
98
|
+
restoreRegisterTool();
|
|
63
99
|
}
|
|
64
100
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,+DAA+D;AAC/D,6DAA6D;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-diagnostic.tools.d.ts","sourceRoot":"","sources":["../../src/tools/relay-diagnostic.tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-diagnostic.tools.d.ts","sourceRoot":"","sources":["../../src/tools/relay-diagnostic.tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuGpE"}
|
|
@@ -3,20 +3,25 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Tools for checking sponsor relay health and diagnosing nonce issues
|
|
5
5
|
*/
|
|
6
|
+
import { z } from "zod";
|
|
6
7
|
import { createJsonResponse, createErrorResponse } from "../utils/index.js";
|
|
7
|
-
import { checkRelayHealth, formatRelayHealthStatus } from "../utils/relay-health.js";
|
|
8
|
+
import { checkRelayHealth, formatRelayHealthStatus, attemptRbf, attemptFillGaps } from "../utils/relay-health.js";
|
|
8
9
|
import { NETWORK } from "../services/x402.service.js";
|
|
10
|
+
import { getWalletManager } from "../services/wallet-manager.js";
|
|
9
11
|
export function registerRelayDiagnosticTools(server) {
|
|
10
12
|
server.registerTool("check_relay_health", {
|
|
11
13
|
description: `Check the sponsor relay health and nonce status.
|
|
12
14
|
|
|
13
|
-
Use this tool to diagnose
|
|
15
|
+
Use this tool to diagnose sponsored transaction failures. It will:
|
|
14
16
|
- Check relay availability
|
|
15
17
|
- Inspect sponsor address nonce state
|
|
16
18
|
- Detect nonce gaps that block transactions
|
|
19
|
+
- Detect mempool desync (confirmed nonce far behind mempool nonce)
|
|
20
|
+
- List stuck transactions with txid, nonce, and how long they have been pending
|
|
17
21
|
- Report mempool congestion
|
|
18
22
|
|
|
19
|
-
If nonce gaps are detected,
|
|
23
|
+
If nonce gaps or stuck transactions are detected, the output includes
|
|
24
|
+
txids and pending durations to share with the AIBTC team for recovery.`,
|
|
20
25
|
inputSchema: {},
|
|
21
26
|
}, async () => {
|
|
22
27
|
try {
|
|
@@ -27,7 +32,65 @@ If nonce gaps are detected, wait for AIBTC team to clear them before retrying se
|
|
|
27
32
|
});
|
|
28
33
|
}
|
|
29
34
|
catch (error) {
|
|
30
|
-
return createErrorResponse(error
|
|
35
|
+
return createErrorResponse(error);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
server.registerTool("recover_sponsor_nonce", {
|
|
39
|
+
description: `Attempt automated recovery of stuck sponsor transactions via the relay API.
|
|
40
|
+
|
|
41
|
+
Run check_relay_health first to identify stuck txids and missing nonces, then use
|
|
42
|
+
this tool to trigger recovery without needing to contact the AIBTC team manually.
|
|
43
|
+
|
|
44
|
+
Two recovery modes are available:
|
|
45
|
+
- rbf: Replace-by-fee — rebroadcasts stuck transactions with a higher fee so miners
|
|
46
|
+
prioritize them. Provide specific txids or omit to bump all stuck transactions.
|
|
47
|
+
- fill-gaps: Nonce gap-fill — submits placeholder transactions to fill any missing
|
|
48
|
+
nonces that are blocking the queue. Provide specific nonces or omit to fill all gaps.
|
|
49
|
+
- both: Attempt both RBF and gap-fill in sequence (default).
|
|
50
|
+
|
|
51
|
+
If the relay does not yet support these endpoints it returns a 404 or 501 and this
|
|
52
|
+
tool will respond with a clear message rather than throwing an error. In that case,
|
|
53
|
+
share the txids and nonces from check_relay_health with the AIBTC team.`,
|
|
54
|
+
inputSchema: {
|
|
55
|
+
action: z
|
|
56
|
+
.enum(["rbf", "fill-gaps", "both"])
|
|
57
|
+
.default("both")
|
|
58
|
+
.describe("Which recovery operation to attempt"),
|
|
59
|
+
txids: z
|
|
60
|
+
.array(z.string())
|
|
61
|
+
.optional()
|
|
62
|
+
.describe("Specific stuck transaction IDs for RBF (omit to bump all stuck txs)"),
|
|
63
|
+
nonces: z
|
|
64
|
+
.array(z.number().int().nonnegative())
|
|
65
|
+
.optional()
|
|
66
|
+
.describe("Specific missing nonces for gap-fill (omit to fill all detected gaps)"),
|
|
67
|
+
},
|
|
68
|
+
}, async ({ action = "both", txids, nonces }) => {
|
|
69
|
+
try {
|
|
70
|
+
// Resolve API key from wallet (if unlocked) to align with sponsor-builder auth flow
|
|
71
|
+
const walletAccount = getWalletManager().getAccount();
|
|
72
|
+
const walletApiKey = walletAccount?.sponsorApiKey;
|
|
73
|
+
const results = { action };
|
|
74
|
+
if (action === "rbf" || action === "both") {
|
|
75
|
+
const rbfResult = await attemptRbf(NETWORK, txids, walletApiKey);
|
|
76
|
+
results.rbf = rbfResult;
|
|
77
|
+
}
|
|
78
|
+
if (action === "fill-gaps" || action === "both") {
|
|
79
|
+
const fillResult = await attemptFillGaps(NETWORK, nonces, walletApiKey);
|
|
80
|
+
results.fillGaps = fillResult;
|
|
81
|
+
}
|
|
82
|
+
// Summarize outcome
|
|
83
|
+
const anyUnsupported = Object.values(results).some((r) => r && typeof r === "object" && "supported" in r && !r.supported);
|
|
84
|
+
const anySupported = Object.values(results).some((r) => r && typeof r === "object" && "supported" in r && r.supported);
|
|
85
|
+
results.summary = anySupported
|
|
86
|
+
? "Recovery request submitted to relay. Run check_relay_health to verify nonce state improved."
|
|
87
|
+
: anyUnsupported
|
|
88
|
+
? "Relay does not yet support automated recovery. Run check_relay_health for txids and nonces to share with the AIBTC team."
|
|
89
|
+
: "Recovery attempted.";
|
|
90
|
+
return createJsonResponse(results);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return createErrorResponse(error);
|
|
31
94
|
}
|
|
32
95
|
});
|
|
33
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-diagnostic.tools.js","sourceRoot":"","sources":["../../src/tools/relay-diagnostic.tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-diagnostic.tools.js","sourceRoot":"","sources":["../../src/tools/relay-diagnostic.tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill reference mappings for MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Maps each MCP tool name to its corresponding skill in the aibtcdev/skills repository.
|
|
5
|
+
* Skills are loaded via the /skill command in Claude Code and provide higher-level
|
|
6
|
+
* orchestration logic built on top of these MCP tools.
|
|
7
|
+
*
|
|
8
|
+
* Skill source: https://github.com/aibtcdev/skills
|
|
9
|
+
*/
|
|
10
|
+
export declare const TOOL_SKILL_MAP: Record<string, string>;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the skill name for a given MCP tool name, or undefined if no mapping exists.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getSkillForTool(toolName: string): string | undefined;
|
|
15
|
+
//# sourceMappingURL=skill-mappings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-mappings.d.ts","sourceRoot":"","sources":["../../src/tools/skill-mappings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA0OjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpE"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill reference mappings for MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Maps each MCP tool name to its corresponding skill in the aibtcdev/skills repository.
|
|
5
|
+
* Skills are loaded via the /skill command in Claude Code and provide higher-level
|
|
6
|
+
* orchestration logic built on top of these MCP tools.
|
|
7
|
+
*
|
|
8
|
+
* Skill source: https://github.com/aibtcdev/skills
|
|
9
|
+
*/
|
|
10
|
+
export const TOOL_SKILL_MAP = {
|
|
11
|
+
// wallet skill — encrypted BIP39 wallet management
|
|
12
|
+
get_wallet_info: "wallet",
|
|
13
|
+
wallet_create: "wallet",
|
|
14
|
+
wallet_import: "wallet",
|
|
15
|
+
wallet_unlock: "wallet",
|
|
16
|
+
wallet_lock: "wallet",
|
|
17
|
+
wallet_list: "wallet",
|
|
18
|
+
wallet_switch: "wallet",
|
|
19
|
+
wallet_delete: "wallet",
|
|
20
|
+
wallet_export: "wallet",
|
|
21
|
+
wallet_rotate_password: "wallet",
|
|
22
|
+
wallet_set_timeout: "wallet",
|
|
23
|
+
wallet_status: "wallet",
|
|
24
|
+
// stx skill — STX transfers and Stacks contract operations
|
|
25
|
+
get_stx_balance: "stx",
|
|
26
|
+
transfer_stx: "stx",
|
|
27
|
+
broadcast_transaction: "stx",
|
|
28
|
+
call_contract: "stx",
|
|
29
|
+
deploy_contract: "stx",
|
|
30
|
+
get_transaction_status: "stx",
|
|
31
|
+
// btc skill — Bitcoin L1 operations
|
|
32
|
+
get_btc_balance: "btc",
|
|
33
|
+
get_btc_fees: "btc",
|
|
34
|
+
get_btc_utxos: "btc",
|
|
35
|
+
transfer_btc: "btc",
|
|
36
|
+
get_cardinal_utxos: "btc",
|
|
37
|
+
get_ordinal_utxos: "btc",
|
|
38
|
+
get_inscriptions_by_address: "btc",
|
|
39
|
+
// sbtc skill — sBTC token operations
|
|
40
|
+
sbtc_get_balance: "sbtc",
|
|
41
|
+
sbtc_transfer: "sbtc",
|
|
42
|
+
sbtc_get_deposit_info: "sbtc",
|
|
43
|
+
sbtc_get_peg_info: "sbtc",
|
|
44
|
+
sbtc_deposit: "sbtc",
|
|
45
|
+
sbtc_deposit_status: "sbtc",
|
|
46
|
+
sbtc_initiate_withdrawal: "sbtc",
|
|
47
|
+
sbtc_withdraw: "sbtc",
|
|
48
|
+
sbtc_withdrawal_status: "sbtc",
|
|
49
|
+
sbtc_withdraw_status: "sbtc",
|
|
50
|
+
// tokens skill — SIP-010 fungible token operations
|
|
51
|
+
get_token_balance: "tokens",
|
|
52
|
+
get_token_info: "tokens",
|
|
53
|
+
list_user_tokens: "tokens",
|
|
54
|
+
get_token_holders: "tokens",
|
|
55
|
+
transfer_token: "tokens",
|
|
56
|
+
// nft skill — SIP-009 NFT operations
|
|
57
|
+
get_nft_holdings: "nft",
|
|
58
|
+
get_nft_metadata: "nft",
|
|
59
|
+
transfer_nft: "nft",
|
|
60
|
+
get_nft_owner: "nft",
|
|
61
|
+
get_collection_info: "nft",
|
|
62
|
+
get_nft_history: "nft",
|
|
63
|
+
// stacking skill — STX stacking and PoX operations
|
|
64
|
+
get_pox_info: "stacking",
|
|
65
|
+
get_stacking_status: "stacking",
|
|
66
|
+
stack_stx: "stacking",
|
|
67
|
+
extend_stacking: "stacking",
|
|
68
|
+
// bns skill — Bitcoin Name System operations
|
|
69
|
+
lookup_bns_name: "bns",
|
|
70
|
+
reverse_bns_lookup: "bns",
|
|
71
|
+
get_bns_info: "bns",
|
|
72
|
+
check_bns_availability: "bns",
|
|
73
|
+
get_bns_price: "bns",
|
|
74
|
+
list_user_domains: "bns",
|
|
75
|
+
claim_bns_name_fast: "bns",
|
|
76
|
+
preorder_bns_name: "bns",
|
|
77
|
+
register_bns_name: "bns",
|
|
78
|
+
// query skill — Stacks network and blockchain queries
|
|
79
|
+
get_stx_fees: "query",
|
|
80
|
+
get_account_info: "query",
|
|
81
|
+
get_account_transactions: "query",
|
|
82
|
+
get_block_info: "query",
|
|
83
|
+
get_mempool_info: "query",
|
|
84
|
+
get_contract_info: "query",
|
|
85
|
+
get_contract_events: "query",
|
|
86
|
+
get_network_status: "query",
|
|
87
|
+
call_read_only_function: "query",
|
|
88
|
+
// x402 skill — x402 paid endpoints, inbox, scaffolding, OpenRouter
|
|
89
|
+
list_x402_endpoints: "x402",
|
|
90
|
+
execute_x402_endpoint: "x402",
|
|
91
|
+
probe_x402_endpoint: "x402",
|
|
92
|
+
scaffold_x402_endpoint: "x402",
|
|
93
|
+
scaffold_x402_ai_endpoint: "x402",
|
|
94
|
+
openrouter_integration_guide: "x402",
|
|
95
|
+
openrouter_models: "x402",
|
|
96
|
+
send_inbox_message: "x402",
|
|
97
|
+
// defi skill — ALEX DEX and Zest Protocol
|
|
98
|
+
alex_list_pools: "defi",
|
|
99
|
+
alex_get_swap_quote: "defi",
|
|
100
|
+
alex_swap: "defi",
|
|
101
|
+
alex_get_pool_info: "defi",
|
|
102
|
+
zest_list_assets: "defi",
|
|
103
|
+
zest_get_position: "defi",
|
|
104
|
+
zest_supply: "defi",
|
|
105
|
+
zest_withdraw: "defi",
|
|
106
|
+
zest_borrow: "defi",
|
|
107
|
+
zest_repay: "defi",
|
|
108
|
+
// styx skill — BTC→sBTC conversion via Styx protocol
|
|
109
|
+
styx_pool_status: "styx",
|
|
110
|
+
styx_pools: "styx",
|
|
111
|
+
styx_fees: "styx",
|
|
112
|
+
styx_price: "styx",
|
|
113
|
+
styx_deposit: "styx",
|
|
114
|
+
styx_status: "styx",
|
|
115
|
+
styx_history: "styx",
|
|
116
|
+
// yield-hunter skill — autonomous sBTC yield farming daemon
|
|
117
|
+
yield_hunter_start: "yield-hunter",
|
|
118
|
+
yield_hunter_stop: "yield-hunter",
|
|
119
|
+
yield_hunter_status: "yield-hunter",
|
|
120
|
+
yield_hunter_configure: "yield-hunter",
|
|
121
|
+
// pillar skill — Pillar smart wallet (browser-handoff + agent-signed direct modes)
|
|
122
|
+
pillar_connect: "pillar",
|
|
123
|
+
pillar_disconnect: "pillar",
|
|
124
|
+
pillar_status: "pillar",
|
|
125
|
+
pillar_send: "pillar",
|
|
126
|
+
pillar_fund: "pillar",
|
|
127
|
+
pillar_add_admin: "pillar",
|
|
128
|
+
pillar_supply: "pillar",
|
|
129
|
+
pillar_auto_compound: "pillar",
|
|
130
|
+
pillar_unwind: "pillar",
|
|
131
|
+
pillar_boost: "pillar",
|
|
132
|
+
pillar_position: "pillar",
|
|
133
|
+
pillar_create_wallet: "pillar",
|
|
134
|
+
pillar_invite: "pillar",
|
|
135
|
+
pillar_dca_invite: "pillar",
|
|
136
|
+
pillar_dca_partners: "pillar",
|
|
137
|
+
pillar_dca_leaderboard: "pillar",
|
|
138
|
+
pillar_dca_status: "pillar",
|
|
139
|
+
pillar_key_generate: "pillar",
|
|
140
|
+
pillar_key_unlock: "pillar",
|
|
141
|
+
pillar_key_lock: "pillar",
|
|
142
|
+
pillar_key_info: "pillar",
|
|
143
|
+
pillar_direct_boost: "pillar",
|
|
144
|
+
pillar_direct_unwind: "pillar",
|
|
145
|
+
pillar_direct_supply: "pillar",
|
|
146
|
+
pillar_direct_send: "pillar",
|
|
147
|
+
pillar_direct_auto_compound: "pillar",
|
|
148
|
+
pillar_direct_position: "pillar",
|
|
149
|
+
pillar_direct_withdraw_collateral: "pillar",
|
|
150
|
+
pillar_direct_add_admin: "pillar",
|
|
151
|
+
pillar_direct_create_wallet: "pillar",
|
|
152
|
+
pillar_direct_dca_invite: "pillar",
|
|
153
|
+
pillar_direct_dca_partners: "pillar",
|
|
154
|
+
pillar_direct_dca_leaderboard: "pillar",
|
|
155
|
+
pillar_direct_dca_status: "pillar",
|
|
156
|
+
pillar_direct_quote: "pillar",
|
|
157
|
+
pillar_direct_resolve_recipient: "pillar",
|
|
158
|
+
pillar_direct_stack_stx: "pillar",
|
|
159
|
+
pillar_direct_revoke_fast_pool: "pillar",
|
|
160
|
+
pillar_direct_stacking_status: "pillar",
|
|
161
|
+
// settings skill — MCP server configuration and relay health
|
|
162
|
+
set_hiro_api_key: "settings",
|
|
163
|
+
get_hiro_api_key: "settings",
|
|
164
|
+
delete_hiro_api_key: "settings",
|
|
165
|
+
set_stacks_api_url: "settings",
|
|
166
|
+
get_stacks_api_url: "settings",
|
|
167
|
+
delete_stacks_api_url: "settings",
|
|
168
|
+
get_server_version: "settings",
|
|
169
|
+
check_relay_health: "settings",
|
|
170
|
+
recover_sponsor_nonce: "settings",
|
|
171
|
+
// signing skill — message signing and verification
|
|
172
|
+
stacks_sign_message: "signing",
|
|
173
|
+
stacks_verify_message: "signing",
|
|
174
|
+
btc_sign_message: "signing",
|
|
175
|
+
btc_verify_message: "signing",
|
|
176
|
+
schnorr_sign_digest: "signing",
|
|
177
|
+
schnorr_verify_digest: "signing",
|
|
178
|
+
nostr_sign_event: "signing",
|
|
179
|
+
// ordinals skill — Bitcoin ordinals inscription operations
|
|
180
|
+
get_taproot_address: "ordinals",
|
|
181
|
+
estimate_inscription_fee: "ordinals",
|
|
182
|
+
inscribe: "ordinals",
|
|
183
|
+
inscribe_reveal: "ordinals",
|
|
184
|
+
get_inscription: "ordinals",
|
|
185
|
+
inscribe_child: "ordinals",
|
|
186
|
+
inscribe_child_reveal: "ordinals",
|
|
187
|
+
estimate_child_inscription_fee: "ordinals",
|
|
188
|
+
// ordinals-p2p skill — peer-to-peer ordinals trading via PSBT
|
|
189
|
+
psbt_decode: "ordinals-p2p",
|
|
190
|
+
psbt_sign: "ordinals-p2p",
|
|
191
|
+
psbt_broadcast: "ordinals-p2p",
|
|
192
|
+
psbt_create_ordinal_buy: "ordinals-p2p",
|
|
193
|
+
// identity skill — ERC-8004 on-chain agent identity
|
|
194
|
+
register_identity: "identity",
|
|
195
|
+
get_identity: "identity",
|
|
196
|
+
// reputation skill — ERC-8004 on-chain agent reputation
|
|
197
|
+
give_feedback: "reputation",
|
|
198
|
+
get_reputation: "reputation",
|
|
199
|
+
// validation skill — ERC-8004 on-chain agent validation
|
|
200
|
+
request_validation: "validation",
|
|
201
|
+
get_validation_status: "validation",
|
|
202
|
+
get_validation_summary: "validation",
|
|
203
|
+
// stackspot skill — stacking lottery pots
|
|
204
|
+
stackspot_list_pots: "stackspot",
|
|
205
|
+
stackspot_get_pot_state: "stackspot",
|
|
206
|
+
stackspot_join_pot: "stackspot",
|
|
207
|
+
stackspot_start_pot: "stackspot",
|
|
208
|
+
stackspot_claim_rewards: "stackspot",
|
|
209
|
+
stackspot_cancel_pot: "stackspot",
|
|
210
|
+
// bitflow skill — Bitflow DEX aggregator
|
|
211
|
+
bitflow_get_ticker: "bitflow",
|
|
212
|
+
bitflow_get_tokens: "bitflow",
|
|
213
|
+
bitflow_get_swap_targets: "bitflow",
|
|
214
|
+
bitflow_get_quote: "bitflow",
|
|
215
|
+
bitflow_get_routes: "bitflow",
|
|
216
|
+
bitflow_swap: "bitflow",
|
|
217
|
+
bitflow_get_keeper_contract: "bitflow",
|
|
218
|
+
bitflow_create_order: "bitflow",
|
|
219
|
+
bitflow_get_order: "bitflow",
|
|
220
|
+
bitflow_cancel_order: "bitflow",
|
|
221
|
+
bitflow_get_keeper_user: "bitflow",
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Returns the skill name for a given MCP tool name, or undefined if no mapping exists.
|
|
225
|
+
*/
|
|
226
|
+
export function getSkillForTool(toolName) {
|
|
227
|
+
return TOOL_SKILL_MAP[toolName];
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=skill-mappings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-mappings.js","sourceRoot":"","sources":["../../src/tools/skill-mappings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Styx BTC→sBTC conversion tools
|
|
3
|
+
*
|
|
4
|
+
* Headless BTC→sBTC conversion via the Styx protocol (btc2sbtc.com).
|
|
5
|
+
* Uses @faktoryfun/styx-sdk for deposit reservation and tracking,
|
|
6
|
+
* @scure/btc-signer for local PSBT construction and signing,
|
|
7
|
+
* mempool.space for broadcast.
|
|
8
|
+
*
|
|
9
|
+
* Tools:
|
|
10
|
+
* - styx_pool_status: Pool liquidity info
|
|
11
|
+
* - styx_pools: All available pools
|
|
12
|
+
* - styx_fees: Bitcoin fee estimates
|
|
13
|
+
* - styx_price: BTC price in USD
|
|
14
|
+
* - styx_deposit: Full headless deposit flow
|
|
15
|
+
* - styx_status: Deposit status by ID or txid
|
|
16
|
+
* - styx_history: Deposit history for a Stacks address
|
|
17
|
+
*/
|
|
18
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
19
|
+
export declare function registerStyxTools(server: McpServer): void;
|
|
20
|
+
//# sourceMappingURL=styx.tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styx.tools.d.ts","sourceRoot":"","sources":["../../src/tools/styx.tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2BpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0bzD"}
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Styx BTC→sBTC conversion tools
|
|
3
|
+
*
|
|
4
|
+
* Headless BTC→sBTC conversion via the Styx protocol (btc2sbtc.com).
|
|
5
|
+
* Uses @faktoryfun/styx-sdk for deposit reservation and tracking,
|
|
6
|
+
* @scure/btc-signer for local PSBT construction and signing,
|
|
7
|
+
* mempool.space for broadcast.
|
|
8
|
+
*
|
|
9
|
+
* Tools:
|
|
10
|
+
* - styx_pool_status: Pool liquidity info
|
|
11
|
+
* - styx_pools: All available pools
|
|
12
|
+
* - styx_fees: Bitcoin fee estimates
|
|
13
|
+
* - styx_price: BTC price in USD
|
|
14
|
+
* - styx_deposit: Full headless deposit flow
|
|
15
|
+
* - styx_status: Deposit status by ID or txid
|
|
16
|
+
* - styx_history: Deposit history for a Stacks address
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
import * as btc from "@scure/btc-signer";
|
|
20
|
+
import { hex } from "@scure/base";
|
|
21
|
+
import { styxSDK, MIN_DEPOSIT_SATS, } from "@faktoryfun/styx-sdk";
|
|
22
|
+
import { NETWORK } from "../config/networks.js";
|
|
23
|
+
import { createJsonResponse, createErrorResponse } from "../utils/index.js";
|
|
24
|
+
import { getWalletManager } from "../services/wallet-manager.js";
|
|
25
|
+
import { MempoolApi, getMempoolTxUrl } from "../services/mempool-api.js";
|
|
26
|
+
import { OrdinalIndexer } from "../services/ordinal-indexer.js";
|
|
27
|
+
const FEE_PRIORITIES = ["low", "medium", "high"];
|
|
28
|
+
function getBtcNetwork() {
|
|
29
|
+
return NETWORK === "testnet" ? btc.TEST_NETWORK : btc.NETWORK;
|
|
30
|
+
}
|
|
31
|
+
export function registerStyxTools(server) {
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// styx_pool_status
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
server.registerTool("styx_pool_status", {
|
|
36
|
+
description: "Get current Styx pool liquidity and status. " +
|
|
37
|
+
"Shows realAvailable and estimatedAvailable BTC in the pool.",
|
|
38
|
+
inputSchema: {
|
|
39
|
+
pool: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Pool ID: "main" (300k sat max) or "aibtc" (1M sat max). Defaults to "main".'),
|
|
43
|
+
},
|
|
44
|
+
}, async ({ pool = "main" }) => {
|
|
45
|
+
try {
|
|
46
|
+
const status = await styxSDK.getPoolStatus(pool);
|
|
47
|
+
return createJsonResponse({
|
|
48
|
+
pool,
|
|
49
|
+
realAvailable: status.realAvailable,
|
|
50
|
+
estimatedAvailable: status.estimatedAvailable,
|
|
51
|
+
estimatedAvailableSats: Math.round(status.estimatedAvailable * 1e8),
|
|
52
|
+
lastUpdated: status.lastUpdated,
|
|
53
|
+
network: NETWORK,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return createErrorResponse(error);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// styx_pools
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
server.registerTool("styx_pools", {
|
|
64
|
+
description: "List all available Styx pools with their configurations. " +
|
|
65
|
+
"Pools: main (up to 300k sats, sbtc/usda/pepe), aibtc (up to 1M sats, sbtc/aibtc). " +
|
|
66
|
+
"Minimum deposit: 10,000 sats for both pools.",
|
|
67
|
+
inputSchema: {},
|
|
68
|
+
}, async () => {
|
|
69
|
+
try {
|
|
70
|
+
const pools = await styxSDK.getAvailablePools();
|
|
71
|
+
return createJsonResponse({ pools, network: NETWORK });
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
return createErrorResponse(error);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// styx_fees
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
server.registerTool("styx_fees", {
|
|
81
|
+
description: "Get current Bitcoin network fee estimates (sat/vB) from Styx: low, medium, high.",
|
|
82
|
+
inputSchema: {},
|
|
83
|
+
}, async () => {
|
|
84
|
+
try {
|
|
85
|
+
const fees = await styxSDK.getFeeEstimates();
|
|
86
|
+
return createJsonResponse({ ...fees, network: NETWORK });
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return createErrorResponse(error);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// styx_price
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
server.registerTool("styx_price", {
|
|
96
|
+
description: "Get current BTC price in USD from Styx.",
|
|
97
|
+
inputSchema: {},
|
|
98
|
+
}, async () => {
|
|
99
|
+
try {
|
|
100
|
+
const price = await styxSDK.getBTCPrice();
|
|
101
|
+
return createJsonResponse({ priceUsd: price, network: NETWORK });
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return createErrorResponse(error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// styx_deposit
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
server.registerTool("styx_deposit", {
|
|
111
|
+
description: "Full headless BTC→sBTC deposit via the Styx protocol. " +
|
|
112
|
+
"Flow: reserve pool liquidity → build PSBT locally → sign with wallet keys → " +
|
|
113
|
+
"broadcast to mempool.space → update deposit status. " +
|
|
114
|
+
"Requires an unlocked wallet with sufficient BTC balance. " +
|
|
115
|
+
"On mainnet, ordinal UTXOs are automatically filtered out to protect inscriptions. " +
|
|
116
|
+
"Minimum deposit: 10,000 sats. Pool limits: main=300k sats, aibtc=1M sats.",
|
|
117
|
+
inputSchema: {
|
|
118
|
+
amount: z
|
|
119
|
+
.coerce
|
|
120
|
+
.number()
|
|
121
|
+
.int()
|
|
122
|
+
.min(MIN_DEPOSIT_SATS)
|
|
123
|
+
.describe(`Amount to deposit in satoshis (min ${MIN_DEPOSIT_SATS}). Example: 50000`),
|
|
124
|
+
stxReceiver: z
|
|
125
|
+
.string()
|
|
126
|
+
.optional()
|
|
127
|
+
.describe("Stacks address to receive sBTC. Uses active wallet address if omitted."),
|
|
128
|
+
btcSender: z
|
|
129
|
+
.string()
|
|
130
|
+
.optional()
|
|
131
|
+
.describe("BTC address sending funds. Must match the active wallet's BTC address. " +
|
|
132
|
+
"Uses active wallet if omitted."),
|
|
133
|
+
pool: z
|
|
134
|
+
.string()
|
|
135
|
+
.optional()
|
|
136
|
+
.describe('Pool ID: "main" or "aibtc". Defaults to "main".'),
|
|
137
|
+
fee: z
|
|
138
|
+
.enum(["low", "medium", "high"])
|
|
139
|
+
.optional()
|
|
140
|
+
.describe('Fee priority: "low", "medium", or "high". Defaults to "medium".'),
|
|
141
|
+
},
|
|
142
|
+
}, async ({ amount, stxReceiver, btcSender, pool = "main", fee = "medium" }) => {
|
|
143
|
+
let depositId;
|
|
144
|
+
let broadcastTxid;
|
|
145
|
+
try {
|
|
146
|
+
// amount is validated by z.coerce.number().int().min(MIN_DEPOSIT_SATS) — no manual checks needed
|
|
147
|
+
const amountSats = amount;
|
|
148
|
+
// Validate fee priority (belt-and-suspenders since zod enum already validates)
|
|
149
|
+
const feePriority = fee;
|
|
150
|
+
if (!FEE_PRIORITIES.includes(feePriority)) {
|
|
151
|
+
throw new Error(`Invalid fee value "${fee}". Must be one of: ${FEE_PRIORITIES.join(", ")}`);
|
|
152
|
+
}
|
|
153
|
+
// Get wallet
|
|
154
|
+
const walletManager = getWalletManager();
|
|
155
|
+
const account = walletManager.getActiveAccount();
|
|
156
|
+
if (!account) {
|
|
157
|
+
throw new Error("Wallet is not unlocked. Unlock your wallet first.");
|
|
158
|
+
}
|
|
159
|
+
if (!account.btcAddress || !account.btcPrivateKey || !account.btcPublicKey) {
|
|
160
|
+
throw new Error("Bitcoin keys not available. Unlock your wallet again.");
|
|
161
|
+
}
|
|
162
|
+
// Validate btcSender if provided — must match the active wallet
|
|
163
|
+
if (btcSender && btcSender !== account.btcAddress) {
|
|
164
|
+
throw new Error(`btcSender "${btcSender}" must match the active wallet BTC address ` +
|
|
165
|
+
`(${account.btcAddress}). This tool signs with the active wallet's keys.`);
|
|
166
|
+
}
|
|
167
|
+
const resolvedBtcSender = account.btcAddress;
|
|
168
|
+
const resolvedStxReceiver = stxReceiver || account.address;
|
|
169
|
+
// Check pool liquidity
|
|
170
|
+
const poolStatus = await styxSDK.getPoolStatus(pool);
|
|
171
|
+
const availableSats = Math.round(poolStatus.estimatedAvailable * 1e8);
|
|
172
|
+
if (amountSats > availableSats) {
|
|
173
|
+
throw new Error(`Insufficient pool liquidity: need ${amountSats} sats, pool has ~${availableSats} sats`);
|
|
174
|
+
}
|
|
175
|
+
// Step 1: Reserve pool liquidity
|
|
176
|
+
const btcAmount = (amountSats / 1e8).toFixed(8);
|
|
177
|
+
depositId = await styxSDK.createDeposit({
|
|
178
|
+
btcAmount: parseFloat(btcAmount),
|
|
179
|
+
stxReceiver: resolvedStxReceiver,
|
|
180
|
+
btcSender: resolvedBtcSender,
|
|
181
|
+
poolId: pool,
|
|
182
|
+
});
|
|
183
|
+
// Step 2: Prepare transaction (UTXOs, deposit address, OP_RETURN)
|
|
184
|
+
const prepared = await styxSDK.prepareTransaction({
|
|
185
|
+
amount: btcAmount,
|
|
186
|
+
userAddress: resolvedStxReceiver,
|
|
187
|
+
btcAddress: resolvedBtcSender,
|
|
188
|
+
feePriority,
|
|
189
|
+
walletProvider: null,
|
|
190
|
+
poolId: pool,
|
|
191
|
+
});
|
|
192
|
+
// Step 3: Filter ordinal UTXOs on mainnet to protect inscriptions
|
|
193
|
+
let safeUtxos = prepared.utxos;
|
|
194
|
+
let ordinalsFiltered = false;
|
|
195
|
+
if (NETWORK === "mainnet") {
|
|
196
|
+
const indexer = new OrdinalIndexer(NETWORK);
|
|
197
|
+
const cardinalUtxos = await indexer.getCardinalUtxos(resolvedBtcSender);
|
|
198
|
+
const cardinalSet = new Set(cardinalUtxos.map((u) => `${u.txid}:${u.vout}`));
|
|
199
|
+
const filtered = prepared.utxos.filter((u) => cardinalSet.has(`${u.txid}:${u.vout}`));
|
|
200
|
+
if (filtered.length < prepared.utxos.length) {
|
|
201
|
+
const removed = prepared.utxos.length - filtered.length;
|
|
202
|
+
if (filtered.length === 0) {
|
|
203
|
+
throw new Error(`All ${removed} UTXO(s) selected by Styx contain inscriptions. ` +
|
|
204
|
+
"Cannot deposit without risking inscription loss.");
|
|
205
|
+
}
|
|
206
|
+
// Recompute change after removing ordinal inputs
|
|
207
|
+
const originalTotal = prepared.utxos.reduce((sum, u) => sum + u.value, 0);
|
|
208
|
+
const filteredTotal = filtered.reduce((sum, u) => sum + u.value, 0);
|
|
209
|
+
const originalFee = originalTotal - prepared.amountInSatoshis - prepared.changeAmount;
|
|
210
|
+
if (originalFee < 0) {
|
|
211
|
+
throw new Error("Invalid Styx transaction preparation: negative implied fee.");
|
|
212
|
+
}
|
|
213
|
+
const requiredTotal = prepared.amountInSatoshis + originalFee;
|
|
214
|
+
if (filteredTotal < requiredTotal) {
|
|
215
|
+
throw new Error(`After removing ${removed} ordinal UTXO(s), remaining cardinal balance ` +
|
|
216
|
+
`(${filteredTotal} sats) is insufficient for deposit (${amountSats} sats) ` +
|
|
217
|
+
`and fee (${originalFee} sats).`);
|
|
218
|
+
}
|
|
219
|
+
prepared.changeAmount =
|
|
220
|
+
filteredTotal - prepared.amountInSatoshis - originalFee;
|
|
221
|
+
ordinalsFiltered = true;
|
|
222
|
+
}
|
|
223
|
+
safeUtxos = filtered;
|
|
224
|
+
}
|
|
225
|
+
// Step 4: Build PSBT locally with @scure/btc-signer
|
|
226
|
+
const btcNetwork = getBtcNetwork();
|
|
227
|
+
const tx = new btc.Transaction({ allowUnknownOutputs: true });
|
|
228
|
+
const senderP2wpkh = btc.p2wpkh(account.btcPublicKey, btcNetwork);
|
|
229
|
+
for (const utxo of safeUtxos) {
|
|
230
|
+
tx.addInput({
|
|
231
|
+
txid: utxo.txid,
|
|
232
|
+
index: utxo.vout,
|
|
233
|
+
witnessUtxo: {
|
|
234
|
+
script: senderP2wpkh.script,
|
|
235
|
+
amount: BigInt(utxo.value),
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// OP_RETURN output FIRST (output index 0) — Styx contract requires OP_RETURN at index 0
|
|
240
|
+
// Styx SDK provides a full script hex (starts with 6a = OP_RETURN opcode)
|
|
241
|
+
if (prepared.opReturnData) {
|
|
242
|
+
tx.addOutput({
|
|
243
|
+
script: hex.decode(prepared.opReturnData),
|
|
244
|
+
amount: BigInt(0),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
// Deposit output to Styx address (output index 1)
|
|
248
|
+
tx.addOutputAddress(prepared.depositAddress, BigInt(prepared.amountInSatoshis), btcNetwork);
|
|
249
|
+
// Change output
|
|
250
|
+
if (prepared.changeAmount > 0) {
|
|
251
|
+
tx.addOutputAddress(resolvedBtcSender, BigInt(prepared.changeAmount), btcNetwork);
|
|
252
|
+
}
|
|
253
|
+
// Step 5: Sign and finalize
|
|
254
|
+
tx.sign(account.btcPrivateKey);
|
|
255
|
+
tx.finalize();
|
|
256
|
+
// Step 6: Broadcast
|
|
257
|
+
const mempoolApi = new MempoolApi(NETWORK);
|
|
258
|
+
broadcastTxid = await mempoolApi.broadcastTransaction(tx.hex);
|
|
259
|
+
// Step 7: Update deposit status (retry once on failure)
|
|
260
|
+
let statusUpdateWarning;
|
|
261
|
+
const statusPayload = {
|
|
262
|
+
id: depositId,
|
|
263
|
+
data: { btcTxId: broadcastTxid, status: "broadcast" },
|
|
264
|
+
};
|
|
265
|
+
try {
|
|
266
|
+
await styxSDK.updateDepositStatus(statusPayload);
|
|
267
|
+
}
|
|
268
|
+
catch (statusError) {
|
|
269
|
+
try {
|
|
270
|
+
await styxSDK.updateDepositStatus(statusPayload);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
statusUpdateWarning =
|
|
274
|
+
"Deposit broadcast succeeded but status update failed after retry. " +
|
|
275
|
+
"Save depositId and txid for manual recovery. " +
|
|
276
|
+
(statusError instanceof Error
|
|
277
|
+
? statusError.message
|
|
278
|
+
: String(statusError));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return createJsonResponse({
|
|
282
|
+
success: true,
|
|
283
|
+
depositId,
|
|
284
|
+
txid: broadcastTxid,
|
|
285
|
+
explorerUrl: getMempoolTxUrl(broadcastTxid, NETWORK),
|
|
286
|
+
amount: { sats: amountSats, btc: btcAmount },
|
|
287
|
+
pool,
|
|
288
|
+
depositAddress: prepared.depositAddress,
|
|
289
|
+
// fee/feeRate are omitted when ordinal filtering occurred — those values were
|
|
290
|
+
// computed against the original UTXO set and no longer reflect the actual tx
|
|
291
|
+
...(ordinalsFiltered
|
|
292
|
+
? { feeNote: "fee metadata omitted — UTXO set was filtered for ordinals" }
|
|
293
|
+
: { fee: prepared.fee, feeRate: prepared.feeRate }),
|
|
294
|
+
status: "broadcast",
|
|
295
|
+
network: NETWORK,
|
|
296
|
+
note: "sBTC will be credited to your Stacks address after Bitcoin confirmation.",
|
|
297
|
+
...(statusUpdateWarning ? { warning: statusUpdateWarning } : {}),
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
// Best-effort: cancel reservation if we never broadcast
|
|
302
|
+
if (depositId && !broadcastTxid) {
|
|
303
|
+
try {
|
|
304
|
+
await styxSDK.updateDepositStatus({
|
|
305
|
+
id: depositId,
|
|
306
|
+
data: { status: "canceled" },
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
// Reservation will expire server-side; don't mask the original error
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return createErrorResponse(error);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// styx_status
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
server.registerTool("styx_status", {
|
|
320
|
+
description: "Check the status of a Styx BTC→sBTC deposit by deposit ID or Bitcoin transaction ID.",
|
|
321
|
+
inputSchema: {
|
|
322
|
+
id: z.string().optional().describe("Styx deposit ID"),
|
|
323
|
+
txid: z.string().optional().describe("Bitcoin transaction ID"),
|
|
324
|
+
},
|
|
325
|
+
}, async ({ id, txid }) => {
|
|
326
|
+
try {
|
|
327
|
+
if (!id && !txid) {
|
|
328
|
+
throw new Error("Provide either id (deposit ID) or txid (Bitcoin transaction ID).");
|
|
329
|
+
}
|
|
330
|
+
let deposit;
|
|
331
|
+
if (id) {
|
|
332
|
+
deposit = await styxSDK.getDepositStatus(id);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
deposit = await styxSDK.getDepositStatusByTxId(txid);
|
|
336
|
+
}
|
|
337
|
+
return createJsonResponse({
|
|
338
|
+
id: deposit.id,
|
|
339
|
+
status: deposit.status,
|
|
340
|
+
btcAmount: deposit.btcAmount,
|
|
341
|
+
sbtcAmount: deposit.sbtcAmount,
|
|
342
|
+
stxReceiver: deposit.stxReceiver,
|
|
343
|
+
btcSender: deposit.btcSender,
|
|
344
|
+
btcTxId: deposit.btcTxId,
|
|
345
|
+
stxTxId: deposit.stxTxId,
|
|
346
|
+
createdAt: deposit.createdAt,
|
|
347
|
+
updatedAt: deposit.updatedAt,
|
|
348
|
+
network: NETWORK,
|
|
349
|
+
explorerUrl: deposit.btcTxId
|
|
350
|
+
? getMempoolTxUrl(deposit.btcTxId, NETWORK)
|
|
351
|
+
: null,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
return createErrorResponse(error);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
// ---------------------------------------------------------------------------
|
|
359
|
+
// styx_history
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
server.registerTool("styx_history", {
|
|
362
|
+
description: "Get BTC→sBTC deposit history for a Stacks address via Styx. " +
|
|
363
|
+
"Uses the active wallet's Stacks address if no address is provided.",
|
|
364
|
+
inputSchema: {
|
|
365
|
+
address: z
|
|
366
|
+
.string()
|
|
367
|
+
.optional()
|
|
368
|
+
.describe("Stacks address to query. Uses active wallet if omitted."),
|
|
369
|
+
},
|
|
370
|
+
}, async ({ address }) => {
|
|
371
|
+
try {
|
|
372
|
+
let resolvedAddress = address;
|
|
373
|
+
if (!resolvedAddress) {
|
|
374
|
+
const walletManager = getWalletManager();
|
|
375
|
+
const account = walletManager.getActiveAccount();
|
|
376
|
+
if (!account) {
|
|
377
|
+
throw new Error("No address provided and wallet is not unlocked.");
|
|
378
|
+
}
|
|
379
|
+
resolvedAddress = account.address;
|
|
380
|
+
}
|
|
381
|
+
const deposits = await styxSDK.getDepositHistory(resolvedAddress);
|
|
382
|
+
return createJsonResponse({
|
|
383
|
+
address: resolvedAddress,
|
|
384
|
+
count: deposits.length,
|
|
385
|
+
network: NETWORK,
|
|
386
|
+
deposits: deposits.map((d) => ({
|
|
387
|
+
id: d.id,
|
|
388
|
+
status: d.status,
|
|
389
|
+
btcAmount: d.btcAmount,
|
|
390
|
+
sbtcAmount: d.sbtcAmount,
|
|
391
|
+
btcTxId: d.btcTxId,
|
|
392
|
+
createdAt: d.createdAt,
|
|
393
|
+
})),
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
return createErrorResponse(error);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
//# sourceMappingURL=styx.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styx.tools.js","sourceRoot":"","sources":["../../src/tools/styx.tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EACL,OAAO,EACP,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;AAE1D,SAAS,aAAa;IACpB,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,8EAA8E;IAC9E,mBAAmB;IACnB,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,WAAW,EACT,8CAA8C;YAC9C,6DAA6D;QAC/D,WAAW,EAAE;YACX,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,6EAA6E,CAAC;SAC3F;KACF,EACD,KAAK,EAAE,EAAE,IAAI,GAAG,MAAM,EAAE,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAe,MAAM,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC7D,OAAO,kBAAkB,CAAC;gBACxB,IAAI;gBACJ,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;gBAC7C,sBAAsB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,GAAG,GAAG,CAAC;gBACnE,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,aAAa;IACb,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,WAAW,EACT,2DAA2D;YAC3D,oFAAoF;YACpF,8CAA8C;QAChD,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,KAAK,GAAiB,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC;YAC9D,OAAO,kBAAkB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,YAAY;IACZ,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;QACE,WAAW,EAAE,kFAAkF;QAC/F,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAiB,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC;YAC3D,OAAO,kBAAkB,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,aAAa;IACb,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,WAAW,EAAE,yCAAyC;QACtD,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAC1C,OAAO,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,eAAe;IACf,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,WAAW,EACT,wDAAwD;YACxD,8EAA8E;YAC9E,sDAAsD;YACtD,2DAA2D;YAC3D,oFAAoF;YACpF,2EAA2E;QAC7E,WAAW,EAAE;YACX,MAAM,EAAE,CAAC;iBACN,MAAM;iBACN,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,gBAAgB,CAAC;iBACrB,QAAQ,CAAC,sCAAsC,gBAAgB,mBAAmB,CAAC;YACtF,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,wEAAwE,CAAC;YACrF,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,yEAAyE;gBACvE,gCAAgC,CACnC;YACH,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iDAAiD,CAAC;YAC9D,GAAG,EAAE,CAAC;iBACH,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;iBAC/B,QAAQ,EAAE;iBACV,QAAQ,CAAC,iEAAiE,CAAC;SAC/E;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,GAAG,QAAQ,EAAE,EAAE,EAAE;QAC1E,IAAI,SAA6B,CAAC;QAClC,IAAI,aAAiC,CAAC;QAEtC,IAAI,CAAC;YACH,iGAAiG;YACjG,MAAM,UAAU,GAAG,MAAM,CAAC;YAE1B,+EAA+E;YAC/E,MAAM,WAAW,GAAG,GAAkB,CAAC;YACvC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CACb,sBAAsB,GAAG,sBAAsB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3E,CAAC;YACJ,CAAC;YAED,aAAa;YACb,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,EAAE,CAAC;YACjD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACvE,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;gBAC3E,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC3E,CAAC;YAED,gEAAgE;YAChE,IAAI,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CACb,cAAc,SAAS,6CAA6C;oBAClE,IAAI,OAAO,CAAC,UAAU,mDAAmD,CAC5E,CAAC;YACJ,CAAC;YACD,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;YAC7C,MAAM,mBAAmB,GAAG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YAE3D,uBAAuB;YACvB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACrD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC;YACtE,IAAI,UAAU,GAAG,aAAa,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CACb,qCAAqC,UAAU,oBAAoB,aAAa,OAAO,CACxF,CAAC;YACJ,CAAC;YAED,iCAAiC;YACjC,MAAM,SAAS,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAChD,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC;gBACtC,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC;gBAChC,WAAW,EAAE,mBAAmB;gBAChC,SAAS,EAAE,iBAAiB;gBAC5B,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YAEH,kEAAkE;YAClE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC;gBAChD,MAAM,EAAE,SAAS;gBACjB,WAAW,EAAE,mBAAmB;gBAChC,UAAU,EAAE,iBAAiB;gBAC7B,WAAW;gBACX,cAAc,EAAE,IAAI;gBACpB,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YAEH,kEAAkE;YAClE,IAAI,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC;YAC/B,IAAI,gBAAgB,GAAG,KAAK,CAAC;YAC7B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;gBAC5C,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;gBACxE,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAChD,CAAC;gBACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3C,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CACvC,CAAC;gBACF,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;oBACxD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC1B,MAAM,IAAI,KAAK,CACb,OAAO,OAAO,kDAAkD;4BAC9D,kDAAkD,CACrD,CAAC;oBACJ,CAAC;oBACD,iDAAiD;oBACjD,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC1E,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBACpE,MAAM,WAAW,GACf,aAAa,GAAG,QAAQ,CAAC,gBAAgB,GAAG,QAAQ,CAAC,YAAY,CAAC;oBACpE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;wBACpB,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;oBACJ,CAAC;oBACD,MAAM,aAAa,GAAG,QAAQ,CAAC,gBAAgB,GAAG,WAAW,CAAC;oBAC9D,IAAI,aAAa,GAAG,aAAa,EAAE,CAAC;wBAClC,MAAM,IAAI,KAAK,CACb,kBAAkB,OAAO,+CAA+C;4BACtE,IAAI,aAAa,uCAAuC,UAAU,SAAS;4BAC3E,YAAY,WAAW,SAAS,CACnC,CAAC;oBACJ,CAAC;oBACD,QAAQ,CAAC,YAAY;wBACnB,aAAa,GAAG,QAAQ,CAAC,gBAAgB,GAAG,WAAW,CAAC;oBAC1D,gBAAgB,GAAG,IAAI,CAAC;gBAC1B,CAAC;gBACD,SAAS,GAAG,QAAQ,CAAC;YACvB,CAAC;YAED,oDAAoD;YACpD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;YACnC,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YAElE,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,EAAE,CAAC,QAAQ,CAAC;oBACV,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,KAAK,EAAE,IAAI,CAAC,IAAI;oBAChB,WAAW,EAAE;wBACX,MAAM,EAAE,YAAY,CAAC,MAAM;wBAC3B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;qBAC3B;iBACF,CAAC,CAAC;YACL,CAAC;YAED,wFAAwF;YACxF,0EAA0E;YAC1E,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAC1B,EAAE,CAAC,SAAS,CAAC;oBACX,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;oBACzC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;iBAClB,CAAC,CAAC;YACL,CAAC;YAED,kDAAkD;YAClD,EAAE,CAAC,gBAAgB,CACjB,QAAQ,CAAC,cAAc,EACvB,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EACjC,UAAU,CACX,CAAC;YAEF,gBAAgB;YAChB,IAAI,QAAQ,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;gBAC9B,EAAE,CAAC,gBAAgB,CACjB,iBAAiB,EACjB,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAC7B,UAAU,CACX,CAAC;YACJ,CAAC;YAED,4BAA4B;YAC5B,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAC/B,EAAE,CAAC,QAAQ,EAAE,CAAC;YAEd,oBAAoB;YACpB,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;YAC3C,aAAa,GAAG,MAAM,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;YAE9D,wDAAwD;YACxD,IAAI,mBAAuC,CAAC;YAC5C,MAAM,aAAa,GAAG;gBACpB,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,WAAoB,EAAE;aAC/D,CAAC;YACF,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;YACnD,CAAC;YAAC,OAAO,WAAW,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACH,MAAM,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;gBACnD,CAAC;gBAAC,MAAM,CAAC;oBACP,mBAAmB;wBACjB,oEAAoE;4BACpE,+CAA+C;4BAC/C,CAAC,WAAW,YAAY,KAAK;gCAC3B,CAAC,CAAC,WAAW,CAAC,OAAO;gCACrB,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;YAED,OAAO,kBAAkB,CAAC;gBACxB,OAAO,EAAE,IAAI;gBACb,SAAS;gBACT,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,eAAe,CAAC,aAAa,EAAE,OAAO,CAAC;gBACpD,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE;gBAC5C,IAAI;gBACJ,cAAc,EAAE,QAAQ,CAAC,cAAc;gBACvC,8EAA8E;gBAC9E,6EAA6E;gBAC7E,GAAG,CAAC,gBAAgB;oBAClB,CAAC,CAAC,EAAE,OAAO,EAAE,2DAA2D,EAAE;oBAC1E,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrD,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,0EAA0E;gBAChF,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjE,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,wDAAwD;YACxD,IAAI,SAAS,IAAI,CAAC,aAAa,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACH,MAAM,OAAO,CAAC,mBAAmB,CAAC;wBAChC,EAAE,EAAE,SAAS;wBACb,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;qBAC7B,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,qEAAqE;gBACvE,CAAC;YACH,CAAC;YACD,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,cAAc;IACd,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,WAAW,EACT,sFAAsF;QACxF,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAC/D;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;YACtF,CAAC;YACD,IAAI,OAAgB,CAAC;YACrB,IAAI,EAAE,EAAE,CAAC;gBACP,OAAO,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,MAAM,OAAO,CAAC,sBAAsB,CAAC,IAAK,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,kBAAkB,CAAC;gBACxB,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,OAAO,EAAE,OAAO;gBAChB,WAAW,EAAE,OAAO,CAAC,OAAO;oBAC1B,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;oBAC3C,CAAC,CAAC,IAAI;aACT,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,eAAe;IACf,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,WAAW,EACT,8DAA8D;YAC9D,oEAAoE;QACtE,WAAW,EAAE;YACX,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yDAAyD,CAAC;SACvE;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,IAAI,CAAC;YACH,IAAI,eAAe,GAAG,OAAO,CAAC;YAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,EAAE,CAAC;gBACjD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACrE,CAAC;gBACD,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;YACpC,CAAC;YAED,MAAM,QAAQ,GAAc,MAAM,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;YAC7E,OAAO,kBAAkB,CAAC;gBACxB,OAAO,EAAE,eAAe;gBACxB,KAAK,EAAE,QAAQ,CAAC,MAAM;gBACtB,OAAO,EAAE,OAAO;gBAChB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC7B,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,SAAS,EAAE,CAAC,CAAC,SAAS;oBACtB,UAAU,EAAE,CAAC,CAAC,UAAU;oBACxB,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,SAAS,EAAE,CAAC,CAAC,SAAS;iBACvB,CAAC,CAAC;aACJ,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
* diagnostic information when send failures occur.
|
|
6
6
|
*/
|
|
7
7
|
import type { Network } from "../config/networks.js";
|
|
8
|
+
export interface StuckTransaction {
|
|
9
|
+
txid: string;
|
|
10
|
+
nonce: number;
|
|
11
|
+
pendingSeconds: number;
|
|
12
|
+
}
|
|
8
13
|
export interface RelayHealthStatus {
|
|
9
14
|
healthy: boolean;
|
|
10
15
|
network: Network;
|
|
@@ -18,7 +23,10 @@ export interface RelayHealthStatus {
|
|
|
18
23
|
mempoolNonces: number[];
|
|
19
24
|
hasGaps: boolean;
|
|
20
25
|
gapCount: number;
|
|
26
|
+
mempoolDesync: boolean;
|
|
27
|
+
desyncGap: number;
|
|
21
28
|
};
|
|
29
|
+
stuckTransactions?: StuckTransaction[];
|
|
22
30
|
issues?: string[];
|
|
23
31
|
}
|
|
24
32
|
/**
|
|
@@ -29,6 +37,26 @@ export declare function checkRelayHealth(network: Network): Promise<RelayHealthS
|
|
|
29
37
|
* Format relay health status as a human-readable string
|
|
30
38
|
*/
|
|
31
39
|
export declare function formatRelayHealthStatus(status: RelayHealthStatus): string;
|
|
40
|
+
export interface RelayRecoveryResult {
|
|
41
|
+
supported: boolean;
|
|
42
|
+
message?: string;
|
|
43
|
+
result?: unknown;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Attempt RBF (replace-by-fee) on stuck transactions via the relay API.
|
|
47
|
+
* If txids is provided, only those transactions are bumped; otherwise the relay
|
|
48
|
+
* bumps all stuck transactions it knows about.
|
|
49
|
+
*
|
|
50
|
+
* Gracefully returns { supported: false } if the relay returns 404 or 501.
|
|
51
|
+
*/
|
|
52
|
+
export declare function attemptRbf(network: Network, txids?: string[], apiKey?: string): Promise<RelayRecoveryResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Attempt to fill nonce gaps on the relay by having it submit placeholder transactions.
|
|
55
|
+
* If nonces is provided, only those gaps are filled; otherwise the relay fills all detected gaps.
|
|
56
|
+
*
|
|
57
|
+
* Gracefully returns { supported: false } if the relay returns 404 or 501.
|
|
58
|
+
*/
|
|
59
|
+
export declare function attemptFillGaps(network: Network, nonces?: number[], apiKey?: string): Promise<RelayRecoveryResult>;
|
|
32
60
|
/**
|
|
33
61
|
* Wait with exponential backoff when relay nonce issues are detected
|
|
34
62
|
* Returns recommended wait time in milliseconds
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-health.d.ts","sourceRoot":"","sources":["../../src/utils/relay-health.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE;QACZ,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-health.d.ts","sourceRoot":"","sources":["../../src/utils/relay-health.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE;QACZ,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,OAAO,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAUD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA4HnF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuDzE;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiDlH;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiDxH;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,CASnF"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Proactively checks the sponsor relay for nonce gaps and provides
|
|
5
5
|
* diagnostic information when send failures occur.
|
|
6
6
|
*/
|
|
7
|
-
import { getSponsorRelayUrl } from "../config/sponsor.js";
|
|
7
|
+
import { getSponsorRelayUrl, getSponsorApiKey } from "../config/sponsor.js";
|
|
8
8
|
import { getHiroApi } from "../services/hiro-api.js";
|
|
9
9
|
/**
|
|
10
10
|
* Known sponsor addresses for each network.
|
|
@@ -53,27 +53,65 @@ export async function checkRelayHealth(network) {
|
|
|
53
53
|
const nonceInfo = await hiroApi.getNonceInfo(sponsorAddress);
|
|
54
54
|
const hasGaps = nonceInfo.detected_missing_nonces.length > 0;
|
|
55
55
|
const gapCount = nonceInfo.detected_missing_nonces.length;
|
|
56
|
+
// Mempool desync: sponsor has submitted far more txs than have been confirmed
|
|
57
|
+
const lastExecuted = nonceInfo.last_executed_tx_nonce || 0;
|
|
58
|
+
const lastMempool = nonceInfo.last_mempool_tx_nonce;
|
|
59
|
+
const desyncGap = lastMempool !== null ? lastMempool - lastExecuted : 0;
|
|
60
|
+
const mempoolDesync = desyncGap > 5;
|
|
56
61
|
if (hasGaps) {
|
|
57
62
|
issues.push(`Sponsor has ${gapCount} missing nonce(s): ${nonceInfo.detected_missing_nonces.slice(0, 5).join(", ")}${gapCount > 5 ? "..." : ""}`);
|
|
58
63
|
}
|
|
59
|
-
if (
|
|
64
|
+
if (mempoolDesync) {
|
|
65
|
+
issues.push(`Mempool desync detected: sponsor nonce ${lastExecuted} (executed) vs ${lastMempool} (mempool), gap of ${desyncGap}`);
|
|
66
|
+
}
|
|
67
|
+
else if (nonceInfo.detected_mempool_nonces.length > 10) {
|
|
60
68
|
issues.push(`Sponsor has ${nonceInfo.detected_mempool_nonces.length} transactions stuck in mempool`);
|
|
61
69
|
}
|
|
62
70
|
const nonceStatus = {
|
|
63
|
-
lastExecuted
|
|
64
|
-
lastMempool
|
|
71
|
+
lastExecuted,
|
|
72
|
+
lastMempool,
|
|
65
73
|
possibleNext: nonceInfo.possible_next_nonce,
|
|
66
74
|
missingNonces: nonceInfo.detected_missing_nonces,
|
|
67
75
|
mempoolNonces: nonceInfo.detected_mempool_nonces,
|
|
68
76
|
hasGaps,
|
|
69
77
|
gapCount,
|
|
78
|
+
mempoolDesync,
|
|
79
|
+
desyncGap,
|
|
70
80
|
};
|
|
81
|
+
// Fetch stuck transactions from mempool for actionable diagnostics
|
|
82
|
+
let stuckTransactions;
|
|
83
|
+
try {
|
|
84
|
+
const mempoolRes = await hiroApi.getMempoolTransactions({
|
|
85
|
+
sender_address: sponsorAddress,
|
|
86
|
+
limit: 50,
|
|
87
|
+
});
|
|
88
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
89
|
+
const stuck = mempoolRes.results
|
|
90
|
+
.filter((tx) => {
|
|
91
|
+
const pendingSeconds = nowSeconds - tx.receipt_time;
|
|
92
|
+
return pendingSeconds > 60;
|
|
93
|
+
})
|
|
94
|
+
.map((tx) => ({
|
|
95
|
+
txid: tx.tx_id,
|
|
96
|
+
nonce: tx.nonce,
|
|
97
|
+
pendingSeconds: nowSeconds - tx.receipt_time,
|
|
98
|
+
}))
|
|
99
|
+
.sort((a, b) => b.pendingSeconds - a.pendingSeconds)
|
|
100
|
+
.slice(0, 10);
|
|
101
|
+
if (stuck.length > 0) {
|
|
102
|
+
stuckTransactions = stuck;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Non-fatal: stuck-tx fetch is best-effort
|
|
107
|
+
}
|
|
71
108
|
return {
|
|
72
109
|
healthy: issues.length === 0,
|
|
73
110
|
network,
|
|
74
111
|
version,
|
|
75
112
|
sponsorAddress,
|
|
76
113
|
nonceStatus,
|
|
114
|
+
stuckTransactions,
|
|
77
115
|
issues: issues.length > 0 ? issues : undefined,
|
|
78
116
|
};
|
|
79
117
|
}
|
|
@@ -107,15 +145,28 @@ export function formatRelayHealthStatus(status) {
|
|
|
107
145
|
lines.push(` Last mempool: ${ns.lastMempool ?? "none"}`);
|
|
108
146
|
lines.push(` Next nonce: ${ns.possibleNext}`);
|
|
109
147
|
if (ns.hasGaps) {
|
|
110
|
-
lines.push(`
|
|
148
|
+
lines.push(` GAPS Missing nonces (${ns.gapCount}): ${ns.missingNonces.slice(0, 10).join(", ")}${ns.gapCount > 10 ? "..." : ""}`);
|
|
111
149
|
}
|
|
112
150
|
else {
|
|
113
|
-
lines.push("
|
|
151
|
+
lines.push(" OK No nonce gaps");
|
|
152
|
+
}
|
|
153
|
+
if (ns.mempoolDesync) {
|
|
154
|
+
lines.push(` DESYNC Mempool desync: executed=${ns.lastExecuted}, mempool=${ns.lastMempool ?? "none"}, gap=${ns.desyncGap}`);
|
|
114
155
|
}
|
|
115
156
|
if (ns.mempoolNonces.length > 0) {
|
|
116
|
-
lines.push(`
|
|
157
|
+
lines.push(` WARN Mempool nonces (${ns.mempoolNonces.length}): ${ns.mempoolNonces.slice(0, 10).join(", ")}${ns.mempoolNonces.length > 10 ? "..." : ""}`);
|
|
117
158
|
}
|
|
118
159
|
}
|
|
160
|
+
if (status.stuckTransactions && status.stuckTransactions.length > 0) {
|
|
161
|
+
lines.push("");
|
|
162
|
+
lines.push("Stuck Transactions:");
|
|
163
|
+
status.stuckTransactions.forEach((tx) => {
|
|
164
|
+
const minutes = Math.floor(tx.pendingSeconds / 60);
|
|
165
|
+
const seconds = tx.pendingSeconds % 60;
|
|
166
|
+
const duration = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
|
|
167
|
+
lines.push(` nonce=${tx.nonce} pending=${duration} txid=${tx.txid}`);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
119
170
|
if (status.issues && status.issues.length > 0) {
|
|
120
171
|
lines.push("");
|
|
121
172
|
lines.push("Issues:");
|
|
@@ -123,6 +174,105 @@ export function formatRelayHealthStatus(status) {
|
|
|
123
174
|
}
|
|
124
175
|
return lines.join("\n");
|
|
125
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* Attempt RBF (replace-by-fee) on stuck transactions via the relay API.
|
|
179
|
+
* If txids is provided, only those transactions are bumped; otherwise the relay
|
|
180
|
+
* bumps all stuck transactions it knows about.
|
|
181
|
+
*
|
|
182
|
+
* Gracefully returns { supported: false } if the relay returns 404 or 501.
|
|
183
|
+
*/
|
|
184
|
+
export async function attemptRbf(network, txids, apiKey) {
|
|
185
|
+
const relayUrl = getSponsorRelayUrl(network);
|
|
186
|
+
const resolvedKey = apiKey || getSponsorApiKey();
|
|
187
|
+
if (!resolvedKey) {
|
|
188
|
+
return {
|
|
189
|
+
supported: true,
|
|
190
|
+
message: "No sponsor API key available. Set SPONSOR_API_KEY env var or use a wallet with sponsorApiKey configured.",
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const headers = {
|
|
194
|
+
"Content-Type": "application/json",
|
|
195
|
+
"Authorization": `Bearer ${resolvedKey}`,
|
|
196
|
+
};
|
|
197
|
+
const body = {};
|
|
198
|
+
if (txids && txids.length > 0) {
|
|
199
|
+
body.txids = txids;
|
|
200
|
+
}
|
|
201
|
+
const controller = new AbortController();
|
|
202
|
+
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
203
|
+
try {
|
|
204
|
+
const res = await fetch(`${relayUrl}/recovery/rbf`, {
|
|
205
|
+
method: "POST",
|
|
206
|
+
headers,
|
|
207
|
+
body: JSON.stringify(body),
|
|
208
|
+
signal: controller.signal,
|
|
209
|
+
});
|
|
210
|
+
if (res.status === 404 || res.status === 501) {
|
|
211
|
+
return {
|
|
212
|
+
supported: false,
|
|
213
|
+
message: "Relay does not support RBF recovery yet. Share stuck txids with the AIBTC team for manual recovery.",
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (!res.ok) {
|
|
217
|
+
const text = await res.text();
|
|
218
|
+
throw new Error(`Relay RBF failed: HTTP ${res.status} — ${text}`);
|
|
219
|
+
}
|
|
220
|
+
const result = await res.json();
|
|
221
|
+
return { supported: true, result };
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
clearTimeout(timeout);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Attempt to fill nonce gaps on the relay by having it submit placeholder transactions.
|
|
229
|
+
* If nonces is provided, only those gaps are filled; otherwise the relay fills all detected gaps.
|
|
230
|
+
*
|
|
231
|
+
* Gracefully returns { supported: false } if the relay returns 404 or 501.
|
|
232
|
+
*/
|
|
233
|
+
export async function attemptFillGaps(network, nonces, apiKey) {
|
|
234
|
+
const relayUrl = getSponsorRelayUrl(network);
|
|
235
|
+
const resolvedKey = apiKey || getSponsorApiKey();
|
|
236
|
+
if (!resolvedKey) {
|
|
237
|
+
return {
|
|
238
|
+
supported: true,
|
|
239
|
+
message: "No sponsor API key available. Set SPONSOR_API_KEY env var or use a wallet with sponsorApiKey configured.",
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const headers = {
|
|
243
|
+
"Content-Type": "application/json",
|
|
244
|
+
"Authorization": `Bearer ${resolvedKey}`,
|
|
245
|
+
};
|
|
246
|
+
const body = {};
|
|
247
|
+
if (nonces && nonces.length > 0) {
|
|
248
|
+
body.nonces = nonces;
|
|
249
|
+
}
|
|
250
|
+
const controller = new AbortController();
|
|
251
|
+
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
252
|
+
try {
|
|
253
|
+
const res = await fetch(`${relayUrl}/recovery/fill-gaps`, {
|
|
254
|
+
method: "POST",
|
|
255
|
+
headers,
|
|
256
|
+
body: JSON.stringify(body),
|
|
257
|
+
signal: controller.signal,
|
|
258
|
+
});
|
|
259
|
+
if (res.status === 404 || res.status === 501) {
|
|
260
|
+
return {
|
|
261
|
+
supported: false,
|
|
262
|
+
message: "Relay does not support nonce gap-fill recovery yet. Share missing nonces with the AIBTC team for manual recovery.",
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
if (!res.ok) {
|
|
266
|
+
const text = await res.text();
|
|
267
|
+
throw new Error(`Relay gap-fill failed: HTTP ${res.status} — ${text}`);
|
|
268
|
+
}
|
|
269
|
+
const result = await res.json();
|
|
270
|
+
return { supported: true, result };
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
clearTimeout(timeout);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
126
276
|
/**
|
|
127
277
|
* Wait with exponential backoff when relay nonce issues are detected
|
|
128
278
|
* Returns recommended wait time in milliseconds
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-health.js","sourceRoot":"","sources":["../../src/utils/relay-health.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-health.js","sourceRoot":"","sources":["../../src/utils/relay-health.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aibtc/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.35.0",
|
|
4
4
|
"description": "Bitcoin-native MCP server for AI agents: BTC/STX wallets, DeFi yield, sBTC peg, NFTs, and x402 payments.",
|
|
5
5
|
"mcpName": "io.github.aibtcdev/mcp-server",
|
|
6
6
|
"type": "module",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"license": "MIT",
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@bitflowlabs/core-sdk": "^3.0.0",
|
|
47
|
+
"@faktoryfun/styx-sdk": "^1.3.5",
|
|
47
48
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
48
49
|
"@noble/curves": "^2.0.1",
|
|
49
50
|
"@scure/base": "^2.0.0",
|
package/skill/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Bitcoin L1 wallet for agents - check balances, send BTC, manage UTX
|
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: aibtcdev
|
|
7
|
-
version: 1.
|
|
7
|
+
version: 1.35.0 # x-release-please-version
|
|
8
8
|
npm: "@aibtc/mcp-server"
|
|
9
9
|
github: https://github.com/aibtcdev/aibtc-mcp-server
|
|
10
10
|
---
|