@aibtc/mcp-server 1.65.0 → 1.66.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/config/legion.d.ts +58 -0
- package/dist/config/legion.js +100 -0
- package/dist/services/legion.service.d.ts +188 -0
- package/dist/services/legion.service.js +410 -0
- package/dist/services/x402.service.d.ts +33 -4
- package/dist/services/x402.service.js +173 -6
- package/dist/tools/endpoint.tools.js +35 -9
- package/dist/tools/index.js +3 -0
- package/dist/tools/legion.tools.d.ts +16 -0
- package/dist/tools/legion.tools.js +1373 -0
- package/package.json +2 -1
- package/skill/SKILL.md +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { createApiClient, API_URL, probeEndpoint, formatPaymentAmount, checkSufficientBalance, generateDedupKey, checkDedupCache, recordTransaction, NETWORK } from "../services/x402.service.js";
|
|
2
|
+
import { createApiClient, API_URL, probeEndpoint, formatPaymentAmount, checkSufficientBalance, generateDedupKey, checkDedupCache, recordTransaction, X402_DEDUP_TTL_MS, NETWORK } from "../services/x402.service.js";
|
|
3
3
|
import { ALL_ENDPOINTS, searchEndpoints, formatEndpointsTable, getEndpointsBySource, getCategories, } from "../endpoints/registry.js";
|
|
4
4
|
import { createJsonResponse, createErrorResponse } from "../utils/index.js";
|
|
5
5
|
import { X402_HEADERS } from "../utils/x402-protocol.js";
|
|
@@ -270,6 +270,9 @@ For aibtc.com inbox messages, use send_inbox_message_direct instead — it signs
|
|
|
270
270
|
},
|
|
271
271
|
}, async ({ method, url, path, apiUrl, params, data, autoApprove, asset }) => {
|
|
272
272
|
let fullUrl = "";
|
|
273
|
+
// Hoisted so the catch can record a broadcast payment for dedup — a
|
|
274
|
+
// failed settlement still spends real funds (#630).
|
|
275
|
+
let dedupKey = null;
|
|
273
276
|
try {
|
|
274
277
|
const parsed = parseEndpointUrl({ url, path, apiUrl, params });
|
|
275
278
|
fullUrl = parsed.fullUrl;
|
|
@@ -281,14 +284,27 @@ For aibtc.com inbox messages, use send_inbox_message_direct instead — it signs
|
|
|
281
284
|
// autoApprove=true: check dedup cache before any network request, then execute
|
|
282
285
|
// with a single request. Balance validation happens inside the onBeforePayment
|
|
283
286
|
// callback when the interceptor receives the 402, eliminating the separate probe.
|
|
284
|
-
|
|
285
|
-
const existingTxid = checkDedupCache(dedupKey);
|
|
287
|
+
dedupKey = generateDedupKey(method, fullUrl, params, data);
|
|
288
|
+
const existingTxid = await checkDedupCache(dedupKey);
|
|
286
289
|
if (existingTxid) {
|
|
290
|
+
const windowSeconds = Math.round(X402_DEDUP_TTL_MS / 1000);
|
|
291
|
+
const pending = existingTxid.startsWith("pending:");
|
|
287
292
|
return createJsonResponse({
|
|
288
293
|
endpoint: `${method} ${fullUrl}`,
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
294
|
+
// Deliberately says "broadcast", not "paid": the entry is written
|
|
295
|
+
// whenever a payment was signed and broadcast, including when
|
|
296
|
+
// settlement then reported an error. Claiming it succeeded would
|
|
297
|
+
// be wrong in exactly the cases the caller most needs to check.
|
|
298
|
+
message: `An identical request already broadcast a payment within the last ${windowSeconds} seconds. This prevents accidental duplicate payments.`,
|
|
299
|
+
// A prior attempt whose txid was never observable is recorded with a
|
|
300
|
+
// synthetic marker. Report it as null rather than leaking the marker,
|
|
301
|
+
// which is not a chain txid and must not be treated as one.
|
|
302
|
+
txid: pending ? null : existingTxid,
|
|
303
|
+
...(pending && {
|
|
304
|
+
txidNote: "The earlier payment was broadcast but its txid was not observable in the response. " +
|
|
305
|
+
"Query get_account_transactions to find the settled txid before paying again.",
|
|
306
|
+
}),
|
|
307
|
+
note: `The earlier payment may have settled even if it reported an error — verify it before retrying. Wait ${windowSeconds}s or vary the endpoint/params to force a new transaction.`,
|
|
292
308
|
});
|
|
293
309
|
}
|
|
294
310
|
const api = await createApiClient(parsed.baseUrl, {
|
|
@@ -321,7 +337,7 @@ For aibtc.com inbox messages, use send_inbox_message_direct instead — it signs
|
|
|
321
337
|
// observable, using a synthetic pending marker that cannot be
|
|
322
338
|
// confused for a real chain txid.
|
|
323
339
|
if (paymentAttempted) {
|
|
324
|
-
recordTransaction(dedupKey, txid ?? `pending:${dedupKey}`);
|
|
340
|
+
await recordTransaction(dedupKey, txid ?? `pending:${dedupKey}`);
|
|
325
341
|
}
|
|
326
342
|
// Build the txid response fields per the behavior matrix:
|
|
327
343
|
// payment attempted + observable txid → { txid: "0x..." }
|
|
@@ -352,9 +368,20 @@ For aibtc.com inbox messages, use send_inbox_message_direct instead — it signs
|
|
|
352
368
|
// interceptor in x402.service.ts) and return it so the agent can verify.
|
|
353
369
|
const axiosError = error;
|
|
354
370
|
const canonicalStatus = axiosError.x402PaymentStatus;
|
|
371
|
+
// The presence of this header means the interceptor signed and
|
|
372
|
+
// broadcast a payment. That spends real funds whether or not
|
|
373
|
+
// settlement succeeded, so record it for dedup before returning any
|
|
374
|
+
// error — otherwise an identical retry passes the dedup guard and pays
|
|
375
|
+
// a second time for an invoice already settled on chain (#630).
|
|
376
|
+
// Mirrors the success path, including the synthetic pending marker
|
|
377
|
+
// used when the txid is not yet observable.
|
|
378
|
+
const paymentSigHeader = axiosError.config?.headers?.[X402_HEADERS.PAYMENT_SIGNATURE];
|
|
379
|
+
if (paymentSigHeader && dedupKey) {
|
|
380
|
+
const broadcastTxid = extractTxidFromPaymentSignature(paymentSigHeader);
|
|
381
|
+
await recordTransaction(dedupKey, broadcastTxid ?? `pending:${dedupKey}`);
|
|
382
|
+
}
|
|
355
383
|
if (canonicalStatus) {
|
|
356
384
|
const baseError = formatEndpointError(error, label);
|
|
357
|
-
const paymentSigHeader = axiosError.config?.headers?.[X402_HEADERS.PAYMENT_SIGNATURE];
|
|
358
385
|
const fallbackTxid = paymentSigHeader
|
|
359
386
|
? extractTxidFromPaymentSignature(paymentSigHeader)
|
|
360
387
|
: null;
|
|
@@ -382,7 +409,6 @@ For aibtc.com inbox messages, use send_inbox_message_direct instead — it signs
|
|
|
382
409
|
content: [{ type: "text", text }],
|
|
383
410
|
};
|
|
384
411
|
}
|
|
385
|
-
const paymentSigHeader = axiosError.config?.headers?.[X402_HEADERS.PAYMENT_SIGNATURE];
|
|
386
412
|
if (paymentSigHeader) {
|
|
387
413
|
const txid = extractTxidFromPaymentSignature(paymentSigHeader);
|
|
388
414
|
const fallbackPaymentId = extractPaymentIdFromPaymentSignature(paymentSigHeader);
|
package/dist/tools/index.js
CHANGED
|
@@ -36,6 +36,7 @@ import { registerJingswapTools } from "./jingswap.tools.js";
|
|
|
36
36
|
import { registerSigningTools } from "./signing.tools.js";
|
|
37
37
|
import { registerInferenceMarketplaceTools } from "./inference-marketplace.tools.js";
|
|
38
38
|
import { registerNewsTools } from "./news.tools.js";
|
|
39
|
+
import { registerLegionTools } from "./legion.tools.js";
|
|
39
40
|
import { registerIdentityTools } from "./identity.tools.js";
|
|
40
41
|
import { registerCredentialsTools } from "./credentials.tools.js";
|
|
41
42
|
import { registerSouldinalsTools } from "./souldinals.tools.js";
|
|
@@ -167,6 +168,8 @@ export function registerAllTools(server) {
|
|
|
167
168
|
registerInferenceMarketplaceTools(server);
|
|
168
169
|
// AIBTC News (signal feed, leaderboard, file signals)
|
|
169
170
|
registerNewsTools(server);
|
|
171
|
+
// AIBTC News Legion (news-gov-v5 governance — inscribe, propose, vote, veto, conclude)
|
|
172
|
+
registerLegionTools(server);
|
|
170
173
|
// Identity (ERC-8004 on-chain agent identity management)
|
|
171
174
|
registerIdentityTools(server);
|
|
172
175
|
// Credentials (encrypted credential store — list, get, set, delete, unlock)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIBTC News Legion tools (news-gov-v5).
|
|
3
|
+
*
|
|
4
|
+
* Lifecycle: inscribe → reveal → propose → vote → veto → conclude, plus
|
|
5
|
+
* contribute (buys weight) and sponsor (does not).
|
|
6
|
+
*
|
|
7
|
+
* These tools pin their own network: `getLegionAccount()` re-derives the
|
|
8
|
+
* unlocked wallet for the legion's chain, so a mainnet-configured server signs
|
|
9
|
+
* against testnet. Inscription is the exception — real BTC on whatever chain
|
|
10
|
+
* NETWORK names.
|
|
11
|
+
*
|
|
12
|
+
* Fund-moving calls sign in DENY mode with an exact post-condition.
|
|
13
|
+
*/
|
|
14
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
15
|
+
export declare function registerLegionTools(server: McpServer): void;
|
|
16
|
+
//# sourceMappingURL=legion.tools.d.ts.map
|