@aibtc/mcp-server 1.58.0 → 1.60.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 +41 -0
- package/dist/bridge/index.d.ts +31 -0
- package/dist/bridge/index.js +285 -0
- package/dist/index.js +28 -5
- package/dist/services/credentials.js +7 -2
- package/dist/services/defi.service.js +23 -11
- package/dist/services/hiro-api.d.ts +10 -0
- package/dist/services/hiro-api.js +30 -8
- package/dist/services/nft.service.js +14 -5
- package/dist/services/pillar-api.service.d.ts +8 -0
- package/dist/services/pillar-api.service.js +13 -1
- package/dist/services/spend-limiter.d.ts +45 -0
- package/dist/services/spend-limiter.js +218 -0
- package/dist/services/wallet-manager.js +5 -0
- package/dist/services/x402.service.js +63 -13
- package/dist/tools/bitcoin.tools.js +19 -0
- package/dist/tools/endpoint.tools.js +3 -1
- package/dist/tools/inbox.tools.js +9 -12
- package/dist/tools/news.tools.js +14 -16
- package/dist/tools/pillar-direct.tools.js +29 -22
- package/dist/tools/sbtc.tools.js +2 -9
- package/dist/tools/scaffold.tools.js +9 -14
- package/dist/tools/stacking-lottery.tools.js +8 -5
- package/dist/tools/yield-dashboard.tools.js +10 -14
- package/dist/transactions/builder.js +5 -0
- package/dist/utils/encryption.js +2 -0
- package/package.json +11 -5
- package/skill/SKILL.md +1 -1
- package/skill/references/genesis-lifecycle.md +105 -92
- package/dist/config/bitcoin-constants.d.ts.map +0 -1
- package/dist/config/bitcoin-constants.js.map +0 -1
- package/dist/config/caip.d.ts.map +0 -1
- package/dist/config/caip.js.map +0 -1
- package/dist/config/competition.d.ts.map +0 -1
- package/dist/config/competition.js.map +0 -1
- package/dist/config/contracts.d.ts.map +0 -1
- package/dist/config/contracts.js.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/config/networks.d.ts.map +0 -1
- package/dist/config/networks.js.map +0 -1
- package/dist/config/pillar.d.ts.map +0 -1
- package/dist/config/pillar.js.map +0 -1
- package/dist/config/sponsor.d.ts.map +0 -1
- package/dist/config/sponsor.js.map +0 -1
- package/dist/endpoints/index.d.ts.map +0 -1
- package/dist/endpoints/index.js.map +0 -1
- package/dist/endpoints/registry.d.ts.map +0 -1
- package/dist/endpoints/registry.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/services/bitflow.service.d.ts.map +0 -1
- package/dist/services/bitflow.service.js.map +0 -1
- package/dist/services/bns.service.d.ts.map +0 -1
- package/dist/services/bns.service.js.map +0 -1
- package/dist/services/credentials.d.ts.map +0 -1
- package/dist/services/credentials.js.map +0 -1
- package/dist/services/defi.service.d.ts.map +0 -1
- package/dist/services/defi.service.js.map +0 -1
- package/dist/services/erc8004.service.d.ts.map +0 -1
- package/dist/services/erc8004.service.js.map +0 -1
- package/dist/services/hiro-api.d.ts.map +0 -1
- package/dist/services/hiro-api.js.map +0 -1
- package/dist/services/inscription-parser.d.ts.map +0 -1
- package/dist/services/inscription-parser.js.map +0 -1
- package/dist/services/lightning/provider.d.ts.map +0 -1
- package/dist/services/lightning/provider.js.map +0 -1
- package/dist/services/lightning/spark-provider.d.ts.map +0 -1
- package/dist/services/lightning/spark-provider.js.map +0 -1
- package/dist/services/lightning-manager.d.ts.map +0 -1
- package/dist/services/lightning-manager.js.map +0 -1
- package/dist/services/mempool-api.d.ts.map +0 -1
- package/dist/services/mempool-api.js.map +0 -1
- package/dist/services/nft.service.d.ts.map +0 -1
- package/dist/services/nft.service.js.map +0 -1
- package/dist/services/nonce-tracker.d.ts.map +0 -1
- package/dist/services/nonce-tracker.js.map +0 -1
- package/dist/services/pillar-api.service.d.ts.map +0 -1
- package/dist/services/pillar-api.service.js.map +0 -1
- package/dist/services/sbtc-deposit.service.d.ts.map +0 -1
- package/dist/services/sbtc-deposit.service.js.map +0 -1
- package/dist/services/sbtc.service.d.ts.map +0 -1
- package/dist/services/sbtc.service.js.map +0 -1
- package/dist/services/scaffold.service.d.ts.map +0 -1
- package/dist/services/scaffold.service.js.map +0 -1
- package/dist/services/signing-key.service.d.ts.map +0 -1
- package/dist/services/signing-key.service.js.map +0 -1
- package/dist/services/stacking.service.d.ts.map +0 -1
- package/dist/services/stacking.service.js.map +0 -1
- package/dist/services/tenero-api.d.ts.map +0 -1
- package/dist/services/tenero-api.js.map +0 -1
- package/dist/services/tokens.service.d.ts.map +0 -1
- package/dist/services/tokens.service.js.map +0 -1
- package/dist/services/unisat-indexer.d.ts.map +0 -1
- package/dist/services/unisat-indexer.js.map +0 -1
- package/dist/services/wallet-manager.d.ts.map +0 -1
- package/dist/services/wallet-manager.js.map +0 -1
- package/dist/services/x402.service.d.ts.map +0 -1
- package/dist/services/x402.service.js.map +0 -1
- package/dist/tools/arxiv-research.tools.d.ts.map +0 -1
- package/dist/tools/arxiv-research.tools.js.map +0 -1
- package/dist/tools/bitcoin.tools.d.ts.map +0 -1
- package/dist/tools/bitcoin.tools.js.map +0 -1
- package/dist/tools/bitflow.tools.d.ts.map +0 -1
- package/dist/tools/bitflow.tools.js.map +0 -1
- package/dist/tools/bns.tools.d.ts.map +0 -1
- package/dist/tools/bns.tools.js.map +0 -1
- package/dist/tools/bounty-scanner.tools.d.ts.map +0 -1
- package/dist/tools/bounty-scanner.tools.js.map +0 -1
- package/dist/tools/child-inscription.tools.d.ts.map +0 -1
- package/dist/tools/child-inscription.tools.js.map +0 -1
- package/dist/tools/competition.tools.d.ts.map +0 -1
- package/dist/tools/competition.tools.js.map +0 -1
- package/dist/tools/contract.tools.d.ts.map +0 -1
- package/dist/tools/contract.tools.js.map +0 -1
- package/dist/tools/credentials.tools.d.ts.map +0 -1
- package/dist/tools/credentials.tools.js.map +0 -1
- package/dist/tools/defi.tools.d.ts.map +0 -1
- package/dist/tools/defi.tools.js.map +0 -1
- package/dist/tools/dual-stacking.tools.d.ts.map +0 -1
- package/dist/tools/dual-stacking.tools.js.map +0 -1
- package/dist/tools/earning.tools.d.ts.map +0 -1
- package/dist/tools/earning.tools.js.map +0 -1
- package/dist/tools/endpoint.tools.d.ts.map +0 -1
- package/dist/tools/endpoint.tools.js.map +0 -1
- package/dist/tools/erc8004.tools.d.ts.map +0 -1
- package/dist/tools/erc8004.tools.js.map +0 -1
- package/dist/tools/identity.tools.d.ts.map +0 -1
- package/dist/tools/identity.tools.js.map +0 -1
- package/dist/tools/inbox-x402.tools.d.ts.map +0 -1
- package/dist/tools/inbox-x402.tools.js.map +0 -1
- package/dist/tools/inbox.tools.d.ts.map +0 -1
- package/dist/tools/inbox.tools.js.map +0 -1
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/jingswap.tools.d.ts.map +0 -1
- package/dist/tools/jingswap.tools.js.map +0 -1
- package/dist/tools/lightning.tools.d.ts.map +0 -1
- package/dist/tools/lightning.tools.js.map +0 -1
- package/dist/tools/mempool.tools.d.ts.map +0 -1
- package/dist/tools/mempool.tools.js.map +0 -1
- package/dist/tools/news.tools.d.ts.map +0 -1
- package/dist/tools/news.tools.js.map +0 -1
- package/dist/tools/nft.tools.d.ts.map +0 -1
- package/dist/tools/nft.tools.js.map +0 -1
- package/dist/tools/nonce.tools.d.ts.map +0 -1
- package/dist/tools/nonce.tools.js.map +0 -1
- package/dist/tools/nostr.tools.d.ts.map +0 -1
- package/dist/tools/nostr.tools.js.map +0 -1
- package/dist/tools/openrouter.tools.d.ts.map +0 -1
- package/dist/tools/openrouter.tools.js.map +0 -1
- package/dist/tools/ordinals-marketplace.tools.d.ts.map +0 -1
- package/dist/tools/ordinals-marketplace.tools.js.map +0 -1
- package/dist/tools/ordinals-p2p.tools.d.ts.map +0 -1
- package/dist/tools/ordinals-p2p.tools.js.map +0 -1
- package/dist/tools/ordinals.tools.d.ts.map +0 -1
- package/dist/tools/ordinals.tools.js.map +0 -1
- package/dist/tools/pillar-direct.tools.d.ts.map +0 -1
- package/dist/tools/pillar-direct.tools.js.map +0 -1
- package/dist/tools/pillar.tools.d.ts.map +0 -1
- package/dist/tools/pillar.tools.js.map +0 -1
- package/dist/tools/psbt.helpers.d.ts.map +0 -1
- package/dist/tools/psbt.helpers.js.map +0 -1
- package/dist/tools/psbt.tools.d.ts.map +0 -1
- package/dist/tools/psbt.tools.js.map +0 -1
- package/dist/tools/query.tools.d.ts.map +0 -1
- package/dist/tools/query.tools.js.map +0 -1
- package/dist/tools/relay-diagnostic.tools.d.ts.map +0 -1
- package/dist/tools/relay-diagnostic.tools.js.map +0 -1
- package/dist/tools/reputation.tools.d.ts.map +0 -1
- package/dist/tools/reputation.tools.js.map +0 -1
- package/dist/tools/runes.tools.d.ts.map +0 -1
- package/dist/tools/runes.tools.js.map +0 -1
- package/dist/tools/sbtc.tools.d.ts.map +0 -1
- package/dist/tools/sbtc.tools.js.map +0 -1
- package/dist/tools/scaffold.tools.d.ts.map +0 -1
- package/dist/tools/scaffold.tools.js.map +0 -1
- package/dist/tools/schemas.d.ts.map +0 -1
- package/dist/tools/schemas.js.map +0 -1
- package/dist/tools/settings.tools.d.ts.map +0 -1
- package/dist/tools/settings.tools.js.map +0 -1
- package/dist/tools/signing.tools.d.ts.map +0 -1
- package/dist/tools/signing.tools.js.map +0 -1
- package/dist/tools/skill-mappings.d.ts.map +0 -1
- package/dist/tools/skill-mappings.js.map +0 -1
- package/dist/tools/souldinals.tools.d.ts.map +0 -1
- package/dist/tools/souldinals.tools.js.map +0 -1
- package/dist/tools/stacking-lottery.tools.d.ts.map +0 -1
- package/dist/tools/stacking-lottery.tools.js.map +0 -1
- package/dist/tools/stacking.tools.d.ts.map +0 -1
- package/dist/tools/stacking.tools.js.map +0 -1
- package/dist/tools/stacks-market.tools.d.ts.map +0 -1
- package/dist/tools/stacks-market.tools.js.map +0 -1
- package/dist/tools/styx.tools.d.ts.map +0 -1
- package/dist/tools/styx.tools.js.map +0 -1
- package/dist/tools/taproot-multisig.tools.d.ts.map +0 -1
- package/dist/tools/taproot-multisig.tools.js.map +0 -1
- package/dist/tools/tenero.tools.d.ts.map +0 -1
- package/dist/tools/tenero.tools.js.map +0 -1
- package/dist/tools/tokens.tools.d.ts.map +0 -1
- package/dist/tools/tokens.tools.js.map +0 -1
- package/dist/tools/transfer.tools.d.ts.map +0 -1
- package/dist/tools/transfer.tools.js.map +0 -1
- package/dist/tools/wallet-management.tools.d.ts.map +0 -1
- package/dist/tools/wallet-management.tools.js.map +0 -1
- package/dist/tools/wallet.tools.d.ts.map +0 -1
- package/dist/tools/wallet.tools.js.map +0 -1
- package/dist/tools/yield-dashboard.tools.d.ts.map +0 -1
- package/dist/tools/yield-dashboard.tools.js.map +0 -1
- package/dist/tools/yield-hunter.tools.d.ts.map +0 -1
- package/dist/tools/yield-hunter.tools.js.map +0 -1
- package/dist/transactions/bitcoin-builder.d.ts.map +0 -1
- package/dist/transactions/bitcoin-builder.js.map +0 -1
- package/dist/transactions/builder.d.ts.map +0 -1
- package/dist/transactions/builder.js.map +0 -1
- package/dist/transactions/child-inscription-builder.d.ts.map +0 -1
- package/dist/transactions/child-inscription-builder.js.map +0 -1
- package/dist/transactions/clarity-values.d.ts.map +0 -1
- package/dist/transactions/clarity-values.js.map +0 -1
- package/dist/transactions/inscription-builder.d.ts.map +0 -1
- package/dist/transactions/inscription-builder.js.map +0 -1
- package/dist/transactions/post-conditions.d.ts.map +0 -1
- package/dist/transactions/post-conditions.js.map +0 -1
- package/dist/transactions/rune-transfer-builder.d.ts.map +0 -1
- package/dist/transactions/rune-transfer-builder.js.map +0 -1
- package/dist/transactions/runestone-builder.d.ts.map +0 -1
- package/dist/transactions/runestone-builder.js.map +0 -1
- package/dist/transactions/sponsor-builder.d.ts.map +0 -1
- package/dist/transactions/sponsor-builder.js.map +0 -1
- package/dist/utils/bip322.d.ts.map +0 -1
- package/dist/utils/bip322.js.map +0 -1
- package/dist/utils/bitcoin.d.ts.map +0 -1
- package/dist/utils/bitcoin.js.map +0 -1
- package/dist/utils/encryption.d.ts.map +0 -1
- package/dist/utils/encryption.js.map +0 -1
- package/dist/utils/erc8004-helpers.d.ts.map +0 -1
- package/dist/utils/erc8004-helpers.js.map +0 -1
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/fee.d.ts.map +0 -1
- package/dist/utils/fee.js.map +0 -1
- package/dist/utils/formatting.d.ts.map +0 -1
- package/dist/utils/formatting.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/l402-protocol.d.ts.map +0 -1
- package/dist/utils/l402-protocol.js.map +0 -1
- package/dist/utils/redact.d.ts.map +0 -1
- package/dist/utils/redact.js.map +0 -1
- package/dist/utils/relay-health.d.ts.map +0 -1
- package/dist/utils/relay-health.js.map +0 -1
- package/dist/utils/storage.d.ts.map +0 -1
- package/dist/utils/storage.js.map +0 -1
- package/dist/utils/tokens.d.ts.map +0 -1
- package/dist/utils/tokens.js.map +0 -1
- package/dist/utils/x402-payment-logging.d.ts.map +0 -1
- package/dist/utils/x402-payment-logging.js.map +0 -1
- package/dist/utils/x402-payment-state.d.ts.map +0 -1
- package/dist/utils/x402-payment-state.js.map +0 -1
- package/dist/utils/x402-protocol.d.ts.map +0 -1
- package/dist/utils/x402-protocol.js.map +0 -1
- package/dist/utils/x402-recovery.d.ts.map +0 -1
- package/dist/utils/x402-recovery.js.map +0 -1
- package/dist/yield-hunter/index.d.ts.map +0 -1
- package/dist/yield-hunter/index.js.map +0 -1
package/dist/tools/news.tools.js
CHANGED
|
@@ -56,21 +56,18 @@ async function getNextNonce(address) {
|
|
|
56
56
|
const hiroApi = getHiroApi(NETWORK);
|
|
57
57
|
const accountInfo = await hiroApi.getAccountInfo(address);
|
|
58
58
|
const confirmedNonce = accountInfo.nonce;
|
|
59
|
+
// The mempool scan is what makes the nonce safe against pending txs —
|
|
60
|
+
// silently skipping it on failure risks a nonce collision, so let it fail.
|
|
59
61
|
let highestMempoolNonce = -1;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
highestMempoolNonce = tx.nonce;
|
|
68
|
-
}
|
|
62
|
+
const mempool = await hiroApi.getMempoolTransactions({
|
|
63
|
+
sender_address: address,
|
|
64
|
+
limit: 50,
|
|
65
|
+
});
|
|
66
|
+
for (const tx of mempool.results) {
|
|
67
|
+
if (tx.nonce > highestMempoolNonce) {
|
|
68
|
+
highestMempoolNonce = tx.nonce;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
catch {
|
|
72
|
-
// Non-fatal
|
|
73
|
-
}
|
|
74
71
|
const chainNext = Math.max(confirmedNonce, highestMempoolNonce + 1);
|
|
75
72
|
await reconcileWithChain(address, chainNext);
|
|
76
73
|
return Math.max(chainNext, localNext ?? 0);
|
|
@@ -466,10 +463,11 @@ Fields:
|
|
|
466
463
|
server.registerTool("news_file_signal", {
|
|
467
464
|
description: `File a signal on a beat at aibtc.news.
|
|
468
465
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
466
|
+
Filing is free — no payment required. Requires an unlocked wallet with a
|
|
467
|
+
P2WPKH (bc1q) BTC address for BIP-322 authentication. If the endpoint ever
|
|
468
|
+
returns a 402 payment challenge, the tool falls back to the x402 sBTC flow:
|
|
469
|
+
1. POST with BIP-322 auth → signal filed (or receive 402 payment challenge)
|
|
470
|
+
2. On 402: build sponsored sBTC transfer (relay pays gas)
|
|
473
471
|
3. Retry with payment proof → signal filed
|
|
474
472
|
|
|
475
473
|
Authentication: BIP-322 signed headers (X-BTC-Address, X-BTC-Signature, X-BTC-Timestamp).
|
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import crypto from "crypto";
|
|
3
3
|
import { tupleCV, stringAsciiCV, uintCV, principalCV, noneCV, trueCV, falseCV, } from "@stacks/transactions";
|
|
4
4
|
import { getSigningKeyService, generateAuthId, } from "../services/signing-key.service.js";
|
|
5
|
-
import { getPillarApi } from "../services/pillar-api.service.js";
|
|
5
|
+
import { getPillarApi, PillarApiError } from "../services/pillar-api.service.js";
|
|
6
6
|
import { getHiroApi } from "../services/hiro-api.js";
|
|
7
7
|
import { NETWORK } from "../config/networks.js";
|
|
8
8
|
import { PILLAR_API_KEY } from "../config/pillar.js";
|
|
@@ -497,8 +497,12 @@ export function registerPillarDirectTools(server) {
|
|
|
497
497
|
const walletInfo = await api.get(`/api/smart-wallet/${walletName}`);
|
|
498
498
|
walletStatus = walletInfo.data?.status || null;
|
|
499
499
|
}
|
|
500
|
-
catch {
|
|
501
|
-
//
|
|
500
|
+
catch (error) {
|
|
501
|
+
// 404 = wallet not registered in backend. Anything else (network,
|
|
502
|
+
// 5xx) must surface, or an initialized wallet gets misreported.
|
|
503
|
+
if (!(error instanceof PillarApiError && error.status === 404)) {
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
502
506
|
}
|
|
503
507
|
if (!walletStatus || walletStatus === "pending_init") {
|
|
504
508
|
return createJsonResponse({
|
|
@@ -554,8 +558,11 @@ export function registerPillarDirectTools(server) {
|
|
|
554
558
|
});
|
|
555
559
|
position = unwindQuote.data;
|
|
556
560
|
}
|
|
557
|
-
catch {
|
|
558
|
-
//
|
|
561
|
+
catch (error) {
|
|
562
|
+
// 4xx = fresh wallet with no position. Infra failures must surface.
|
|
563
|
+
if (!(error instanceof PillarApiError && error.status < 500)) {
|
|
564
|
+
throw error;
|
|
565
|
+
}
|
|
559
566
|
}
|
|
560
567
|
return createJsonResponse({
|
|
561
568
|
success: true,
|
|
@@ -1146,21 +1153,16 @@ export function registerPillarDirectTools(server) {
|
|
|
1146
1153
|
const frac = (micro % BigInt(1_000_000)).toString().padStart(6, "0");
|
|
1147
1154
|
return `${whole}.${frac} STX`;
|
|
1148
1155
|
};
|
|
1149
|
-
// Fetch PoX cycle info
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
};
|
|
1160
|
-
}
|
|
1161
|
-
catch {
|
|
1162
|
-
// PoX info fetch failed, continue without it
|
|
1163
|
-
}
|
|
1156
|
+
// Fetch PoX cycle info — a global endpoint with no "not found" case,
|
|
1157
|
+
// so any failure is infrastructure and should surface.
|
|
1158
|
+
const pox = await hiro.getPoxInfo();
|
|
1159
|
+
const poxInfo = {
|
|
1160
|
+
currentCycleId: pox.current_cycle.id,
|
|
1161
|
+
nextCycleId: pox.next_cycle.id,
|
|
1162
|
+
blocksUntilNextCycle: pox.next_cycle.blocks_until_reward_phase,
|
|
1163
|
+
minAmountUstx: pox.min_amount_ustx,
|
|
1164
|
+
isPoxActive: pox.current_cycle.is_pox_active,
|
|
1165
|
+
};
|
|
1164
1166
|
// Check enrollment status via backend
|
|
1165
1167
|
const api = getPillarApi();
|
|
1166
1168
|
const contractParts = session.smartWallet.split(".");
|
|
@@ -1175,8 +1177,13 @@ export function registerPillarDirectTools(server) {
|
|
|
1175
1177
|
};
|
|
1176
1178
|
}
|
|
1177
1179
|
}
|
|
1178
|
-
catch {
|
|
1179
|
-
//
|
|
1180
|
+
catch (error) {
|
|
1181
|
+
// 404 = wallet not registered, so not enrolled. Other failures
|
|
1182
|
+
// must surface — defaulting to enrolled:false on a backend outage
|
|
1183
|
+
// misreports an enrolled wallet and could prompt re-enrollment.
|
|
1184
|
+
if (!(error instanceof PillarApiError && error.status === 404)) {
|
|
1185
|
+
throw error;
|
|
1186
|
+
}
|
|
1180
1187
|
}
|
|
1181
1188
|
const isStacking = lockedMicro > BigInt(0);
|
|
1182
1189
|
return createJsonResponse({
|
package/dist/tools/sbtc.tools.js
CHANGED
|
@@ -283,16 +283,9 @@ Signers later process the request and send BTC on L1.`,
|
|
|
283
283
|
description: "Get information about how to deposit BTC to receive sBTC.",
|
|
284
284
|
}, async () => {
|
|
285
285
|
try {
|
|
286
|
-
//
|
|
286
|
+
// getActiveAccount returns null when locked - generic instructions then
|
|
287
287
|
const walletManager = getWalletManager();
|
|
288
|
-
|
|
289
|
-
try {
|
|
290
|
-
account = walletManager.getActiveAccount();
|
|
291
|
-
}
|
|
292
|
-
catch {
|
|
293
|
-
// Wallet not unlocked - return generic instructions
|
|
294
|
-
account = null;
|
|
295
|
-
}
|
|
288
|
+
const account = walletManager.getActiveAccount();
|
|
296
289
|
// If wallet is unlocked and has Taproot keys, generate real deposit address
|
|
297
290
|
if (account?.taprootPublicKey) {
|
|
298
291
|
const depositService = getSbtcDepositService(NETWORK);
|
|
@@ -8,20 +8,15 @@ import { getWalletAddress } from "../services/x402.service.js";
|
|
|
8
8
|
* Check if a directory contains an existing x402 project
|
|
9
9
|
*/
|
|
10
10
|
async function isExistingX402Project(dir) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return hasIndex && hasMiddleware && hasPackage;
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
11
|
+
const indexPath = path.join(dir, "src", "index.ts");
|
|
12
|
+
const middlewarePath = path.join(dir, "src", "x402-middleware.ts");
|
|
13
|
+
const packagePath = path.join(dir, "package.json");
|
|
14
|
+
const [hasIndex, hasMiddleware, hasPackage] = await Promise.all([
|
|
15
|
+
fs.access(indexPath).then(() => true).catch(() => false),
|
|
16
|
+
fs.access(middlewarePath).then(() => true).catch(() => false),
|
|
17
|
+
fs.access(packagePath).then(() => true).catch(() => false),
|
|
18
|
+
]);
|
|
19
|
+
return hasIndex && hasMiddleware && hasPackage;
|
|
25
20
|
}
|
|
26
21
|
/**
|
|
27
22
|
* Validate that a project directory does not already exist.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { uintCV, contractPrincipalCV, PostConditionMode, deserializeCV, cvToJSON, } from "@stacks/transactions";
|
|
3
3
|
import { getAccount, NETWORK } from "../services/x402.service.js";
|
|
4
|
-
import { getHiroApi } from "../services/hiro-api.js";
|
|
4
|
+
import { getHiroApi, isNotFoundError } from "../services/hiro-api.js";
|
|
5
5
|
import { callContract } from "../transactions/builder.js";
|
|
6
6
|
import { getExplorerTxUrl } from "../config/networks.js";
|
|
7
7
|
import { createJsonResponse, createErrorResponse } from "../utils/index.js";
|
|
@@ -100,14 +100,17 @@ Note: Stackspot is only available on mainnet.`,
|
|
|
100
100
|
try {
|
|
101
101
|
currentValueUstx = await callPotReadOnly(pot.contractName, "get-pot-value", []);
|
|
102
102
|
}
|
|
103
|
-
catch {
|
|
104
|
-
// pot
|
|
103
|
+
catch (error) {
|
|
104
|
+
// 404 = pot contract not deployed; other failures surface
|
|
105
|
+
if (!isNotFoundError(error))
|
|
106
|
+
throw error;
|
|
105
107
|
}
|
|
106
108
|
try {
|
|
107
109
|
isLocked = await callPotReadOnly(pot.contractName, "is-locked", []);
|
|
108
110
|
}
|
|
109
|
-
catch {
|
|
110
|
-
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (!isNotFoundError(error))
|
|
113
|
+
throw error;
|
|
111
114
|
}
|
|
112
115
|
return {
|
|
113
116
|
name: pot.name,
|
|
@@ -251,21 +251,17 @@ async function readStackingPosition(walletAddress) {
|
|
|
251
251
|
return pos;
|
|
252
252
|
}
|
|
253
253
|
async function getWalletBalances(walletAddress) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return { stxMicroStx: 0, sbtcSats: 0 };
|
|
258
|
-
const data = (await res.json());
|
|
259
|
-
const stxMicroStx = parseInt(data.stx?.balance ?? "0", 10);
|
|
260
|
-
const sbtcKey = Object.keys(data.fungible_tokens ?? {}).find((k) => k.toLowerCase().includes("sbtc"));
|
|
261
|
-
const sbtcSats = sbtcKey
|
|
262
|
-
? parseInt(data.fungible_tokens?.[sbtcKey]?.balance ?? "0", 10)
|
|
263
|
-
: 0;
|
|
264
|
-
return { stxMicroStx, sbtcSats };
|
|
265
|
-
}
|
|
266
|
-
catch {
|
|
267
|
-
return { stxMicroStx: 0, sbtcSats: 0 };
|
|
254
|
+
const res = await fetch(`${MAINNET_HIRO_API}/extended/v1/address/${walletAddress}/balances`);
|
|
255
|
+
if (!res.ok) {
|
|
256
|
+
throw new Error(`Failed to fetch wallet balances for ${walletAddress}: HTTP ${res.status}`);
|
|
268
257
|
}
|
|
258
|
+
const data = (await res.json());
|
|
259
|
+
const stxMicroStx = parseInt(data.stx?.balance ?? "0", 10);
|
|
260
|
+
const sbtcKey = Object.keys(data.fungible_tokens ?? {}).find((k) => k.toLowerCase().includes("sbtc"));
|
|
261
|
+
const sbtcSats = sbtcKey
|
|
262
|
+
? parseInt(data.fungible_tokens?.[sbtcKey]?.balance ?? "0", 10)
|
|
263
|
+
: 0;
|
|
264
|
+
return { stxMicroStx, sbtcSats };
|
|
269
265
|
}
|
|
270
266
|
async function checkZestV2() {
|
|
271
267
|
try {
|
|
@@ -3,6 +3,7 @@ import { hexToBytes } from "@stacks/common";
|
|
|
3
3
|
import { getStacksNetwork, getApiBaseUrl } from "../config/networks.js";
|
|
4
4
|
import { getHiroApi } from "../services/hiro-api.js";
|
|
5
5
|
import { resolveDefaultFee } from "../utils/fee.js";
|
|
6
|
+
import { getSpendLimiter } from "../services/spend-limiter.js";
|
|
6
7
|
import { getTrackedNonce, recordNonceUsed, resetTrackedNonce, reconcileWithChain, } from "../services/nonce-tracker.js";
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
8
9
|
// Pending nonce tracking (unified via SharedNonceTracker, issue #413)
|
|
@@ -82,6 +83,9 @@ export function advancePendingNonce(address, nonce, txid = "") {
|
|
|
82
83
|
* @param fee Optional fee in micro-STX. If omitted, a medium-priority clamped fee is resolved.
|
|
83
84
|
*/
|
|
84
85
|
export async function transferStx(account, recipient, amount, memo, fee) {
|
|
86
|
+
// Safety rail: block before signing if this would exceed the wallet's
|
|
87
|
+
// cumulative spending limit (per-session or per-day).
|
|
88
|
+
await getSpendLimiter().check("ustx", amount, account.address);
|
|
85
89
|
const networkName = getStacksNetwork(account.network);
|
|
86
90
|
const nonce = await getNextNonce(account.address, account.network);
|
|
87
91
|
// Always resolve a clamped fee — prevents @stacks/transactions from over-estimating.
|
|
@@ -103,6 +107,7 @@ export async function transferStx(account, recipient, amount, memo, fee) {
|
|
|
103
107
|
throw new Error(`Broadcast failed: ${broadcastResponse.error} - ${broadcastResponse.reason}`);
|
|
104
108
|
}
|
|
105
109
|
advancePendingNonce(account.address, nonce, broadcastResponse.txid);
|
|
110
|
+
await getSpendLimiter().record("ustx", amount, account.address);
|
|
106
111
|
return {
|
|
107
112
|
txid: broadcastResponse.txid,
|
|
108
113
|
rawTx: transaction.serialize(),
|
package/dist/utils/encryption.js
CHANGED
|
@@ -37,6 +37,7 @@ export async function encrypt(plaintext, password) {
|
|
|
37
37
|
const key = await deriveKey(password, salt);
|
|
38
38
|
// Encrypt with AES-256-GCM
|
|
39
39
|
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
|
40
|
+
key.fill(0); // cipher holds its own copy
|
|
40
41
|
const encrypted = Buffer.concat([
|
|
41
42
|
cipher.update(plaintext, "utf8"),
|
|
42
43
|
cipher.final(),
|
|
@@ -64,6 +65,7 @@ export async function decrypt(encrypted, password) {
|
|
|
64
65
|
const key = await deriveKeyWithParams(password, salt, encrypted.scryptParams);
|
|
65
66
|
// Decrypt with AES-256-GCM
|
|
66
67
|
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
|
|
68
|
+
key.fill(0); // decipher holds its own copy
|
|
67
69
|
decipher.setAuthTag(authTag);
|
|
68
70
|
try {
|
|
69
71
|
const decrypted = Buffer.concat([
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aibtc/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.60.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",
|
|
@@ -14,13 +14,18 @@
|
|
|
14
14
|
"dev": "tsx src/index.ts",
|
|
15
15
|
"test": "vitest run",
|
|
16
16
|
"test:watch": "vitest",
|
|
17
|
+
"prepare": "git config core.hooksPath >/dev/null 2>&1 || git config core.hooksPath .githooks 2>/dev/null || true",
|
|
17
18
|
"prepublishOnly": "npm run build"
|
|
18
19
|
},
|
|
19
20
|
"files": [
|
|
20
21
|
"dist",
|
|
22
|
+
"!dist/**/*.map",
|
|
21
23
|
"README.md",
|
|
22
24
|
"skill"
|
|
23
25
|
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18.0.0"
|
|
28
|
+
},
|
|
24
29
|
"keywords": [
|
|
25
30
|
"claude",
|
|
26
31
|
"claude-code",
|
|
@@ -60,7 +65,7 @@
|
|
|
60
65
|
"@stacks/transactions": "^7.3.1",
|
|
61
66
|
"@stacks/wallet-sdk": "^7.2.0",
|
|
62
67
|
"alex-sdk": "^3.2.1",
|
|
63
|
-
"axios": "^1.
|
|
68
|
+
"axios": "^1.17.0",
|
|
64
69
|
"dotenv": "^17.3.1",
|
|
65
70
|
"light-bolt11-decoder": "^3.2.0",
|
|
66
71
|
"micro-ordinals": "^0.3.0",
|
|
@@ -68,7 +73,7 @@
|
|
|
68
73
|
"path-to-regexp": "^8.4.0",
|
|
69
74
|
"sbtc": "^0.3.2",
|
|
70
75
|
"tslib": "^2.8.1",
|
|
71
|
-
"ws": "^8.
|
|
76
|
+
"ws": "^8.21.0",
|
|
72
77
|
"x402-stacks": "^2.0.3",
|
|
73
78
|
"zod": "^4.3.6"
|
|
74
79
|
},
|
|
@@ -77,9 +82,10 @@
|
|
|
77
82
|
"@types/ws": "^8.18.1",
|
|
78
83
|
"tsx": "^4.21.0",
|
|
79
84
|
"typescript": "^5.9.3",
|
|
80
|
-
"vitest": "^4.
|
|
85
|
+
"vitest": "^4.1.8"
|
|
81
86
|
},
|
|
82
87
|
"overrides": {
|
|
83
|
-
"lodash": "^4.18.0"
|
|
88
|
+
"lodash": "^4.18.0",
|
|
89
|
+
"axios": "^1.17.0"
|
|
84
90
|
}
|
|
85
91
|
}
|
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.60.0 # x-release-please-version
|
|
8
8
|
npm: "@aibtc/mcp-server"
|
|
9
9
|
github: https://github.com/aibtcdev/aibtc-mcp-server
|
|
10
10
|
---
|