@t402/mcp 2.7.1 → 2.8.1
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/cjs/index.js +1652 -208
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/index.d.ts +41 -0
- package/dist/cjs/server/index.js +1652 -208
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/tools/index.d.ts +1215 -217
- package/dist/cjs/tools/index.js +1847 -173
- package/dist/cjs/tools/index.js.map +1 -1
- package/dist/esm/{chunk-3PMBXSJ3.mjs → chunk-4DCBAKH2.mjs} +218 -2
- package/dist/esm/chunk-4DCBAKH2.mjs.map +1 -0
- package/dist/esm/{chunk-B7X7H6NV.mjs → chunk-OSPCSAZF.mjs} +1800 -174
- package/dist/esm/chunk-OSPCSAZF.mjs.map +1 -0
- package/dist/esm/index.mjs +2 -2
- package/dist/esm/server/index.d.mts +41 -0
- package/dist/esm/server/index.mjs +2 -2
- package/dist/esm/tools/index.d.mts +1215 -217
- package/dist/esm/tools/index.mjs +94 -1
- package/package.json +15 -15
- package/dist/esm/chunk-3PMBXSJ3.mjs.map +0 -1
- package/dist/esm/chunk-B7X7H6NV.mjs.map +0 -1
package/dist/cjs/index.js
CHANGED
|
@@ -519,7 +519,8 @@ var payInputSchema = import_zod3.z.object({
|
|
|
519
519
|
"berachain",
|
|
520
520
|
"unichain"
|
|
521
521
|
]).describe("Network to execute payment on"),
|
|
522
|
-
memo: import_zod3.z.string().optional().describe("Optional memo/reference for the payment")
|
|
522
|
+
memo: import_zod3.z.string().optional().describe("Optional memo/reference for the payment"),
|
|
523
|
+
confirmed: import_zod3.z.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
523
524
|
});
|
|
524
525
|
function getViemChain2(network) {
|
|
525
526
|
switch (network) {
|
|
@@ -548,6 +549,13 @@ function getViemChain2(network) {
|
|
|
548
549
|
async function executePay(input, options) {
|
|
549
550
|
const { to, amount, token, network, memo: _memo } = input;
|
|
550
551
|
const { privateKey, rpcUrl, demoMode } = options;
|
|
552
|
+
if (!input.confirmed) {
|
|
553
|
+
return {
|
|
554
|
+
needsConfirmation: true,
|
|
555
|
+
summary: `Send ${amount} ${token} on ${network} to ${to}`,
|
|
556
|
+
details: { to, amount, token, network }
|
|
557
|
+
};
|
|
558
|
+
}
|
|
551
559
|
if (!supportsToken(network, token)) {
|
|
552
560
|
throw new Error(`Token ${token} is not supported on ${network}`);
|
|
553
561
|
}
|
|
@@ -632,7 +640,8 @@ var payGaslessInputSchema = import_zod4.z.object({
|
|
|
632
640
|
to: import_zod4.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address"),
|
|
633
641
|
amount: import_zod4.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to pay (e.g., '10.50' for 10.50 USDC)"),
|
|
634
642
|
token: import_zod4.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to use for payment"),
|
|
635
|
-
network: import_zod4.z.enum(["ethereum", "base", "arbitrum", "optimism", "polygon", "avalanche"]).describe("Network to execute gasless payment on (must support ERC-4337)")
|
|
643
|
+
network: import_zod4.z.enum(["ethereum", "base", "arbitrum", "optimism", "polygon", "avalanche"]).describe("Network to execute gasless payment on (must support ERC-4337)"),
|
|
644
|
+
confirmed: import_zod4.z.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
636
645
|
});
|
|
637
646
|
var GASLESS_SUPPORTED_NETWORKS = [
|
|
638
647
|
"ethereum",
|
|
@@ -669,6 +678,13 @@ function getViemChain3(network) {
|
|
|
669
678
|
async function executePayGasless(input, options) {
|
|
670
679
|
const { to, amount, token, network } = input;
|
|
671
680
|
const { privateKey, bundlerUrl, paymasterUrl: _paymasterUrl, rpcUrl, demoMode } = options;
|
|
681
|
+
if (!input.confirmed) {
|
|
682
|
+
return {
|
|
683
|
+
needsConfirmation: true,
|
|
684
|
+
summary: `Send ${amount} ${token} gasless on ${network} to ${to}`,
|
|
685
|
+
details: { to, amount, token, network }
|
|
686
|
+
};
|
|
687
|
+
}
|
|
672
688
|
if (!GASLESS_SUPPORTED_NETWORKS.includes(network)) {
|
|
673
689
|
throw new Error(
|
|
674
690
|
`Network ${network} does not support ERC-4337 gasless transactions. Supported: ${GASLESS_SUPPORTED_NETWORKS.join(", ")}`
|
|
@@ -954,7 +970,8 @@ var bridgeInputSchema = import_zod6.z.object({
|
|
|
954
970
|
fromChain: import_zod6.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Source chain to bridge from"),
|
|
955
971
|
toChain: import_zod6.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Destination chain to bridge to"),
|
|
956
972
|
amount: import_zod6.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"),
|
|
957
|
-
recipient: import_zod6.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain")
|
|
973
|
+
recipient: import_zod6.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain"),
|
|
974
|
+
confirmed: import_zod6.z.boolean().optional().describe("Set to true to confirm and execute this bridge")
|
|
958
975
|
});
|
|
959
976
|
var LAYERZERO_ENDPOINT_IDS2 = {
|
|
960
977
|
ethereum: 30101,
|
|
@@ -1081,6 +1098,13 @@ function addressToBytes322(address) {
|
|
|
1081
1098
|
async function executeBridge(input, options) {
|
|
1082
1099
|
const { fromChain, toChain, amount, recipient } = input;
|
|
1083
1100
|
const { privateKey, rpcUrl, demoMode, slippageTolerance = 0.5 } = options;
|
|
1101
|
+
if (!input.confirmed) {
|
|
1102
|
+
return {
|
|
1103
|
+
needsConfirmation: true,
|
|
1104
|
+
summary: `Bridge ${amount} USDT0 from ${fromChain} to ${toChain}`,
|
|
1105
|
+
details: { fromChain, toChain, amount, recipient }
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1084
1108
|
if (fromChain === toChain) {
|
|
1085
1109
|
throw new Error("Source and destination chains must be different");
|
|
1086
1110
|
}
|
|
@@ -1210,10 +1234,10 @@ var import_zod7 = require("zod");
|
|
|
1210
1234
|
var wdkGetWalletInputSchema = import_zod7.z.object({});
|
|
1211
1235
|
async function executeWdkGetWallet(_input, wdk) {
|
|
1212
1236
|
const signer = await wdk.getSigner("ethereum");
|
|
1213
|
-
const
|
|
1237
|
+
const chains10 = wdk.getConfiguredChains();
|
|
1214
1238
|
return {
|
|
1215
1239
|
evmAddress: signer.address,
|
|
1216
|
-
chains:
|
|
1240
|
+
chains: chains10.length > 0 ? chains10 : ["ethereum"]
|
|
1217
1241
|
};
|
|
1218
1242
|
}
|
|
1219
1243
|
function executeWdkGetWalletDemo() {
|
|
@@ -1245,14 +1269,14 @@ function findTokenFormatted(tokens, symbol) {
|
|
|
1245
1269
|
}
|
|
1246
1270
|
async function executeWdkGetBalances(input, wdk) {
|
|
1247
1271
|
const balances = await wdk.getAggregatedBalances();
|
|
1248
|
-
const
|
|
1272
|
+
const chains10 = balances.chains.filter((c) => !input.chains || input.chains.includes(c.chain)).map((c) => ({
|
|
1249
1273
|
chain: c.chain,
|
|
1250
1274
|
usdt0: findTokenFormatted(c.tokens, "USDT0"),
|
|
1251
1275
|
usdc: findTokenFormatted(c.tokens, "USDC"),
|
|
1252
1276
|
native: (0, import_viem6.formatUnits)(c.native, 18)
|
|
1253
1277
|
}));
|
|
1254
1278
|
return {
|
|
1255
|
-
chains:
|
|
1279
|
+
chains: chains10,
|
|
1256
1280
|
totalUsdt0: (0, import_viem6.formatUnits)(balances.totalUsdt0, 6),
|
|
1257
1281
|
totalUsdc: (0, import_viem6.formatUnits)(balances.totalUsdc, 6)
|
|
1258
1282
|
};
|
|
@@ -1294,9 +1318,17 @@ var wdkTransferInputSchema = import_zod9.z.object({
|
|
|
1294
1318
|
to: import_zod9.z.string().describe("Recipient address"),
|
|
1295
1319
|
amount: import_zod9.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to send (e.g., '10.50')"),
|
|
1296
1320
|
token: import_zod9.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to transfer"),
|
|
1297
|
-
chain: import_zod9.z.string().describe('Chain to execute transfer on (e.g., "ethereum", "arbitrum")')
|
|
1321
|
+
chain: import_zod9.z.string().describe('Chain to execute transfer on (e.g., "ethereum", "arbitrum")'),
|
|
1322
|
+
confirmed: import_zod9.z.boolean().optional().describe("Set to true to confirm and execute this transfer")
|
|
1298
1323
|
});
|
|
1299
1324
|
async function executeWdkTransfer(input, wdk) {
|
|
1325
|
+
if (!input.confirmed) {
|
|
1326
|
+
return {
|
|
1327
|
+
needsConfirmation: true,
|
|
1328
|
+
summary: `Transfer ${input.amount} ${input.token} on ${input.chain} to ${input.to}`,
|
|
1329
|
+
details: { to: input.to, amount: input.amount, token: input.token, chain: input.chain }
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1300
1332
|
const signer = await wdk.getSigner(input.chain);
|
|
1301
1333
|
const result = await signer.sendTransaction({
|
|
1302
1334
|
to: input.to
|
|
@@ -1313,6 +1345,13 @@ async function executeWdkTransfer(input, wdk) {
|
|
|
1313
1345
|
};
|
|
1314
1346
|
}
|
|
1315
1347
|
function executeWdkTransferDemo(input) {
|
|
1348
|
+
if (!input.confirmed) {
|
|
1349
|
+
return {
|
|
1350
|
+
needsConfirmation: true,
|
|
1351
|
+
summary: `Transfer ${input.amount} ${input.token} on ${input.chain} to ${input.to}`,
|
|
1352
|
+
details: { to: input.to, amount: input.amount, token: input.token, chain: input.chain }
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1316
1355
|
const demoTxHash = "0xdemo" + Math.random().toString(16).slice(2, 10);
|
|
1317
1356
|
return {
|
|
1318
1357
|
txHash: demoTxHash,
|
|
@@ -1342,9 +1381,22 @@ var wdkSwapInputSchema = import_zod10.z.object({
|
|
|
1342
1381
|
fromToken: import_zod10.z.string().describe('Token to swap from (e.g., "ETH", "USDC")'),
|
|
1343
1382
|
toToken: import_zod10.z.string().describe('Token to swap to (e.g., "USDT0", "USDC")'),
|
|
1344
1383
|
amount: import_zod10.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to swap (e.g., '1.0')"),
|
|
1345
|
-
chain: import_zod10.z.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")')
|
|
1384
|
+
chain: import_zod10.z.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")'),
|
|
1385
|
+
confirmed: import_zod10.z.boolean().optional().describe("Set to true to confirm and execute this swap")
|
|
1346
1386
|
});
|
|
1347
1387
|
async function executeWdkSwap(input, wdk) {
|
|
1388
|
+
if (!input.confirmed) {
|
|
1389
|
+
return {
|
|
1390
|
+
needsConfirmation: true,
|
|
1391
|
+
summary: `Swap ${input.amount} ${input.fromToken} to ${input.toToken} on ${input.chain}`,
|
|
1392
|
+
details: {
|
|
1393
|
+
fromToken: input.fromToken,
|
|
1394
|
+
toToken: input.toToken,
|
|
1395
|
+
amount: input.amount,
|
|
1396
|
+
chain: input.chain
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1348
1400
|
const decimals = ["USDC", "USDT", "USDT0"].includes(input.fromToken.toUpperCase()) ? 6 : 18;
|
|
1349
1401
|
const amountBigInt = (0, import_viem7.parseUnits)(input.amount, decimals);
|
|
1350
1402
|
const quote = await wdk.getSwapQuote(input.chain, input.fromToken, amountBigInt);
|
|
@@ -1365,6 +1417,18 @@ async function executeWdkSwap(input, wdk) {
|
|
|
1365
1417
|
};
|
|
1366
1418
|
}
|
|
1367
1419
|
function executeWdkSwapDemo(input) {
|
|
1420
|
+
if (!input.confirmed) {
|
|
1421
|
+
return {
|
|
1422
|
+
needsConfirmation: true,
|
|
1423
|
+
summary: `Swap ${input.amount} ${input.fromToken} to ${input.toToken} on ${input.chain}`,
|
|
1424
|
+
details: {
|
|
1425
|
+
fromToken: input.fromToken,
|
|
1426
|
+
toToken: input.toToken,
|
|
1427
|
+
amount: input.amount,
|
|
1428
|
+
chain: input.chain
|
|
1429
|
+
}
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1368
1432
|
const inputAmount = parseFloat(input.amount);
|
|
1369
1433
|
const outputAmount = (inputAmount * 0.997).toFixed(6);
|
|
1370
1434
|
return {
|
|
@@ -1397,25 +1461,52 @@ var autoPayInputSchema = import_zod11.z.object({
|
|
|
1397
1461
|
maxAmount: import_zod11.z.string().regex(/^\d+(\.\d+)?$/).optional().describe('Maximum amount willing to pay (e.g., "10.00"). If not set, pays any amount.'),
|
|
1398
1462
|
preferredChain: import_zod11.z.string().optional().describe(
|
|
1399
1463
|
'Preferred chain for payment (e.g., "arbitrum"). If not specified, uses first available.'
|
|
1400
|
-
)
|
|
1464
|
+
),
|
|
1465
|
+
confirmed: import_zod11.z.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
1401
1466
|
});
|
|
1402
1467
|
async function executeAutoPay(input, wdk) {
|
|
1403
|
-
|
|
1468
|
+
if (!input.confirmed) {
|
|
1469
|
+
return {
|
|
1470
|
+
needsConfirmation: true,
|
|
1471
|
+
summary: `Auto-pay for ${input.url}${input.maxAmount ? ` (max ${input.maxAmount})` : ""}`,
|
|
1472
|
+
details: {
|
|
1473
|
+
url: input.url,
|
|
1474
|
+
...input.maxAmount ? { maxAmount: input.maxAmount } : {},
|
|
1475
|
+
...input.preferredChain ? { preferredChain: input.preferredChain } : {}
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
const chains10 = input.preferredChain ? [input.preferredChain] : ["ethereum", "arbitrum", "base"];
|
|
1404
1480
|
const { T402Protocol } = await import("@t402/wdk-protocol");
|
|
1405
|
-
const protocol = await T402Protocol.create(wdk, { chains:
|
|
1406
|
-
|
|
1407
|
-
if (receipt && input.maxAmount) {
|
|
1408
|
-
const paidAmount = parseFloat(receipt.amount) / 1e6;
|
|
1481
|
+
const protocol = await T402Protocol.create(wdk, { chains: chains10 });
|
|
1482
|
+
if (input.maxAmount) {
|
|
1409
1483
|
const maxAmount = parseFloat(input.maxAmount);
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1484
|
+
const preflightResponse = await fetch(input.url);
|
|
1485
|
+
if (preflightResponse.status === 402) {
|
|
1486
|
+
const requirementsHeader = preflightResponse.headers.get("x-payment") || preflightResponse.headers.get("x-payment-requirements");
|
|
1487
|
+
if (requirementsHeader) {
|
|
1488
|
+
try {
|
|
1489
|
+
const requirements = JSON.parse(requirementsHeader);
|
|
1490
|
+
const reqArray = Array.isArray(requirements) ? requirements : [requirements];
|
|
1491
|
+
for (const req of reqArray) {
|
|
1492
|
+
if (req.amount) {
|
|
1493
|
+
const reqAmount = parseFloat(req.amount) / 1e6;
|
|
1494
|
+
if (reqAmount > maxAmount) {
|
|
1495
|
+
return {
|
|
1496
|
+
success: false,
|
|
1497
|
+
statusCode: 402,
|
|
1498
|
+
body: "",
|
|
1499
|
+
error: `Required payment amount (${reqAmount}) exceeds max allowed (${maxAmount})`
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
} catch {
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1417
1507
|
}
|
|
1418
1508
|
}
|
|
1509
|
+
const { response, receipt } = await protocol.fetch(input.url);
|
|
1419
1510
|
const contentType = response.headers.get("content-type") ?? void 0;
|
|
1420
1511
|
let body = "";
|
|
1421
1512
|
try {
|
|
@@ -1440,6 +1531,17 @@ async function executeAutoPay(input, wdk) {
|
|
|
1440
1531
|
};
|
|
1441
1532
|
}
|
|
1442
1533
|
function executeAutoPayDemo(input) {
|
|
1534
|
+
if (!input.confirmed) {
|
|
1535
|
+
return {
|
|
1536
|
+
needsConfirmation: true,
|
|
1537
|
+
summary: `Auto-pay for ${input.url}${input.maxAmount ? ` (max ${input.maxAmount})` : ""}`,
|
|
1538
|
+
details: {
|
|
1539
|
+
url: input.url,
|
|
1540
|
+
...input.maxAmount ? { maxAmount: input.maxAmount } : {},
|
|
1541
|
+
...input.preferredChain ? { preferredChain: input.preferredChain } : {}
|
|
1542
|
+
}
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1443
1545
|
return {
|
|
1444
1546
|
success: true,
|
|
1445
1547
|
statusCode: 200,
|
|
@@ -1883,174 +1985,981 @@ function formatErc8004VerifyWalletResult(result) {
|
|
|
1883
1985
|
return lines.join("\n");
|
|
1884
1986
|
}
|
|
1885
1987
|
|
|
1886
|
-
// src/tools/
|
|
1988
|
+
// src/tools/priceService.ts
|
|
1989
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1990
|
+
var COINGECKO_API = "https://api.coingecko.com/api/v3/simple/price";
|
|
1991
|
+
var TOKEN_TO_COINGECKO_ID = {
|
|
1992
|
+
ETH: "ethereum",
|
|
1993
|
+
MATIC: "matic-network",
|
|
1994
|
+
AVAX: "avalanche-2",
|
|
1995
|
+
BERA: "berachain-bera",
|
|
1996
|
+
USDC: "usd-coin",
|
|
1997
|
+
USDT: "tether",
|
|
1998
|
+
USDT0: "tether"
|
|
1999
|
+
};
|
|
2000
|
+
var cache = /* @__PURE__ */ new Map();
|
|
2001
|
+
async function getTokenPrices(tokens, currency = "usd") {
|
|
2002
|
+
const cacheKey = `${currency}:${tokens.sort().join(",")}`;
|
|
2003
|
+
const cached = cache.get(cacheKey);
|
|
2004
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
|
|
2005
|
+
return cached.prices;
|
|
2006
|
+
}
|
|
2007
|
+
const coinIds = /* @__PURE__ */ new Set();
|
|
2008
|
+
const tokenToCoinId = /* @__PURE__ */ new Map();
|
|
2009
|
+
for (const token of tokens) {
|
|
2010
|
+
const coinId = TOKEN_TO_COINGECKO_ID[token.toUpperCase()] ?? token.toLowerCase();
|
|
2011
|
+
coinIds.add(coinId);
|
|
2012
|
+
tokenToCoinId.set(token.toUpperCase(), coinId);
|
|
2013
|
+
}
|
|
2014
|
+
const url = `${COINGECKO_API}?ids=${[...coinIds].join(",")}&vs_currencies=${currency}`;
|
|
2015
|
+
const response = await fetch(url);
|
|
2016
|
+
if (!response.ok) {
|
|
2017
|
+
throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
|
|
2018
|
+
}
|
|
2019
|
+
const data = await response.json();
|
|
2020
|
+
const prices = {};
|
|
2021
|
+
for (const token of tokens) {
|
|
2022
|
+
const coinId = tokenToCoinId.get(token.toUpperCase()) ?? token.toLowerCase();
|
|
2023
|
+
prices[token.toUpperCase()] = data[coinId]?.[currency] ?? 0;
|
|
2024
|
+
}
|
|
2025
|
+
cache.set(cacheKey, { prices, timestamp: Date.now() });
|
|
2026
|
+
return prices;
|
|
2027
|
+
}
|
|
2028
|
+
function getTokenPricesDemo(tokens) {
|
|
2029
|
+
const demoPrices = {
|
|
2030
|
+
ETH: 3250.42,
|
|
2031
|
+
MATIC: 0.58,
|
|
2032
|
+
AVAX: 24.15,
|
|
2033
|
+
BERA: 3.82,
|
|
2034
|
+
USDC: 1,
|
|
2035
|
+
USDT: 1,
|
|
2036
|
+
USDT0: 1
|
|
2037
|
+
};
|
|
2038
|
+
const prices = {};
|
|
2039
|
+
for (const token of tokens) {
|
|
2040
|
+
prices[token.toUpperCase()] = demoPrices[token.toUpperCase()] ?? 0;
|
|
2041
|
+
}
|
|
2042
|
+
return prices;
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
// src/tools/getTokenPrice.ts
|
|
1887
2046
|
var import_zod15 = require("zod");
|
|
1888
|
-
var
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
preferredNetwork: import_zod15.z.string().optional().describe("Preferred network for payment (optional)")
|
|
2047
|
+
var getTokenPriceInputSchema = import_zod15.z.object({
|
|
2048
|
+
tokens: import_zod15.z.array(import_zod15.z.string()).min(1).describe('Token symbols to get prices for (e.g., ["ETH", "MATIC", "USDC"])'),
|
|
2049
|
+
currency: import_zod15.z.string().optional().describe('Target currency (default: "usd"). Supports: usd, eur, gbp, etc.')
|
|
1892
2050
|
});
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
});
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
name: "t402/smartPay",
|
|
1907
|
-
description: "Intelligent payment that automatically checks balance, bridges if needed, and pays. Handles the entire payment flow for 402-protected resources.",
|
|
1908
|
-
inputSchema: {
|
|
1909
|
-
type: "object",
|
|
1910
|
-
properties: {
|
|
1911
|
-
url: { type: "string", description: "URL of the 402-protected resource" },
|
|
1912
|
-
maxBridgeFee: {
|
|
1913
|
-
type: "string",
|
|
1914
|
-
description: "Maximum acceptable bridge fee in native token (optional)"
|
|
1915
|
-
},
|
|
1916
|
-
preferredNetwork: {
|
|
1917
|
-
type: "string",
|
|
1918
|
-
description: "Preferred network for payment (optional)"
|
|
1919
|
-
}
|
|
1920
|
-
},
|
|
1921
|
-
required: ["url"]
|
|
1922
|
-
}
|
|
1923
|
-
},
|
|
1924
|
-
"t402/paymentPlan": {
|
|
1925
|
-
name: "t402/paymentPlan",
|
|
1926
|
-
description: "Analyze a 402 response and create an optimal payment plan considering balances across all chains. Returns recommended network, bridge requirements, and balance overview.",
|
|
1927
|
-
inputSchema: {
|
|
1928
|
-
type: "object",
|
|
1929
|
-
properties: {
|
|
1930
|
-
paymentRequired: {
|
|
1931
|
-
type: "object",
|
|
1932
|
-
description: "The 402 PaymentRequired response"
|
|
1933
|
-
}
|
|
1934
|
-
},
|
|
1935
|
-
required: ["paymentRequired"]
|
|
2051
|
+
async function executeGetTokenPrice(input, options) {
|
|
2052
|
+
const currency = input.currency ?? "usd";
|
|
2053
|
+
const prices = options.demoMode ? getTokenPricesDemo(input.tokens) : await getTokenPrices(input.tokens, currency);
|
|
2054
|
+
return { prices, currency };
|
|
2055
|
+
}
|
|
2056
|
+
function formatTokenPriceResult(result) {
|
|
2057
|
+
const lines = ["## Token Prices", ""];
|
|
2058
|
+
const currencyUpper = result.currency.toUpperCase();
|
|
2059
|
+
for (const [token, price] of Object.entries(result.prices)) {
|
|
2060
|
+
if (price > 0) {
|
|
2061
|
+
lines.push(`- **${token}:** ${price.toLocaleString()} ${currencyUpper}`);
|
|
2062
|
+
} else {
|
|
2063
|
+
lines.push(`- **${token}:** Price unavailable`);
|
|
1936
2064
|
}
|
|
1937
2065
|
}
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2066
|
+
return lines.join("\n");
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
// src/tools/getGasPrice.ts
|
|
2070
|
+
var import_zod16 = require("zod");
|
|
2071
|
+
var import_viem9 = require("viem");
|
|
2072
|
+
var chains7 = __toESM(require("viem/chains"));
|
|
2073
|
+
var getGasPriceInputSchema = import_zod16.z.object({
|
|
2074
|
+
network: import_zod16.z.enum([
|
|
2075
|
+
"ethereum",
|
|
2076
|
+
"base",
|
|
2077
|
+
"arbitrum",
|
|
2078
|
+
"optimism",
|
|
2079
|
+
"polygon",
|
|
2080
|
+
"avalanche",
|
|
2081
|
+
"ink",
|
|
2082
|
+
"berachain",
|
|
2083
|
+
"unichain"
|
|
2084
|
+
]).describe("Blockchain network to check gas price on")
|
|
2085
|
+
});
|
|
2086
|
+
function getViemChain6(network) {
|
|
2087
|
+
switch (network) {
|
|
2088
|
+
case "ethereum":
|
|
2089
|
+
return chains7.mainnet;
|
|
2090
|
+
case "base":
|
|
2091
|
+
return chains7.base;
|
|
2092
|
+
case "arbitrum":
|
|
2093
|
+
return chains7.arbitrum;
|
|
2094
|
+
case "optimism":
|
|
2095
|
+
return chains7.optimism;
|
|
2096
|
+
case "polygon":
|
|
2097
|
+
return chains7.polygon;
|
|
2098
|
+
case "avalanche":
|
|
2099
|
+
return chains7.avalanche;
|
|
2100
|
+
case "ink":
|
|
2101
|
+
return chains7.ink;
|
|
2102
|
+
case "berachain":
|
|
2103
|
+
return chains7.berachain;
|
|
2104
|
+
case "unichain":
|
|
2105
|
+
return chains7.unichain;
|
|
2106
|
+
default:
|
|
2107
|
+
return chains7.mainnet;
|
|
1961
2108
|
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2109
|
+
}
|
|
2110
|
+
async function executeGetGasPrice(input, options) {
|
|
2111
|
+
const { network } = input;
|
|
2112
|
+
if (options.demoMode) {
|
|
2113
|
+
const demoGasPrices = {
|
|
2114
|
+
ethereum: 25000000000n,
|
|
2115
|
+
// 25 gwei
|
|
2116
|
+
base: 50000000n,
|
|
2117
|
+
// 0.05 gwei
|
|
2118
|
+
arbitrum: 100000000n,
|
|
2119
|
+
// 0.1 gwei
|
|
2120
|
+
optimism: 50000000n,
|
|
2121
|
+
// 0.05 gwei
|
|
2122
|
+
polygon: 30000000000n,
|
|
2123
|
+
// 30 gwei
|
|
2124
|
+
avalanche: 25000000000n,
|
|
2125
|
+
// 25 nAVAX
|
|
2126
|
+
ink: 50000000n,
|
|
2127
|
+
// 0.05 gwei
|
|
2128
|
+
berachain: 1000000000n,
|
|
2129
|
+
// 1 gwei
|
|
2130
|
+
unichain: 50000000n
|
|
2131
|
+
// 0.05 gwei
|
|
2132
|
+
};
|
|
2133
|
+
const gasPrice2 = demoGasPrices[network] ?? 1000000000n;
|
|
2134
|
+
return {
|
|
2135
|
+
network,
|
|
2136
|
+
gasPriceWei: gasPrice2.toString(),
|
|
2137
|
+
gasPriceGwei: (0, import_viem9.formatGwei)(gasPrice2),
|
|
2138
|
+
nativeSymbol: NATIVE_SYMBOLS[network]
|
|
2139
|
+
};
|
|
1971
2140
|
}
|
|
2141
|
+
const chain = getViemChain6(network);
|
|
2142
|
+
const transport = (0, import_viem9.http)(options.rpcUrl ?? DEFAULT_RPC_URLS[network]);
|
|
2143
|
+
const client = (0, import_viem9.createPublicClient)({ chain, transport });
|
|
2144
|
+
const gasPrice = await client.getGasPrice();
|
|
1972
2145
|
return {
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
steps,
|
|
1978
|
-
payment: receipt ? {
|
|
1979
|
-
network: receipt.network,
|
|
1980
|
-
scheme: receipt.scheme,
|
|
1981
|
-
amount: receipt.amount,
|
|
1982
|
-
payTo: receipt.payTo
|
|
1983
|
-
} : void 0
|
|
2146
|
+
network,
|
|
2147
|
+
gasPriceWei: gasPrice.toString(),
|
|
2148
|
+
gasPriceGwei: (0, import_viem9.formatGwei)(gasPrice),
|
|
2149
|
+
nativeSymbol: NATIVE_SYMBOLS[network]
|
|
1984
2150
|
};
|
|
1985
2151
|
}
|
|
1986
|
-
function
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
2152
|
+
function formatGasPriceResult(result) {
|
|
2153
|
+
return [
|
|
2154
|
+
"## Gas Price",
|
|
2155
|
+
"",
|
|
2156
|
+
`- **Network:** ${result.network}`,
|
|
2157
|
+
`- **Gas Price:** ${result.gasPriceGwei} gwei`,
|
|
2158
|
+
`- **Native Token:** ${result.nativeSymbol}`
|
|
2159
|
+
].join("\n");
|
|
2160
|
+
}
|
|
1992
2161
|
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2162
|
+
// src/tools/estimatePaymentFee.ts
|
|
2163
|
+
var import_zod17 = require("zod");
|
|
2164
|
+
var import_viem10 = require("viem");
|
|
2165
|
+
var chains8 = __toESM(require("viem/chains"));
|
|
2166
|
+
var estimatePaymentFeeInputSchema = import_zod17.z.object({
|
|
2167
|
+
network: import_zod17.z.enum([
|
|
2168
|
+
"ethereum",
|
|
2169
|
+
"base",
|
|
2170
|
+
"arbitrum",
|
|
2171
|
+
"optimism",
|
|
2172
|
+
"polygon",
|
|
2173
|
+
"avalanche",
|
|
2174
|
+
"ink",
|
|
2175
|
+
"berachain",
|
|
2176
|
+
"unichain"
|
|
2177
|
+
]).describe("Network to estimate fee on"),
|
|
2178
|
+
amount: import_zod17.z.string().regex(/^\d+(\.\d+)?$/).describe("Payment amount (e.g., '100')"),
|
|
2179
|
+
token: import_zod17.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to use for payment")
|
|
2180
|
+
});
|
|
2181
|
+
function getViemChain7(network) {
|
|
2182
|
+
switch (network) {
|
|
2183
|
+
case "ethereum":
|
|
2184
|
+
return chains8.mainnet;
|
|
2185
|
+
case "base":
|
|
2186
|
+
return chains8.base;
|
|
2187
|
+
case "arbitrum":
|
|
2188
|
+
return chains8.arbitrum;
|
|
2189
|
+
case "optimism":
|
|
2190
|
+
return chains8.optimism;
|
|
2191
|
+
case "polygon":
|
|
2192
|
+
return chains8.polygon;
|
|
2193
|
+
case "avalanche":
|
|
2194
|
+
return chains8.avalanche;
|
|
2195
|
+
case "ink":
|
|
2196
|
+
return chains8.ink;
|
|
2197
|
+
case "berachain":
|
|
2198
|
+
return chains8.berachain;
|
|
2199
|
+
case "unichain":
|
|
2200
|
+
return chains8.unichain;
|
|
2201
|
+
default:
|
|
2202
|
+
return chains8.mainnet;
|
|
2203
|
+
}
|
|
2008
2204
|
}
|
|
2009
|
-
async function
|
|
2010
|
-
const
|
|
2011
|
-
const
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2205
|
+
async function executeEstimatePaymentFee(input, options) {
|
|
2206
|
+
const { network, amount, token } = input;
|
|
2207
|
+
const nativeSymbol = NATIVE_SYMBOLS[network];
|
|
2208
|
+
if (options.demoMode) {
|
|
2209
|
+
const demoEstimates = {
|
|
2210
|
+
ethereum: { gasLimit: 65000n, gasPrice: 25000000000n, nativePrice: 3250.42 },
|
|
2211
|
+
base: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 },
|
|
2212
|
+
arbitrum: { gasLimit: 65000n, gasPrice: 100000000n, nativePrice: 3250.42 },
|
|
2213
|
+
optimism: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 },
|
|
2214
|
+
polygon: { gasLimit: 65000n, gasPrice: 30000000000n, nativePrice: 0.58 },
|
|
2215
|
+
avalanche: { gasLimit: 65000n, gasPrice: 25000000000n, nativePrice: 24.15 },
|
|
2216
|
+
ink: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 },
|
|
2217
|
+
berachain: { gasLimit: 65000n, gasPrice: 1000000000n, nativePrice: 3.82 },
|
|
2218
|
+
unichain: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 }
|
|
2020
2219
|
};
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
if (bestChain) {
|
|
2025
|
-
const needsBridge = targetNetwork ? !bestChain.chain.includes(targetNetwork) : false;
|
|
2220
|
+
const est = demoEstimates[network] ?? demoEstimates["ethereum"];
|
|
2221
|
+
const nativeCost2 = est.gasLimit * est.gasPrice;
|
|
2222
|
+
const usdCost2 = Number(nativeCost2) / 1e18 * est.nativePrice;
|
|
2026
2223
|
return {
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
toChain: targetNetwork ?? bestChain.chain,
|
|
2034
|
-
amount: requiredAmount ?? "0",
|
|
2035
|
-
estimatedFee: "0.001"
|
|
2036
|
-
} : void 0,
|
|
2037
|
-
balances
|
|
2224
|
+
network,
|
|
2225
|
+
gasLimit: est.gasLimit.toString(),
|
|
2226
|
+
gasPriceGwei: (0, import_viem10.formatGwei)(est.gasPrice),
|
|
2227
|
+
nativeCost: (0, import_viem10.formatEther)(nativeCost2),
|
|
2228
|
+
nativeSymbol,
|
|
2229
|
+
usdCost: `$${usdCost2.toFixed(4)}`
|
|
2038
2230
|
};
|
|
2039
2231
|
}
|
|
2232
|
+
const tokenAddress = getTokenAddress(network, token);
|
|
2233
|
+
if (!tokenAddress) {
|
|
2234
|
+
throw new Error(`Token ${token} is not supported on ${network}`);
|
|
2235
|
+
}
|
|
2236
|
+
const chain = getViemChain7(network);
|
|
2237
|
+
const transport = (0, import_viem10.http)(options.rpcUrl ?? DEFAULT_RPC_URLS[network]);
|
|
2238
|
+
const client = (0, import_viem10.createPublicClient)({ chain, transport });
|
|
2239
|
+
const amountBigInt = (0, import_viem10.parseUnits)(amount, 6);
|
|
2240
|
+
const dummyTo = "0x000000000000000000000000000000000000dEaD";
|
|
2241
|
+
let gasLimit;
|
|
2242
|
+
try {
|
|
2243
|
+
gasLimit = await client.estimateGas({
|
|
2244
|
+
to: tokenAddress,
|
|
2245
|
+
data: `0xa9059cbb${dummyTo.slice(2).padStart(64, "0")}${amountBigInt.toString(16).padStart(64, "0")}`
|
|
2246
|
+
});
|
|
2247
|
+
} catch {
|
|
2248
|
+
gasLimit = 65000n;
|
|
2249
|
+
}
|
|
2250
|
+
const gasPrice = await client.getGasPrice();
|
|
2251
|
+
const nativeCost = gasLimit * gasPrice;
|
|
2252
|
+
let usdCost;
|
|
2253
|
+
try {
|
|
2254
|
+
const prices = await getTokenPrices([nativeSymbol]);
|
|
2255
|
+
const nativePrice = prices[nativeSymbol] ?? 0;
|
|
2256
|
+
const cost = Number(nativeCost) / 1e18 * nativePrice;
|
|
2257
|
+
usdCost = `$${cost.toFixed(4)}`;
|
|
2258
|
+
} catch {
|
|
2259
|
+
usdCost = "N/A";
|
|
2260
|
+
}
|
|
2040
2261
|
return {
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2262
|
+
network,
|
|
2263
|
+
gasLimit: gasLimit.toString(),
|
|
2264
|
+
gasPriceGwei: (0, import_viem10.formatGwei)(gasPrice),
|
|
2265
|
+
nativeCost: (0, import_viem10.formatEther)(nativeCost),
|
|
2266
|
+
nativeSymbol,
|
|
2267
|
+
usdCost
|
|
2045
2268
|
};
|
|
2046
2269
|
}
|
|
2047
|
-
function
|
|
2048
|
-
return
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2270
|
+
function formatPaymentFeeEstimate(result) {
|
|
2271
|
+
return [
|
|
2272
|
+
"## Payment Fee Estimate",
|
|
2273
|
+
"",
|
|
2274
|
+
`- **Network:** ${result.network}`,
|
|
2275
|
+
`- **Estimated Gas:** ${result.gasLimit}`,
|
|
2276
|
+
`- **Gas Price:** ${result.gasPriceGwei} gwei`,
|
|
2277
|
+
`- **Native Cost:** ${result.nativeCost} ${result.nativeSymbol}`,
|
|
2278
|
+
`- **USD Cost:** ${result.usdCost}`
|
|
2279
|
+
].join("\n");
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
// src/tools/compareNetworkFees.ts
|
|
2283
|
+
var import_zod18 = require("zod");
|
|
2284
|
+
var compareNetworkFeesInputSchema = import_zod18.z.object({
|
|
2285
|
+
amount: import_zod18.z.string().regex(/^\d+(\.\d+)?$/).describe("Payment amount (e.g., '100')"),
|
|
2286
|
+
token: import_zod18.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to use for payment"),
|
|
2287
|
+
networks: import_zod18.z.array(import_zod18.z.string()).optional().describe(
|
|
2288
|
+
"Networks to compare. If not provided, compares all networks that support the token."
|
|
2289
|
+
)
|
|
2290
|
+
});
|
|
2291
|
+
var ALL_NETWORKS2 = [
|
|
2292
|
+
"ethereum",
|
|
2293
|
+
"base",
|
|
2294
|
+
"arbitrum",
|
|
2295
|
+
"optimism",
|
|
2296
|
+
"polygon",
|
|
2297
|
+
"avalanche",
|
|
2298
|
+
"ink",
|
|
2299
|
+
"berachain",
|
|
2300
|
+
"unichain"
|
|
2301
|
+
];
|
|
2302
|
+
async function executeCompareNetworkFees(input, options) {
|
|
2303
|
+
const { amount, token } = input;
|
|
2304
|
+
const requestedNetworks = input.networks ? input.networks : ALL_NETWORKS2;
|
|
2305
|
+
const networks = requestedNetworks.filter((n) => supportsToken(n, token));
|
|
2306
|
+
if (networks.length === 0) {
|
|
2307
|
+
throw new Error(`No supported networks found for token ${token}`);
|
|
2308
|
+
}
|
|
2309
|
+
const results = await Promise.allSettled(
|
|
2310
|
+
networks.map(
|
|
2311
|
+
(network) => executeEstimatePaymentFee(
|
|
2312
|
+
{ network, amount, token },
|
|
2313
|
+
{
|
|
2314
|
+
rpcUrl: options.rpcUrls?.[network],
|
|
2315
|
+
demoMode: options.demoMode
|
|
2316
|
+
}
|
|
2317
|
+
)
|
|
2318
|
+
)
|
|
2319
|
+
);
|
|
2320
|
+
const fees = [];
|
|
2321
|
+
for (const result of results) {
|
|
2322
|
+
if (result.status === "fulfilled") {
|
|
2323
|
+
fees.push(result.value);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
if (fees.length === 0) {
|
|
2327
|
+
throw new Error("Failed to estimate fees on any network");
|
|
2328
|
+
}
|
|
2329
|
+
fees.sort((a, b) => {
|
|
2330
|
+
const costA = parseFloat(a.nativeCost) || Infinity;
|
|
2331
|
+
const costB = parseFloat(b.nativeCost) || Infinity;
|
|
2332
|
+
const usdA = parseFloat(a.usdCost.replace("$", "")) || Infinity;
|
|
2333
|
+
const usdB = parseFloat(b.usdCost.replace("$", "")) || Infinity;
|
|
2334
|
+
return usdA - usdB || costA - costB;
|
|
2335
|
+
});
|
|
2336
|
+
return {
|
|
2337
|
+
token,
|
|
2338
|
+
amount,
|
|
2339
|
+
fees,
|
|
2340
|
+
cheapest: fees[0].network
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
function formatNetworkFeeComparison(result) {
|
|
2344
|
+
const lines = [
|
|
2345
|
+
"## Network Fee Comparison",
|
|
2346
|
+
"",
|
|
2347
|
+
`**Token:** ${result.token} | **Amount:** ${result.amount}`,
|
|
2348
|
+
`**Cheapest:** ${result.cheapest}`,
|
|
2349
|
+
"",
|
|
2350
|
+
"| Network | Gas Price | Native Cost | USD Cost |",
|
|
2351
|
+
"|---------|----------|-------------|----------|"
|
|
2352
|
+
];
|
|
2353
|
+
for (const fee of result.fees) {
|
|
2354
|
+
const marker = fee.network === result.cheapest ? " *" : "";
|
|
2355
|
+
lines.push(
|
|
2356
|
+
`| ${fee.network}${marker} | ${fee.gasPriceGwei} gwei | ${fee.nativeCost} ${fee.nativeSymbol} | ${fee.usdCost} |`
|
|
2357
|
+
);
|
|
2358
|
+
}
|
|
2359
|
+
return lines.join("\n");
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
// src/tools/signMessage.ts
|
|
2363
|
+
var import_zod19 = require("zod");
|
|
2364
|
+
var signMessageInputSchema = import_zod19.z.object({
|
|
2365
|
+
chain: import_zod19.z.enum([
|
|
2366
|
+
"ethereum",
|
|
2367
|
+
"base",
|
|
2368
|
+
"arbitrum",
|
|
2369
|
+
"optimism",
|
|
2370
|
+
"polygon",
|
|
2371
|
+
"avalanche",
|
|
2372
|
+
"ink",
|
|
2373
|
+
"berachain",
|
|
2374
|
+
"unichain"
|
|
2375
|
+
]).describe("Blockchain network context for signing"),
|
|
2376
|
+
message: import_zod19.z.string().min(1).describe("Message to sign")
|
|
2377
|
+
});
|
|
2378
|
+
|
|
2379
|
+
// src/tools/verifySignature.ts
|
|
2380
|
+
var import_zod20 = require("zod");
|
|
2381
|
+
var import_viem11 = require("viem");
|
|
2382
|
+
var verifySignatureInputSchema = import_zod20.z.object({
|
|
2383
|
+
chain: import_zod20.z.enum([
|
|
2384
|
+
"ethereum",
|
|
2385
|
+
"base",
|
|
2386
|
+
"arbitrum",
|
|
2387
|
+
"optimism",
|
|
2388
|
+
"polygon",
|
|
2389
|
+
"avalanche",
|
|
2390
|
+
"ink",
|
|
2391
|
+
"berachain",
|
|
2392
|
+
"unichain"
|
|
2393
|
+
]).describe("Blockchain network context for verification"),
|
|
2394
|
+
message: import_zod20.z.string().min(1).describe("The original message that was signed"),
|
|
2395
|
+
signature: import_zod20.z.string().regex(/^0x[a-fA-F0-9]+$/).describe("The signature to verify (hex string)"),
|
|
2396
|
+
address: import_zod20.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("The expected signer address")
|
|
2397
|
+
});
|
|
2398
|
+
|
|
2399
|
+
// src/tools/getTransferHistory.ts
|
|
2400
|
+
var import_zod21 = require("zod");
|
|
2401
|
+
var import_viem12 = require("viem");
|
|
2402
|
+
var chains9 = __toESM(require("viem/chains"));
|
|
2403
|
+
var getTransferHistoryInputSchema = import_zod21.z.object({
|
|
2404
|
+
network: import_zod21.z.enum([
|
|
2405
|
+
"ethereum",
|
|
2406
|
+
"base",
|
|
2407
|
+
"arbitrum",
|
|
2408
|
+
"optimism",
|
|
2409
|
+
"polygon",
|
|
2410
|
+
"avalanche",
|
|
2411
|
+
"ink",
|
|
2412
|
+
"berachain",
|
|
2413
|
+
"unichain"
|
|
2414
|
+
]).describe("Blockchain network to query"),
|
|
2415
|
+
address: import_zod21.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Wallet address to get transfer history for"),
|
|
2416
|
+
token: import_zod21.z.enum(["USDC", "USDT", "USDT0"]).optional().describe("Filter by specific token. If not provided, queries all supported stablecoins."),
|
|
2417
|
+
limit: import_zod21.z.number().int().min(1).max(100).optional().describe("Maximum number of transfers to return (default: 10, max: 100)")
|
|
2418
|
+
});
|
|
2419
|
+
|
|
2420
|
+
// src/tools/getHistoricalPrice.ts
|
|
2421
|
+
var import_zod22 = require("zod");
|
|
2422
|
+
var getHistoricalPriceInputSchema = import_zod22.z.object({
|
|
2423
|
+
token: import_zod22.z.string().min(1).describe('Token symbol (e.g., "ETH", "USDC", "USDT", "MATIC", "AVAX")'),
|
|
2424
|
+
days: import_zod22.z.number().int().min(1).max(365).optional().describe("Number of days of history to retrieve (default: 7, max: 365)")
|
|
2425
|
+
});
|
|
2426
|
+
|
|
2427
|
+
// src/tools/quoteStore.ts
|
|
2428
|
+
var import_crypto = require("crypto");
|
|
2429
|
+
var DEFAULT_TTL_MS = 5 * 60 * 1e3;
|
|
2430
|
+
var quotes = /* @__PURE__ */ new Map();
|
|
2431
|
+
var cleanupInterval = null;
|
|
2432
|
+
function ensureCleanup() {
|
|
2433
|
+
if (cleanupInterval) return;
|
|
2434
|
+
cleanupInterval = setInterval(() => {
|
|
2435
|
+
const now = Date.now();
|
|
2436
|
+
for (const [id, quote] of quotes) {
|
|
2437
|
+
if (now > quote.expiresAt) {
|
|
2438
|
+
quotes.delete(id);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
}, 6e4);
|
|
2442
|
+
if (cleanupInterval.unref) {
|
|
2443
|
+
cleanupInterval.unref();
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
function createQuote(type, data, ttlMs = DEFAULT_TTL_MS) {
|
|
2447
|
+
ensureCleanup();
|
|
2448
|
+
const id = (0, import_crypto.randomUUID)();
|
|
2449
|
+
const now = Date.now();
|
|
2450
|
+
quotes.set(id, {
|
|
2451
|
+
id,
|
|
2452
|
+
type,
|
|
2453
|
+
createdAt: now,
|
|
2454
|
+
expiresAt: now + ttlMs,
|
|
2455
|
+
data
|
|
2456
|
+
});
|
|
2457
|
+
return id;
|
|
2458
|
+
}
|
|
2459
|
+
function getQuote(quoteId) {
|
|
2460
|
+
const quote = quotes.get(quoteId);
|
|
2461
|
+
if (!quote) return null;
|
|
2462
|
+
if (Date.now() > quote.expiresAt) {
|
|
2463
|
+
quotes.delete(quoteId);
|
|
2464
|
+
return null;
|
|
2465
|
+
}
|
|
2466
|
+
return quote;
|
|
2467
|
+
}
|
|
2468
|
+
function deleteQuote(quoteId) {
|
|
2469
|
+
quotes.delete(quoteId);
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
// src/tools/wdkQuoteSwap.ts
|
|
2473
|
+
var import_zod23 = require("zod");
|
|
2474
|
+
var import_viem13 = require("viem");
|
|
2475
|
+
var wdkQuoteSwapInputSchema = import_zod23.z.object({
|
|
2476
|
+
fromToken: import_zod23.z.string().describe('Token to swap from (e.g., "ETH", "USDC")'),
|
|
2477
|
+
toToken: import_zod23.z.string().describe('Token to swap to (e.g., "USDT0", "USDC")'),
|
|
2478
|
+
amount: import_zod23.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to swap (e.g., '1.0')"),
|
|
2479
|
+
chain: import_zod23.z.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")')
|
|
2480
|
+
});
|
|
2481
|
+
async function executeWdkQuoteSwap(input, wdk) {
|
|
2482
|
+
const decimals = ["USDC", "USDT", "USDT0"].includes(input.fromToken.toUpperCase()) ? 6 : 18;
|
|
2483
|
+
const amountBigInt = (0, import_viem13.parseUnits)(input.amount, decimals);
|
|
2484
|
+
const quote = await wdk.getSwapQuote(input.chain, input.fromToken, amountBigInt);
|
|
2485
|
+
const outputDecimals = ["USDC", "USDT", "USDT0"].includes(input.toToken.toUpperCase()) ? 6 : 18;
|
|
2486
|
+
const outputDivisor = 10 ** outputDecimals;
|
|
2487
|
+
const toAmount = (Number(quote.outputAmount) / outputDivisor).toFixed(outputDecimals === 6 ? 6 : 8);
|
|
2488
|
+
const inputAmount = parseFloat(input.amount);
|
|
2489
|
+
const outputAmount = parseFloat(toAmount);
|
|
2490
|
+
const exchangeRate = inputAmount > 0 ? (outputAmount / inputAmount).toFixed(6) : "0";
|
|
2491
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
2492
|
+
const quoteId = createQuote("swap", {
|
|
2493
|
+
fromToken: input.fromToken,
|
|
2494
|
+
toToken: input.toToken,
|
|
2495
|
+
fromAmount: input.amount,
|
|
2496
|
+
toAmount,
|
|
2497
|
+
chain: input.chain,
|
|
2498
|
+
exchangeRate
|
|
2499
|
+
});
|
|
2500
|
+
return {
|
|
2501
|
+
quoteId,
|
|
2502
|
+
fromToken: input.fromToken,
|
|
2503
|
+
toToken: input.toToken,
|
|
2504
|
+
fromAmount: input.amount,
|
|
2505
|
+
toAmount,
|
|
2506
|
+
exchangeRate,
|
|
2507
|
+
fee: "0.3%",
|
|
2508
|
+
priceImpact: "< 0.1%",
|
|
2509
|
+
expiresAt,
|
|
2510
|
+
chain: input.chain
|
|
2511
|
+
};
|
|
2512
|
+
}
|
|
2513
|
+
function executeWdkQuoteSwapDemo(input) {
|
|
2514
|
+
const inputAmount = parseFloat(input.amount);
|
|
2515
|
+
const toAmount = (inputAmount * 0.997).toFixed(6);
|
|
2516
|
+
const exchangeRate = 0.997.toFixed(6);
|
|
2517
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
2518
|
+
const quoteId = createQuote("swap", {
|
|
2519
|
+
fromToken: input.fromToken,
|
|
2520
|
+
toToken: input.toToken,
|
|
2521
|
+
fromAmount: input.amount,
|
|
2522
|
+
toAmount,
|
|
2523
|
+
chain: input.chain,
|
|
2524
|
+
exchangeRate
|
|
2525
|
+
});
|
|
2526
|
+
return {
|
|
2527
|
+
quoteId,
|
|
2528
|
+
fromToken: input.fromToken,
|
|
2529
|
+
toToken: input.toToken,
|
|
2530
|
+
fromAmount: input.amount,
|
|
2531
|
+
toAmount,
|
|
2532
|
+
exchangeRate,
|
|
2533
|
+
fee: "0.3%",
|
|
2534
|
+
priceImpact: "< 0.1%",
|
|
2535
|
+
expiresAt,
|
|
2536
|
+
chain: input.chain
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2539
|
+
function formatSwapQuoteResult(result) {
|
|
2540
|
+
return [
|
|
2541
|
+
"## Swap Quote",
|
|
2542
|
+
"",
|
|
2543
|
+
`- **Quote ID:** \`${result.quoteId}\``,
|
|
2544
|
+
`- **From:** ${result.fromAmount} ${result.fromToken}`,
|
|
2545
|
+
`- **To:** ${result.toAmount} ${result.toToken}`,
|
|
2546
|
+
`- **Exchange Rate:** ${result.exchangeRate}`,
|
|
2547
|
+
`- **Fee:** ${result.fee}`,
|
|
2548
|
+
`- **Price Impact:** ${result.priceImpact}`,
|
|
2549
|
+
`- **Chain:** ${result.chain}`,
|
|
2550
|
+
`- **Expires:** ${result.expiresAt}`,
|
|
2551
|
+
"",
|
|
2552
|
+
"_Call `wdk/executeSwap` with the quoteId to execute this swap._"
|
|
2553
|
+
].join("\n");
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
// src/tools/wdkExecuteSwap.ts
|
|
2557
|
+
var import_zod24 = require("zod");
|
|
2558
|
+
var import_viem14 = require("viem");
|
|
2559
|
+
var wdkExecuteSwapInputSchema = import_zod24.z.object({
|
|
2560
|
+
quoteId: import_zod24.z.string().uuid().describe("Quote ID from wdk/quoteSwap"),
|
|
2561
|
+
confirmed: import_zod24.z.boolean().optional().describe("Set to true to confirm and execute this swap")
|
|
2562
|
+
});
|
|
2563
|
+
async function executeWdkExecuteSwap(input, wdk) {
|
|
2564
|
+
const quote = getQuote(input.quoteId);
|
|
2565
|
+
if (!quote) {
|
|
2566
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
2567
|
+
}
|
|
2568
|
+
if (quote.type !== "swap") {
|
|
2569
|
+
throw new Error("Invalid quote type. Expected a swap quote.");
|
|
2570
|
+
}
|
|
2571
|
+
const { fromToken, toToken, fromAmount, toAmount, chain } = quote.data;
|
|
2572
|
+
if (!input.confirmed) {
|
|
2573
|
+
return {
|
|
2574
|
+
needsConfirmation: true,
|
|
2575
|
+
summary: `Swap ${fromAmount} ${fromToken} to ${toAmount} ${toToken} on ${chain}`,
|
|
2576
|
+
details: { fromToken, toToken, fromAmount, toAmount, chain, quoteId: input.quoteId }
|
|
2577
|
+
};
|
|
2578
|
+
}
|
|
2579
|
+
const decimals = ["USDC", "USDT", "USDT0"].includes(fromToken.toUpperCase()) ? 6 : 18;
|
|
2580
|
+
const amountBigInt = (0, import_viem14.parseUnits)(fromAmount, decimals);
|
|
2581
|
+
const result = await wdk.swapAndPay({
|
|
2582
|
+
chain,
|
|
2583
|
+
fromToken,
|
|
2584
|
+
amount: amountBigInt
|
|
2585
|
+
});
|
|
2586
|
+
deleteQuote(input.quoteId);
|
|
2587
|
+
return {
|
|
2588
|
+
fromAmount,
|
|
2589
|
+
fromToken,
|
|
2590
|
+
toAmount,
|
|
2591
|
+
toToken,
|
|
2592
|
+
chain,
|
|
2593
|
+
txHash: result?.txHash ?? "0x"
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
function executeWdkExecuteSwapDemo(input) {
|
|
2597
|
+
const quote = getQuote(input.quoteId);
|
|
2598
|
+
if (!quote) {
|
|
2599
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
2600
|
+
}
|
|
2601
|
+
if (quote.type !== "swap") {
|
|
2602
|
+
throw new Error("Invalid quote type. Expected a swap quote.");
|
|
2603
|
+
}
|
|
2604
|
+
const { fromToken, toToken, fromAmount, toAmount, chain } = quote.data;
|
|
2605
|
+
if (!input.confirmed) {
|
|
2606
|
+
return {
|
|
2607
|
+
needsConfirmation: true,
|
|
2608
|
+
summary: `Swap ${fromAmount} ${fromToken} to ${toAmount} ${toToken} on ${chain}`,
|
|
2609
|
+
details: { fromToken, toToken, fromAmount, toAmount, chain, quoteId: input.quoteId }
|
|
2610
|
+
};
|
|
2611
|
+
}
|
|
2612
|
+
deleteQuote(input.quoteId);
|
|
2613
|
+
return {
|
|
2614
|
+
fromAmount,
|
|
2615
|
+
fromToken,
|
|
2616
|
+
toAmount,
|
|
2617
|
+
toToken,
|
|
2618
|
+
chain,
|
|
2619
|
+
txHash: "0xdemo" + Math.random().toString(16).slice(2, 10)
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
function formatExecuteSwapResult(result) {
|
|
2623
|
+
return [
|
|
2624
|
+
"## Swap Executed",
|
|
2625
|
+
"",
|
|
2626
|
+
`- **From:** ${result.fromAmount} ${result.fromToken}`,
|
|
2627
|
+
`- **To:** ${result.toAmount} ${result.toToken}`,
|
|
2628
|
+
`- **Chain:** ${result.chain}`,
|
|
2629
|
+
`- **Tx Hash:** \`${result.txHash}\``
|
|
2630
|
+
].join("\n");
|
|
2631
|
+
}
|
|
2632
|
+
|
|
2633
|
+
// src/tools/quoteBridge.ts
|
|
2634
|
+
var import_zod25 = require("zod");
|
|
2635
|
+
var quoteBridgeInputSchema = import_zod25.z.object({
|
|
2636
|
+
fromChain: import_zod25.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Source chain to bridge from"),
|
|
2637
|
+
toChain: import_zod25.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Destination chain to bridge to"),
|
|
2638
|
+
amount: import_zod25.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"),
|
|
2639
|
+
recipient: import_zod25.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain")
|
|
2640
|
+
});
|
|
2641
|
+
async function executeQuoteBridge(input, rpcUrls) {
|
|
2642
|
+
const feeResult = await executeGetBridgeFee(input, rpcUrls);
|
|
2643
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
2644
|
+
const quoteId = createQuote("bridge", {
|
|
2645
|
+
fromChain: input.fromChain,
|
|
2646
|
+
toChain: input.toChain,
|
|
2647
|
+
amount: input.amount,
|
|
2648
|
+
recipient: input.recipient,
|
|
2649
|
+
nativeFee: feeResult.nativeFee,
|
|
2650
|
+
nativeFeeFormatted: feeResult.nativeFeeFormatted,
|
|
2651
|
+
estimatedTime: feeResult.estimatedTime
|
|
2652
|
+
});
|
|
2653
|
+
return {
|
|
2654
|
+
quoteId,
|
|
2655
|
+
fromChain: input.fromChain,
|
|
2656
|
+
toChain: input.toChain,
|
|
2657
|
+
amount: input.amount,
|
|
2658
|
+
recipient: input.recipient,
|
|
2659
|
+
nativeFee: feeResult.nativeFee,
|
|
2660
|
+
nativeFeeFormatted: feeResult.nativeFeeFormatted,
|
|
2661
|
+
estimatedTime: feeResult.estimatedTime,
|
|
2662
|
+
expiresAt
|
|
2663
|
+
};
|
|
2664
|
+
}
|
|
2665
|
+
function executeQuoteBridgeDemo(input) {
|
|
2666
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
2667
|
+
const estimatedTime = input.toChain === "ethereum" ? 900 : 300;
|
|
2668
|
+
const quoteId = createQuote("bridge", {
|
|
2669
|
+
fromChain: input.fromChain,
|
|
2670
|
+
toChain: input.toChain,
|
|
2671
|
+
amount: input.amount,
|
|
2672
|
+
recipient: input.recipient,
|
|
2673
|
+
nativeFee: "1000000000000000",
|
|
2674
|
+
nativeFeeFormatted: "0.001 ETH",
|
|
2675
|
+
estimatedTime
|
|
2676
|
+
});
|
|
2677
|
+
return {
|
|
2678
|
+
quoteId,
|
|
2679
|
+
fromChain: input.fromChain,
|
|
2680
|
+
toChain: input.toChain,
|
|
2681
|
+
amount: input.amount,
|
|
2682
|
+
recipient: input.recipient,
|
|
2683
|
+
nativeFee: "1000000000000000",
|
|
2684
|
+
nativeFeeFormatted: "0.001 ETH",
|
|
2685
|
+
estimatedTime,
|
|
2686
|
+
expiresAt
|
|
2687
|
+
};
|
|
2688
|
+
}
|
|
2689
|
+
function formatBridgeQuoteResult(result) {
|
|
2690
|
+
const minutes = Math.ceil(result.estimatedTime / 60);
|
|
2691
|
+
return [
|
|
2692
|
+
"## Bridge Quote",
|
|
2693
|
+
"",
|
|
2694
|
+
`- **Quote ID:** \`${result.quoteId}\``,
|
|
2695
|
+
`- **Route:** ${result.fromChain} -> ${result.toChain}`,
|
|
2696
|
+
`- **Amount:** ${result.amount} USDT0`,
|
|
2697
|
+
`- **Recipient:** \`${result.recipient}\``,
|
|
2698
|
+
`- **Fee:** ${result.nativeFeeFormatted}`,
|
|
2699
|
+
`- **Estimated Time:** ~${minutes} minutes`,
|
|
2700
|
+
`- **Expires:** ${result.expiresAt}`,
|
|
2701
|
+
"",
|
|
2702
|
+
"_Call `t402/executeBridge` with the quoteId to execute this bridge._"
|
|
2703
|
+
].join("\n");
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
// src/tools/executeBridgeFromQuote.ts
|
|
2707
|
+
var import_zod26 = require("zod");
|
|
2708
|
+
var executeBridgeFromQuoteInputSchema = import_zod26.z.object({
|
|
2709
|
+
quoteId: import_zod26.z.string().uuid().describe("Quote ID from t402/quoteBridge"),
|
|
2710
|
+
confirmed: import_zod26.z.boolean().optional().describe("Set to true to confirm and execute this bridge")
|
|
2711
|
+
});
|
|
2712
|
+
async function executeExecuteBridgeFromQuote(input, options) {
|
|
2713
|
+
const quote = getQuote(input.quoteId);
|
|
2714
|
+
if (!quote) {
|
|
2715
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
2716
|
+
}
|
|
2717
|
+
if (quote.type !== "bridge") {
|
|
2718
|
+
throw new Error("Invalid quote type. Expected a bridge quote.");
|
|
2719
|
+
}
|
|
2720
|
+
const { fromChain, toChain, amount, recipient } = quote.data;
|
|
2721
|
+
if (!input.confirmed) {
|
|
2722
|
+
return {
|
|
2723
|
+
needsConfirmation: true,
|
|
2724
|
+
summary: `Bridge ${amount} USDT0 from ${fromChain} to ${toChain}`,
|
|
2725
|
+
details: { fromChain, toChain, amount, recipient, quoteId: input.quoteId }
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
const result = await executeBridge(
|
|
2729
|
+
{ fromChain, toChain, amount, recipient, confirmed: true },
|
|
2730
|
+
options
|
|
2731
|
+
);
|
|
2732
|
+
if ("needsConfirmation" in result) {
|
|
2733
|
+
return result;
|
|
2734
|
+
}
|
|
2735
|
+
deleteQuote(input.quoteId);
|
|
2736
|
+
return result;
|
|
2737
|
+
}
|
|
2738
|
+
function executeExecuteBridgeFromQuoteDemo(input) {
|
|
2739
|
+
const quote = getQuote(input.quoteId);
|
|
2740
|
+
if (!quote) {
|
|
2741
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
2742
|
+
}
|
|
2743
|
+
if (quote.type !== "bridge") {
|
|
2744
|
+
throw new Error("Invalid quote type. Expected a bridge quote.");
|
|
2745
|
+
}
|
|
2746
|
+
const { fromChain, toChain, amount, recipient } = quote.data;
|
|
2747
|
+
if (!input.confirmed) {
|
|
2748
|
+
return {
|
|
2749
|
+
needsConfirmation: true,
|
|
2750
|
+
summary: `Bridge ${amount} USDT0 from ${fromChain} to ${toChain}`,
|
|
2751
|
+
details: { fromChain, toChain, amount, recipient, quoteId: input.quoteId }
|
|
2752
|
+
};
|
|
2753
|
+
}
|
|
2754
|
+
deleteQuote(input.quoteId);
|
|
2755
|
+
const fakeTxHash = `0x${"a".repeat(64)}`;
|
|
2756
|
+
const fakeGuid = `0x${"b".repeat(64)}`;
|
|
2757
|
+
return {
|
|
2758
|
+
txHash: fakeTxHash,
|
|
2759
|
+
messageGuid: fakeGuid,
|
|
2760
|
+
amount,
|
|
2761
|
+
fromChain,
|
|
2762
|
+
toChain,
|
|
2763
|
+
estimatedTime: quote.data.estimatedTime ?? 300,
|
|
2764
|
+
trackingUrl: `https://layerzeroscan.com/tx/${fakeGuid}`
|
|
2765
|
+
};
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
// src/tools/unified.ts
|
|
2769
|
+
var import_zod27 = require("zod");
|
|
2770
|
+
var smartPayInputSchema = import_zod27.z.object({
|
|
2771
|
+
url: import_zod27.z.string().url().describe("URL of the 402-protected resource"),
|
|
2772
|
+
maxBridgeFee: import_zod27.z.string().regex(/^\d+(\.\d+)?$/).optional().describe("Maximum acceptable bridge fee in native token (optional)"),
|
|
2773
|
+
preferredNetwork: import_zod27.z.string().optional().describe("Preferred network for payment (optional)"),
|
|
2774
|
+
confirmed: import_zod27.z.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
2775
|
+
});
|
|
2776
|
+
var paymentPlanInputSchema = import_zod27.z.object({
|
|
2777
|
+
paymentRequired: import_zod27.z.object({
|
|
2778
|
+
scheme: import_zod27.z.string().optional(),
|
|
2779
|
+
network: import_zod27.z.string().optional(),
|
|
2780
|
+
maxAmountRequired: import_zod27.z.string().optional(),
|
|
2781
|
+
resource: import_zod27.z.string().optional(),
|
|
2782
|
+
description: import_zod27.z.string().optional(),
|
|
2783
|
+
payTo: import_zod27.z.string().optional(),
|
|
2784
|
+
maxDeadline: import_zod27.z.number().optional()
|
|
2785
|
+
}).passthrough().describe("The 402 PaymentRequired response")
|
|
2786
|
+
});
|
|
2787
|
+
var UNIFIED_TOOL_DEFINITIONS = {
|
|
2788
|
+
"t402/smartPay": {
|
|
2789
|
+
name: "t402/smartPay",
|
|
2790
|
+
description: "Intelligent payment that automatically checks balance, bridges if needed, and pays. Handles the entire payment flow for 402-protected resources.",
|
|
2791
|
+
inputSchema: {
|
|
2792
|
+
type: "object",
|
|
2793
|
+
properties: {
|
|
2794
|
+
url: { type: "string", description: "URL of the 402-protected resource" },
|
|
2795
|
+
maxBridgeFee: {
|
|
2796
|
+
type: "string",
|
|
2797
|
+
description: "Maximum acceptable bridge fee in native token (optional)"
|
|
2798
|
+
},
|
|
2799
|
+
preferredNetwork: {
|
|
2800
|
+
type: "string",
|
|
2801
|
+
description: "Preferred network for payment (optional)"
|
|
2802
|
+
},
|
|
2803
|
+
confirmed: {
|
|
2804
|
+
type: "boolean",
|
|
2805
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2806
|
+
}
|
|
2807
|
+
},
|
|
2808
|
+
required: ["url"]
|
|
2809
|
+
}
|
|
2810
|
+
},
|
|
2811
|
+
"t402/paymentPlan": {
|
|
2812
|
+
name: "t402/paymentPlan",
|
|
2813
|
+
description: "Analyze a 402 response and create an optimal payment plan considering balances across all chains. Returns recommended network, bridge requirements, and balance overview.",
|
|
2814
|
+
inputSchema: {
|
|
2815
|
+
type: "object",
|
|
2816
|
+
properties: {
|
|
2817
|
+
paymentRequired: {
|
|
2818
|
+
type: "object",
|
|
2819
|
+
description: "The 402 PaymentRequired response"
|
|
2820
|
+
}
|
|
2821
|
+
},
|
|
2822
|
+
required: ["paymentRequired"]
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
};
|
|
2826
|
+
async function executeSmartPay(input, wdk) {
|
|
2827
|
+
if (!input.confirmed) {
|
|
2828
|
+
return {
|
|
2829
|
+
needsConfirmation: true,
|
|
2830
|
+
summary: `Smart-pay for ${input.url}${input.preferredNetwork ? ` on ${input.preferredNetwork}` : ""}`,
|
|
2831
|
+
details: {
|
|
2832
|
+
url: input.url,
|
|
2833
|
+
...input.maxBridgeFee ? { maxBridgeFee: input.maxBridgeFee } : {},
|
|
2834
|
+
...input.preferredNetwork ? { preferredNetwork: input.preferredNetwork } : {}
|
|
2835
|
+
}
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
const steps = [];
|
|
2839
|
+
const chains10 = input.preferredNetwork ? [input.preferredNetwork] : ["ethereum", "arbitrum", "base"];
|
|
2840
|
+
steps.push({
|
|
2841
|
+
action: "check_balance",
|
|
2842
|
+
status: "success",
|
|
2843
|
+
detail: `Checking balances on ${chains10.join(", ")}`
|
|
2844
|
+
});
|
|
2845
|
+
const { T402Protocol } = await import("@t402/wdk-protocol");
|
|
2846
|
+
const protocol = await T402Protocol.create(wdk, { chains: chains10 });
|
|
2847
|
+
steps.push({
|
|
2848
|
+
action: "fetch",
|
|
2849
|
+
status: "success",
|
|
2850
|
+
detail: `Fetching ${input.url}`
|
|
2851
|
+
});
|
|
2852
|
+
const { response, receipt } = await protocol.fetch(input.url);
|
|
2853
|
+
if (receipt) {
|
|
2854
|
+
steps.push({
|
|
2855
|
+
action: "pay",
|
|
2856
|
+
status: "success",
|
|
2857
|
+
detail: `Payment made: ${receipt.amount} on ${receipt.network}`
|
|
2858
|
+
});
|
|
2859
|
+
}
|
|
2860
|
+
const contentType = response.headers.get("content-type") ?? void 0;
|
|
2861
|
+
let body = "";
|
|
2862
|
+
try {
|
|
2863
|
+
body = await response.text();
|
|
2864
|
+
if (body.length > 1e4) {
|
|
2865
|
+
body = body.slice(0, 1e4) + "\n... (truncated)";
|
|
2866
|
+
}
|
|
2867
|
+
} catch {
|
|
2868
|
+
body = "[Could not read response body]";
|
|
2869
|
+
}
|
|
2870
|
+
return {
|
|
2871
|
+
success: response.ok,
|
|
2872
|
+
statusCode: response.status,
|
|
2873
|
+
body,
|
|
2874
|
+
contentType,
|
|
2875
|
+
steps,
|
|
2876
|
+
payment: receipt ? {
|
|
2877
|
+
network: receipt.network,
|
|
2878
|
+
scheme: receipt.scheme,
|
|
2879
|
+
amount: receipt.amount,
|
|
2880
|
+
payTo: receipt.payTo
|
|
2881
|
+
} : void 0
|
|
2882
|
+
};
|
|
2883
|
+
}
|
|
2884
|
+
function executeSmartPayDemo(input) {
|
|
2885
|
+
if (!input.confirmed) {
|
|
2886
|
+
return {
|
|
2887
|
+
needsConfirmation: true,
|
|
2888
|
+
summary: `Smart-pay for ${input.url}${input.preferredNetwork ? ` on ${input.preferredNetwork}` : ""}`,
|
|
2889
|
+
details: {
|
|
2890
|
+
url: input.url,
|
|
2891
|
+
...input.maxBridgeFee ? { maxBridgeFee: input.maxBridgeFee } : {},
|
|
2892
|
+
...input.preferredNetwork ? { preferredNetwork: input.preferredNetwork } : {}
|
|
2893
|
+
}
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
const network = input.preferredNetwork ?? "arbitrum";
|
|
2897
|
+
return {
|
|
2898
|
+
success: true,
|
|
2899
|
+
statusCode: 200,
|
|
2900
|
+
body: `[Demo] Premium content from ${input.url}
|
|
2901
|
+
|
|
2902
|
+
This is simulated content returned after smart payment.`,
|
|
2903
|
+
contentType: "text/plain",
|
|
2904
|
+
steps: [
|
|
2905
|
+
{ action: "check_balance", status: "success", detail: `Checked balances on ${network}` },
|
|
2906
|
+
{ action: "check_price", status: "success", detail: "Resource costs 1.00 USDT0" },
|
|
2907
|
+
{ action: "pay", status: "success", detail: `Paid 1000000 USDT0 on eip155:42161` },
|
|
2908
|
+
{ action: "fetch", status: "success", detail: `Fetched ${input.url}` }
|
|
2909
|
+
],
|
|
2910
|
+
payment: {
|
|
2911
|
+
network: "eip155:42161",
|
|
2912
|
+
scheme: "exact",
|
|
2913
|
+
amount: "1000000",
|
|
2914
|
+
payTo: "0xC88f67e776f16DcFBf42e6bDda1B82604448899B"
|
|
2915
|
+
}
|
|
2916
|
+
};
|
|
2917
|
+
}
|
|
2918
|
+
async function executePaymentPlan(input, wdk) {
|
|
2919
|
+
const targetNetwork = input.paymentRequired.network;
|
|
2920
|
+
const requiredAmount = input.paymentRequired.maxAmountRequired;
|
|
2921
|
+
const aggregated = await wdk.getAggregatedBalances();
|
|
2922
|
+
const balances = aggregated.chains.map((chain) => {
|
|
2923
|
+
const usdt0 = chain.tokens.find((t) => t.symbol === "USDT0");
|
|
2924
|
+
const usdc = chain.tokens.find((t) => t.symbol === "USDC");
|
|
2925
|
+
return {
|
|
2926
|
+
chain: chain.chain,
|
|
2927
|
+
usdt0: usdt0?.formatted ?? "0",
|
|
2928
|
+
usdc: usdc?.formatted ?? "0"
|
|
2929
|
+
};
|
|
2930
|
+
});
|
|
2931
|
+
const requiredBigint = requiredAmount ? BigInt(requiredAmount) : 0n;
|
|
2932
|
+
const bestChain = await wdk.findBestChainForPayment(requiredBigint);
|
|
2933
|
+
if (bestChain) {
|
|
2934
|
+
const needsBridge = targetNetwork ? !bestChain.chain.includes(targetNetwork) : false;
|
|
2935
|
+
return {
|
|
2936
|
+
viable: true,
|
|
2937
|
+
recommendedNetwork: bestChain.chain,
|
|
2938
|
+
availableBalance: bestChain.balance.toString(),
|
|
2939
|
+
bridgeRequired: needsBridge,
|
|
2940
|
+
bridgeDetails: needsBridge ? {
|
|
2941
|
+
fromChain: bestChain.chain,
|
|
2942
|
+
toChain: targetNetwork ?? bestChain.chain,
|
|
2943
|
+
amount: requiredAmount ?? "0",
|
|
2944
|
+
estimatedFee: "0.001"
|
|
2945
|
+
} : void 0,
|
|
2946
|
+
balances
|
|
2947
|
+
};
|
|
2948
|
+
}
|
|
2949
|
+
return {
|
|
2950
|
+
viable: false,
|
|
2951
|
+
bridgeRequired: false,
|
|
2952
|
+
balances,
|
|
2953
|
+
reason: "Insufficient balance across all chains"
|
|
2954
|
+
};
|
|
2955
|
+
}
|
|
2956
|
+
function executePaymentPlanDemo(_input) {
|
|
2957
|
+
return {
|
|
2958
|
+
viable: true,
|
|
2959
|
+
recommendedNetwork: "arbitrum",
|
|
2960
|
+
availableBalance: "500000000",
|
|
2961
|
+
bridgeRequired: false,
|
|
2962
|
+
balances: [
|
|
2054
2963
|
{ chain: "ethereum", usdt0: "100.00", usdc: "250.00" },
|
|
2055
2964
|
{ chain: "arbitrum", usdt0: "500.00", usdc: "0" },
|
|
2056
2965
|
{ chain: "base", usdt0: "50.00", usdc: "100.00" }
|
|
@@ -2232,49 +3141,225 @@ var TOOL_DEFINITIONS = {
|
|
|
2232
3141
|
"berachain",
|
|
2233
3142
|
"unichain"
|
|
2234
3143
|
],
|
|
2235
|
-
description: "Network to execute payment on"
|
|
3144
|
+
description: "Network to execute payment on"
|
|
3145
|
+
},
|
|
3146
|
+
memo: {
|
|
3147
|
+
type: "string",
|
|
3148
|
+
description: "Optional memo/reference for the payment"
|
|
3149
|
+
},
|
|
3150
|
+
confirmed: {
|
|
3151
|
+
type: "boolean",
|
|
3152
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3153
|
+
}
|
|
3154
|
+
},
|
|
3155
|
+
required: ["to", "amount", "token", "network"]
|
|
3156
|
+
}
|
|
3157
|
+
},
|
|
3158
|
+
"t402/payGasless": {
|
|
3159
|
+
name: "t402/payGasless",
|
|
3160
|
+
description: "Execute a gasless stablecoin payment using ERC-4337 account abstraction. Gas fees are sponsored by a paymaster, so no ETH is needed for the transaction. Supported on select networks.",
|
|
3161
|
+
inputSchema: {
|
|
3162
|
+
type: "object",
|
|
3163
|
+
properties: {
|
|
3164
|
+
to: {
|
|
3165
|
+
type: "string",
|
|
3166
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
3167
|
+
description: "Recipient address"
|
|
3168
|
+
},
|
|
3169
|
+
amount: {
|
|
3170
|
+
type: "string",
|
|
3171
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3172
|
+
description: "Amount to pay (e.g., '10.50' for 10.50 USDC)"
|
|
3173
|
+
},
|
|
3174
|
+
token: {
|
|
3175
|
+
type: "string",
|
|
3176
|
+
enum: ["USDC", "USDT", "USDT0"],
|
|
3177
|
+
description: "Token to use for payment"
|
|
3178
|
+
},
|
|
3179
|
+
network: {
|
|
3180
|
+
type: "string",
|
|
3181
|
+
enum: ["ethereum", "base", "arbitrum", "optimism", "polygon", "avalanche"],
|
|
3182
|
+
description: "Network to execute gasless payment on (must support ERC-4337)"
|
|
3183
|
+
},
|
|
3184
|
+
confirmed: {
|
|
3185
|
+
type: "boolean",
|
|
3186
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3187
|
+
}
|
|
3188
|
+
},
|
|
3189
|
+
required: ["to", "amount", "token", "network"]
|
|
3190
|
+
}
|
|
3191
|
+
},
|
|
3192
|
+
"t402/getBridgeFee": {
|
|
3193
|
+
name: "t402/getBridgeFee",
|
|
3194
|
+
description: "Get the fee quote for bridging USDT0 between chains using LayerZero OFT. Returns the native token fee required and estimated delivery time. Supported chains: ethereum, arbitrum, ink, berachain, unichain.",
|
|
3195
|
+
inputSchema: {
|
|
3196
|
+
type: "object",
|
|
3197
|
+
properties: {
|
|
3198
|
+
fromChain: {
|
|
3199
|
+
type: "string",
|
|
3200
|
+
enum: ["ethereum", "arbitrum", "ink", "berachain", "unichain"],
|
|
3201
|
+
description: "Source chain to bridge from"
|
|
3202
|
+
},
|
|
3203
|
+
toChain: {
|
|
3204
|
+
type: "string",
|
|
3205
|
+
enum: ["ethereum", "arbitrum", "ink", "berachain", "unichain"],
|
|
3206
|
+
description: "Destination chain to bridge to"
|
|
3207
|
+
},
|
|
3208
|
+
amount: {
|
|
3209
|
+
type: "string",
|
|
3210
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3211
|
+
description: "Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"
|
|
3212
|
+
},
|
|
3213
|
+
recipient: {
|
|
3214
|
+
type: "string",
|
|
3215
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
3216
|
+
description: "Recipient address on destination chain"
|
|
3217
|
+
}
|
|
3218
|
+
},
|
|
3219
|
+
required: ["fromChain", "toChain", "amount", "recipient"]
|
|
3220
|
+
}
|
|
3221
|
+
},
|
|
3222
|
+
"t402/bridge": {
|
|
3223
|
+
name: "t402/bridge",
|
|
3224
|
+
description: "Bridge USDT0 between chains using LayerZero OFT standard. Executes a cross-chain transfer and returns the LayerZero message GUID for tracking. Supported chains: ethereum, arbitrum, ink, berachain, unichain.",
|
|
3225
|
+
inputSchema: {
|
|
3226
|
+
type: "object",
|
|
3227
|
+
properties: {
|
|
3228
|
+
fromChain: {
|
|
3229
|
+
type: "string",
|
|
3230
|
+
enum: ["ethereum", "arbitrum", "ink", "berachain", "unichain"],
|
|
3231
|
+
description: "Source chain to bridge from"
|
|
3232
|
+
},
|
|
3233
|
+
toChain: {
|
|
3234
|
+
type: "string",
|
|
3235
|
+
enum: ["ethereum", "arbitrum", "ink", "berachain", "unichain"],
|
|
3236
|
+
description: "Destination chain to bridge to"
|
|
3237
|
+
},
|
|
3238
|
+
amount: {
|
|
3239
|
+
type: "string",
|
|
3240
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3241
|
+
description: "Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"
|
|
3242
|
+
},
|
|
3243
|
+
recipient: {
|
|
3244
|
+
type: "string",
|
|
3245
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
3246
|
+
description: "Recipient address on destination chain"
|
|
3247
|
+
},
|
|
3248
|
+
confirmed: {
|
|
3249
|
+
type: "boolean",
|
|
3250
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3251
|
+
}
|
|
3252
|
+
},
|
|
3253
|
+
required: ["fromChain", "toChain", "amount", "recipient"]
|
|
3254
|
+
}
|
|
3255
|
+
},
|
|
3256
|
+
"t402/getTokenPrice": {
|
|
3257
|
+
name: "t402/getTokenPrice",
|
|
3258
|
+
description: "Get current market prices for tokens (ETH, MATIC, AVAX, USDC, etc.) via CoinGecko. Cached for 5 minutes.",
|
|
3259
|
+
inputSchema: {
|
|
3260
|
+
type: "object",
|
|
3261
|
+
properties: {
|
|
3262
|
+
tokens: {
|
|
3263
|
+
type: "array",
|
|
3264
|
+
items: { type: "string" },
|
|
3265
|
+
description: 'Token symbols to get prices for (e.g., ["ETH", "MATIC", "USDC"])'
|
|
3266
|
+
},
|
|
3267
|
+
currency: {
|
|
3268
|
+
type: "string",
|
|
3269
|
+
description: 'Target currency (default: "usd")'
|
|
3270
|
+
}
|
|
3271
|
+
},
|
|
3272
|
+
required: ["tokens"]
|
|
3273
|
+
}
|
|
3274
|
+
},
|
|
3275
|
+
"t402/getGasPrice": {
|
|
3276
|
+
name: "t402/getGasPrice",
|
|
3277
|
+
description: "Get the current gas price on a specific blockchain network. Returns the price in gwei.",
|
|
3278
|
+
inputSchema: {
|
|
3279
|
+
type: "object",
|
|
3280
|
+
properties: {
|
|
3281
|
+
network: {
|
|
3282
|
+
type: "string",
|
|
3283
|
+
enum: [
|
|
3284
|
+
"ethereum",
|
|
3285
|
+
"base",
|
|
3286
|
+
"arbitrum",
|
|
3287
|
+
"optimism",
|
|
3288
|
+
"polygon",
|
|
3289
|
+
"avalanche",
|
|
3290
|
+
"ink",
|
|
3291
|
+
"berachain",
|
|
3292
|
+
"unichain"
|
|
3293
|
+
],
|
|
3294
|
+
description: "Blockchain network to check gas price on"
|
|
3295
|
+
}
|
|
3296
|
+
},
|
|
3297
|
+
required: ["network"]
|
|
3298
|
+
}
|
|
3299
|
+
},
|
|
3300
|
+
"t402/estimatePaymentFee": {
|
|
3301
|
+
name: "t402/estimatePaymentFee",
|
|
3302
|
+
description: "Estimate the gas cost (in native token and USD) for a stablecoin payment on a specific network.",
|
|
3303
|
+
inputSchema: {
|
|
3304
|
+
type: "object",
|
|
3305
|
+
properties: {
|
|
3306
|
+
network: {
|
|
3307
|
+
type: "string",
|
|
3308
|
+
enum: [
|
|
3309
|
+
"ethereum",
|
|
3310
|
+
"base",
|
|
3311
|
+
"arbitrum",
|
|
3312
|
+
"optimism",
|
|
3313
|
+
"polygon",
|
|
3314
|
+
"avalanche",
|
|
3315
|
+
"ink",
|
|
3316
|
+
"berachain",
|
|
3317
|
+
"unichain"
|
|
3318
|
+
],
|
|
3319
|
+
description: "Network to estimate fee on"
|
|
2236
3320
|
},
|
|
2237
|
-
|
|
3321
|
+
amount: {
|
|
2238
3322
|
type: "string",
|
|
2239
|
-
|
|
3323
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3324
|
+
description: "Payment amount (e.g., '100')"
|
|
3325
|
+
},
|
|
3326
|
+
token: {
|
|
3327
|
+
type: "string",
|
|
3328
|
+
enum: ["USDC", "USDT", "USDT0"],
|
|
3329
|
+
description: "Token to use for payment"
|
|
2240
3330
|
}
|
|
2241
3331
|
},
|
|
2242
|
-
required: ["
|
|
3332
|
+
required: ["network", "amount", "token"]
|
|
2243
3333
|
}
|
|
2244
3334
|
},
|
|
2245
|
-
"t402/
|
|
2246
|
-
name: "t402/
|
|
2247
|
-
description: "
|
|
3335
|
+
"t402/compareNetworkFees": {
|
|
3336
|
+
name: "t402/compareNetworkFees",
|
|
3337
|
+
description: "Compare payment fees across multiple networks for the same token. Returns a sorted table from cheapest to most expensive.",
|
|
2248
3338
|
inputSchema: {
|
|
2249
3339
|
type: "object",
|
|
2250
3340
|
properties: {
|
|
2251
|
-
to: {
|
|
2252
|
-
type: "string",
|
|
2253
|
-
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
2254
|
-
description: "Recipient address"
|
|
2255
|
-
},
|
|
2256
3341
|
amount: {
|
|
2257
3342
|
type: "string",
|
|
2258
3343
|
pattern: "^\\d+(\\.\\d+)?$",
|
|
2259
|
-
description: "
|
|
3344
|
+
description: "Payment amount (e.g., '100')"
|
|
2260
3345
|
},
|
|
2261
3346
|
token: {
|
|
2262
3347
|
type: "string",
|
|
2263
3348
|
enum: ["USDC", "USDT", "USDT0"],
|
|
2264
3349
|
description: "Token to use for payment"
|
|
2265
3350
|
},
|
|
2266
|
-
|
|
2267
|
-
type: "
|
|
2268
|
-
|
|
2269
|
-
description: "
|
|
3351
|
+
networks: {
|
|
3352
|
+
type: "array",
|
|
3353
|
+
items: { type: "string" },
|
|
3354
|
+
description: "Networks to compare. If not provided, compares all networks that support the token."
|
|
2270
3355
|
}
|
|
2271
3356
|
},
|
|
2272
|
-
required: ["
|
|
3357
|
+
required: ["amount", "token"]
|
|
2273
3358
|
}
|
|
2274
3359
|
},
|
|
2275
|
-
"t402/
|
|
2276
|
-
name: "t402/
|
|
2277
|
-
description: "Get
|
|
3360
|
+
"t402/quoteBridge": {
|
|
3361
|
+
name: "t402/quoteBridge",
|
|
3362
|
+
description: "Get a bridge fee quote with a quoteId for later execution. Like getBridgeFee but returns a reusable quoteId. Call t402/executeBridge with the quoteId to execute.",
|
|
2278
3363
|
inputSchema: {
|
|
2279
3364
|
type: "object",
|
|
2280
3365
|
properties: {
|
|
@@ -2302,34 +3387,147 @@ var TOOL_DEFINITIONS = {
|
|
|
2302
3387
|
required: ["fromChain", "toChain", "amount", "recipient"]
|
|
2303
3388
|
}
|
|
2304
3389
|
},
|
|
2305
|
-
"t402/
|
|
2306
|
-
name: "t402/
|
|
2307
|
-
description: "
|
|
3390
|
+
"t402/executeBridgeQuote": {
|
|
3391
|
+
name: "t402/executeBridgeQuote",
|
|
3392
|
+
description: "Execute a bridge using a quoteId from t402/quoteBridge. Requires confirmation.",
|
|
2308
3393
|
inputSchema: {
|
|
2309
3394
|
type: "object",
|
|
2310
3395
|
properties: {
|
|
2311
|
-
|
|
3396
|
+
quoteId: {
|
|
2312
3397
|
type: "string",
|
|
2313
|
-
|
|
2314
|
-
description: "Source chain to bridge from"
|
|
3398
|
+
description: "Quote ID from t402/quoteBridge"
|
|
2315
3399
|
},
|
|
2316
|
-
|
|
3400
|
+
confirmed: {
|
|
3401
|
+
type: "boolean",
|
|
3402
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3403
|
+
}
|
|
3404
|
+
},
|
|
3405
|
+
required: ["quoteId"]
|
|
3406
|
+
}
|
|
3407
|
+
},
|
|
3408
|
+
"t402/signMessage": {
|
|
3409
|
+
name: "t402/signMessage",
|
|
3410
|
+
description: "Sign a message using the configured wallet. Returns an EIP-191 personal signature. Requires a configured private key.",
|
|
3411
|
+
inputSchema: {
|
|
3412
|
+
type: "object",
|
|
3413
|
+
properties: {
|
|
3414
|
+
chain: {
|
|
2317
3415
|
type: "string",
|
|
2318
|
-
enum: [
|
|
2319
|
-
|
|
3416
|
+
enum: [
|
|
3417
|
+
"ethereum",
|
|
3418
|
+
"base",
|
|
3419
|
+
"arbitrum",
|
|
3420
|
+
"optimism",
|
|
3421
|
+
"polygon",
|
|
3422
|
+
"avalanche",
|
|
3423
|
+
"ink",
|
|
3424
|
+
"berachain",
|
|
3425
|
+
"unichain"
|
|
3426
|
+
],
|
|
3427
|
+
description: "Blockchain network context for signing"
|
|
2320
3428
|
},
|
|
2321
|
-
|
|
3429
|
+
message: {
|
|
2322
3430
|
type: "string",
|
|
2323
|
-
|
|
2324
|
-
|
|
3431
|
+
description: "Message to sign"
|
|
3432
|
+
}
|
|
3433
|
+
},
|
|
3434
|
+
required: ["chain", "message"]
|
|
3435
|
+
}
|
|
3436
|
+
},
|
|
3437
|
+
"t402/verifySignature": {
|
|
3438
|
+
name: "t402/verifySignature",
|
|
3439
|
+
description: "Verify an EIP-191 signed message. Checks whether a signature was produced by the claimed address. No wallet configuration needed \u2014 this is a read-only verification.",
|
|
3440
|
+
inputSchema: {
|
|
3441
|
+
type: "object",
|
|
3442
|
+
properties: {
|
|
3443
|
+
chain: {
|
|
3444
|
+
type: "string",
|
|
3445
|
+
enum: [
|
|
3446
|
+
"ethereum",
|
|
3447
|
+
"base",
|
|
3448
|
+
"arbitrum",
|
|
3449
|
+
"optimism",
|
|
3450
|
+
"polygon",
|
|
3451
|
+
"avalanche",
|
|
3452
|
+
"ink",
|
|
3453
|
+
"berachain",
|
|
3454
|
+
"unichain"
|
|
3455
|
+
],
|
|
3456
|
+
description: "Blockchain network context for verification"
|
|
2325
3457
|
},
|
|
2326
|
-
|
|
3458
|
+
message: {
|
|
3459
|
+
type: "string",
|
|
3460
|
+
description: "The original message that was signed"
|
|
3461
|
+
},
|
|
3462
|
+
signature: {
|
|
3463
|
+
type: "string",
|
|
3464
|
+
pattern: "^0x[a-fA-F0-9]+$",
|
|
3465
|
+
description: "The signature to verify (hex string)"
|
|
3466
|
+
},
|
|
3467
|
+
address: {
|
|
2327
3468
|
type: "string",
|
|
2328
3469
|
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
2329
|
-
description: "
|
|
3470
|
+
description: "The expected signer address"
|
|
2330
3471
|
}
|
|
2331
3472
|
},
|
|
2332
|
-
required: ["
|
|
3473
|
+
required: ["chain", "message", "signature", "address"]
|
|
3474
|
+
}
|
|
3475
|
+
},
|
|
3476
|
+
"t402/getTransferHistory": {
|
|
3477
|
+
name: "t402/getTransferHistory",
|
|
3478
|
+
description: "Get recent ERC-20 stablecoin transfer history for a wallet address. Queries on-chain Transfer events for USDC, USDT, and USDT0. Returns sent and received transfers sorted by most recent.",
|
|
3479
|
+
inputSchema: {
|
|
3480
|
+
type: "object",
|
|
3481
|
+
properties: {
|
|
3482
|
+
network: {
|
|
3483
|
+
type: "string",
|
|
3484
|
+
enum: [
|
|
3485
|
+
"ethereum",
|
|
3486
|
+
"base",
|
|
3487
|
+
"arbitrum",
|
|
3488
|
+
"optimism",
|
|
3489
|
+
"polygon",
|
|
3490
|
+
"avalanche",
|
|
3491
|
+
"ink",
|
|
3492
|
+
"berachain",
|
|
3493
|
+
"unichain"
|
|
3494
|
+
],
|
|
3495
|
+
description: "Blockchain network to query"
|
|
3496
|
+
},
|
|
3497
|
+
address: {
|
|
3498
|
+
type: "string",
|
|
3499
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
3500
|
+
description: "Wallet address to get transfer history for"
|
|
3501
|
+
},
|
|
3502
|
+
token: {
|
|
3503
|
+
type: "string",
|
|
3504
|
+
enum: ["USDC", "USDT", "USDT0"],
|
|
3505
|
+
description: "Filter by specific token. If not provided, queries all supported stablecoins."
|
|
3506
|
+
},
|
|
3507
|
+
limit: {
|
|
3508
|
+
type: "number",
|
|
3509
|
+
description: "Maximum number of transfers to return (default: 10, max: 100)"
|
|
3510
|
+
}
|
|
3511
|
+
},
|
|
3512
|
+
required: ["network", "address"]
|
|
3513
|
+
}
|
|
3514
|
+
},
|
|
3515
|
+
"t402/getHistoricalPrice": {
|
|
3516
|
+
name: "t402/getHistoricalPrice",
|
|
3517
|
+
description: "Get historical price data for a token over a specified period via CoinGecko. Returns price data points, high/low, and percentage change. Useful for trend analysis.",
|
|
3518
|
+
inputSchema: {
|
|
3519
|
+
type: "object",
|
|
3520
|
+
properties: {
|
|
3521
|
+
token: {
|
|
3522
|
+
type: "string",
|
|
3523
|
+
description: 'Token symbol (e.g., "ETH", "USDC", "USDT", "MATIC", "AVAX", "BTC", "SOL")'
|
|
3524
|
+
},
|
|
3525
|
+
days: {
|
|
3526
|
+
type: "number",
|
|
3527
|
+
description: "Number of days of history to retrieve (default: 7, max: 365)"
|
|
3528
|
+
}
|
|
3529
|
+
},
|
|
3530
|
+
required: ["token"]
|
|
2333
3531
|
}
|
|
2334
3532
|
}
|
|
2335
3533
|
};
|
|
@@ -2381,6 +3579,10 @@ var WDK_TOOL_DEFINITIONS = {
|
|
|
2381
3579
|
chain: {
|
|
2382
3580
|
type: "string",
|
|
2383
3581
|
description: 'Chain to execute transfer on (e.g., "ethereum", "arbitrum")'
|
|
3582
|
+
},
|
|
3583
|
+
confirmed: {
|
|
3584
|
+
type: "boolean",
|
|
3585
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2384
3586
|
}
|
|
2385
3587
|
},
|
|
2386
3588
|
required: ["to", "amount", "token", "chain"]
|
|
@@ -2408,6 +3610,10 @@ var WDK_TOOL_DEFINITIONS = {
|
|
|
2408
3610
|
chain: {
|
|
2409
3611
|
type: "string",
|
|
2410
3612
|
description: 'Chain to execute swap on (e.g., "ethereum", "arbitrum")'
|
|
3613
|
+
},
|
|
3614
|
+
confirmed: {
|
|
3615
|
+
type: "boolean",
|
|
3616
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2411
3617
|
}
|
|
2412
3618
|
},
|
|
2413
3619
|
required: ["fromToken", "toToken", "amount", "chain"]
|
|
@@ -2431,10 +3637,59 @@ var WDK_TOOL_DEFINITIONS = {
|
|
|
2431
3637
|
preferredChain: {
|
|
2432
3638
|
type: "string",
|
|
2433
3639
|
description: 'Preferred chain for payment (e.g., "arbitrum"). If not specified, uses first available.'
|
|
3640
|
+
},
|
|
3641
|
+
confirmed: {
|
|
3642
|
+
type: "boolean",
|
|
3643
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2434
3644
|
}
|
|
2435
3645
|
},
|
|
2436
3646
|
required: ["url"]
|
|
2437
3647
|
}
|
|
3648
|
+
},
|
|
3649
|
+
"wdk/quoteSwap": {
|
|
3650
|
+
name: "wdk/quoteSwap",
|
|
3651
|
+
description: "Get a swap quote with a quoteId for later execution. Returns exchange rate, fee, and price impact. Call wdk/executeSwap with the quoteId to execute.",
|
|
3652
|
+
inputSchema: {
|
|
3653
|
+
type: "object",
|
|
3654
|
+
properties: {
|
|
3655
|
+
fromToken: {
|
|
3656
|
+
type: "string",
|
|
3657
|
+
description: 'Token to swap from (e.g., "ETH", "USDC")'
|
|
3658
|
+
},
|
|
3659
|
+
toToken: {
|
|
3660
|
+
type: "string",
|
|
3661
|
+
description: 'Token to swap to (e.g., "USDT0", "USDC")'
|
|
3662
|
+
},
|
|
3663
|
+
amount: {
|
|
3664
|
+
type: "string",
|
|
3665
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3666
|
+
description: "Amount to swap (e.g., '1.0')"
|
|
3667
|
+
},
|
|
3668
|
+
chain: {
|
|
3669
|
+
type: "string",
|
|
3670
|
+
description: 'Chain to execute swap on (e.g., "ethereum", "arbitrum")'
|
|
3671
|
+
}
|
|
3672
|
+
},
|
|
3673
|
+
required: ["fromToken", "toToken", "amount", "chain"]
|
|
3674
|
+
}
|
|
3675
|
+
},
|
|
3676
|
+
"wdk/executeSwap": {
|
|
3677
|
+
name: "wdk/executeSwap",
|
|
3678
|
+
description: "Execute a swap using a quoteId from wdk/quoteSwap. Requires confirmation.",
|
|
3679
|
+
inputSchema: {
|
|
3680
|
+
type: "object",
|
|
3681
|
+
properties: {
|
|
3682
|
+
quoteId: {
|
|
3683
|
+
type: "string",
|
|
3684
|
+
description: "Quote ID from wdk/quoteSwap"
|
|
3685
|
+
},
|
|
3686
|
+
confirmed: {
|
|
3687
|
+
type: "boolean",
|
|
3688
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3689
|
+
}
|
|
3690
|
+
},
|
|
3691
|
+
required: ["quoteId"]
|
|
3692
|
+
}
|
|
2438
3693
|
}
|
|
2439
3694
|
};
|
|
2440
3695
|
var ERC8004_TOOL_DEFINITIONS = {
|
|
@@ -2553,6 +3808,19 @@ var T402McpServer = class {
|
|
|
2553
3808
|
console.error("Warning: Failed to initialize WDK. WDK tools will not be available.");
|
|
2554
3809
|
}
|
|
2555
3810
|
}
|
|
3811
|
+
/**
|
|
3812
|
+
* Clear sensitive data from memory.
|
|
3813
|
+
* Should be called on server shutdown to minimize key exposure window.
|
|
3814
|
+
*/
|
|
3815
|
+
cleanup() {
|
|
3816
|
+
if (this.config.privateKey) {
|
|
3817
|
+
this.config.privateKey = "";
|
|
3818
|
+
}
|
|
3819
|
+
if (this.config.seedPhrase) {
|
|
3820
|
+
this.config.seedPhrase = "";
|
|
3821
|
+
}
|
|
3822
|
+
this.wdk = null;
|
|
3823
|
+
}
|
|
2556
3824
|
/**
|
|
2557
3825
|
* Register TON bridge tools
|
|
2558
3826
|
*
|
|
@@ -2618,6 +3886,24 @@ var T402McpServer = class {
|
|
|
2618
3886
|
return await this.handleSmartPay(args);
|
|
2619
3887
|
case "t402/paymentPlan":
|
|
2620
3888
|
return await this.handlePaymentPlan(args);
|
|
3889
|
+
// Price and fee tools
|
|
3890
|
+
case "t402/getTokenPrice":
|
|
3891
|
+
return await this.handleGetTokenPrice(args);
|
|
3892
|
+
case "t402/getGasPrice":
|
|
3893
|
+
return await this.handleGetGasPrice(args);
|
|
3894
|
+
case "t402/estimatePaymentFee":
|
|
3895
|
+
return await this.handleEstimatePaymentFee(args);
|
|
3896
|
+
case "t402/compareNetworkFees":
|
|
3897
|
+
return await this.handleCompareNetworkFees(args);
|
|
3898
|
+
// Quote-based tools
|
|
3899
|
+
case "t402/quoteBridge":
|
|
3900
|
+
return await this.handleQuoteBridge(args);
|
|
3901
|
+
case "t402/executeBridgeQuote":
|
|
3902
|
+
return await this.handleExecuteBridgeQuote(args);
|
|
3903
|
+
case "wdk/quoteSwap":
|
|
3904
|
+
return await this.handleWdkQuoteSwap(args);
|
|
3905
|
+
case "wdk/executeSwap":
|
|
3906
|
+
return await this.handleWdkExecuteSwap(args);
|
|
2621
3907
|
// ERC-8004 tools
|
|
2622
3908
|
case "erc8004/resolveAgent":
|
|
2623
3909
|
return await this.handleErc8004ResolveAgent(args);
|
|
@@ -2679,6 +3965,28 @@ var T402McpServer = class {
|
|
|
2679
3965
|
]
|
|
2680
3966
|
};
|
|
2681
3967
|
}
|
|
3968
|
+
/**
|
|
3969
|
+
* Format a confirmation prompt for elicitation
|
|
3970
|
+
*/
|
|
3971
|
+
formatConfirmation(result) {
|
|
3972
|
+
const detailLines = Object.entries(result.details).map(([key, value]) => `- **${key}:** ${value}`).join("\n");
|
|
3973
|
+
return {
|
|
3974
|
+
content: [
|
|
3975
|
+
{
|
|
3976
|
+
type: "text",
|
|
3977
|
+
text: [
|
|
3978
|
+
"## Confirmation Required",
|
|
3979
|
+
"",
|
|
3980
|
+
result.summary,
|
|
3981
|
+
"",
|
|
3982
|
+
detailLines,
|
|
3983
|
+
"",
|
|
3984
|
+
"_Call this tool again with `confirmed: true` to execute._"
|
|
3985
|
+
].join("\n")
|
|
3986
|
+
}
|
|
3987
|
+
]
|
|
3988
|
+
};
|
|
3989
|
+
}
|
|
2682
3990
|
/**
|
|
2683
3991
|
* Handle t402/pay
|
|
2684
3992
|
*/
|
|
@@ -2694,6 +4002,9 @@ var T402McpServer = class {
|
|
|
2694
4002
|
rpcUrl: this.config.rpcUrls?.[input.network],
|
|
2695
4003
|
demoMode: this.config.demoMode
|
|
2696
4004
|
});
|
|
4005
|
+
if ("needsConfirmation" in result) {
|
|
4006
|
+
return this.formatConfirmation(result);
|
|
4007
|
+
}
|
|
2697
4008
|
return {
|
|
2698
4009
|
content: [
|
|
2699
4010
|
{
|
|
@@ -2730,6 +4041,9 @@ var T402McpServer = class {
|
|
|
2730
4041
|
rpcUrl: this.config.rpcUrls?.[input.network],
|
|
2731
4042
|
demoMode: this.config.demoMode
|
|
2732
4043
|
});
|
|
4044
|
+
if ("needsConfirmation" in result) {
|
|
4045
|
+
return this.formatConfirmation(result);
|
|
4046
|
+
}
|
|
2733
4047
|
return {
|
|
2734
4048
|
content: [
|
|
2735
4049
|
{
|
|
@@ -2769,6 +4083,9 @@ var T402McpServer = class {
|
|
|
2769
4083
|
rpcUrl: this.config.rpcUrls?.[input.fromChain],
|
|
2770
4084
|
demoMode: this.config.demoMode
|
|
2771
4085
|
});
|
|
4086
|
+
if ("needsConfirmation" in result) {
|
|
4087
|
+
return this.formatConfirmation(result);
|
|
4088
|
+
}
|
|
2772
4089
|
return {
|
|
2773
4090
|
content: [
|
|
2774
4091
|
{
|
|
@@ -2805,6 +4122,9 @@ var T402McpServer = class {
|
|
|
2805
4122
|
async handleWdkTransfer(args) {
|
|
2806
4123
|
const input = wdkTransferInputSchema.parse(args);
|
|
2807
4124
|
const result = this.config.demoMode || !this.wdk ? executeWdkTransferDemo(input) : await executeWdkTransfer(input, this.wdk);
|
|
4125
|
+
if ("needsConfirmation" in result) {
|
|
4126
|
+
return this.formatConfirmation(result);
|
|
4127
|
+
}
|
|
2808
4128
|
return {
|
|
2809
4129
|
content: [{ type: "text", text: formatWdkTransferResult(result) }]
|
|
2810
4130
|
};
|
|
@@ -2815,6 +4135,9 @@ var T402McpServer = class {
|
|
|
2815
4135
|
async handleWdkSwap(args) {
|
|
2816
4136
|
const input = wdkSwapInputSchema.parse(args);
|
|
2817
4137
|
const result = this.config.demoMode || !this.wdk ? executeWdkSwapDemo(input) : await executeWdkSwap(input, this.wdk);
|
|
4138
|
+
if ("needsConfirmation" in result) {
|
|
4139
|
+
return this.formatConfirmation(result);
|
|
4140
|
+
}
|
|
2818
4141
|
return {
|
|
2819
4142
|
content: [{ type: "text", text: formatWdkSwapResult(result) }]
|
|
2820
4143
|
};
|
|
@@ -2825,6 +4148,9 @@ var T402McpServer = class {
|
|
|
2825
4148
|
async handleAutoPay(args) {
|
|
2826
4149
|
const input = autoPayInputSchema.parse(args);
|
|
2827
4150
|
const result = this.config.demoMode || !this.wdk ? executeAutoPayDemo(input) : await executeAutoPay(input, this.wdk);
|
|
4151
|
+
if ("needsConfirmation" in result) {
|
|
4152
|
+
return this.formatConfirmation(result);
|
|
4153
|
+
}
|
|
2828
4154
|
return {
|
|
2829
4155
|
content: [{ type: "text", text: formatAutoPayResult(result) }]
|
|
2830
4156
|
};
|
|
@@ -2836,6 +4162,9 @@ var T402McpServer = class {
|
|
|
2836
4162
|
async handleSmartPay(args) {
|
|
2837
4163
|
const input = smartPayInputSchema.parse(args);
|
|
2838
4164
|
const result = this.config.demoMode || !this.wdk ? executeSmartPayDemo(input) : await executeSmartPay(input, this.wdk);
|
|
4165
|
+
if ("needsConfirmation" in result) {
|
|
4166
|
+
return this.formatConfirmation(result);
|
|
4167
|
+
}
|
|
2839
4168
|
return {
|
|
2840
4169
|
content: [{ type: "text", text: formatSmartPayResult(result) }]
|
|
2841
4170
|
};
|
|
@@ -2850,6 +4179,111 @@ var T402McpServer = class {
|
|
|
2850
4179
|
content: [{ type: "text", text: formatPaymentPlanResult(result) }]
|
|
2851
4180
|
};
|
|
2852
4181
|
}
|
|
4182
|
+
// ---- Price and Fee Tool Handlers ----
|
|
4183
|
+
/**
|
|
4184
|
+
* Handle t402/getTokenPrice
|
|
4185
|
+
*/
|
|
4186
|
+
async handleGetTokenPrice(args) {
|
|
4187
|
+
const input = getTokenPriceInputSchema.parse(args);
|
|
4188
|
+
const result = await executeGetTokenPrice(input, { demoMode: this.config.demoMode });
|
|
4189
|
+
return {
|
|
4190
|
+
content: [{ type: "text", text: formatTokenPriceResult(result) }]
|
|
4191
|
+
};
|
|
4192
|
+
}
|
|
4193
|
+
/**
|
|
4194
|
+
* Handle t402/getGasPrice
|
|
4195
|
+
*/
|
|
4196
|
+
async handleGetGasPrice(args) {
|
|
4197
|
+
const input = getGasPriceInputSchema.parse(args);
|
|
4198
|
+
const result = await executeGetGasPrice(input, {
|
|
4199
|
+
rpcUrl: this.config.rpcUrls?.[input.network],
|
|
4200
|
+
demoMode: this.config.demoMode
|
|
4201
|
+
});
|
|
4202
|
+
return {
|
|
4203
|
+
content: [{ type: "text", text: formatGasPriceResult(result) }]
|
|
4204
|
+
};
|
|
4205
|
+
}
|
|
4206
|
+
/**
|
|
4207
|
+
* Handle t402/estimatePaymentFee
|
|
4208
|
+
*/
|
|
4209
|
+
async handleEstimatePaymentFee(args) {
|
|
4210
|
+
const input = estimatePaymentFeeInputSchema.parse(args);
|
|
4211
|
+
const result = await executeEstimatePaymentFee(input, {
|
|
4212
|
+
rpcUrl: this.config.rpcUrls?.[input.network],
|
|
4213
|
+
demoMode: this.config.demoMode
|
|
4214
|
+
});
|
|
4215
|
+
return {
|
|
4216
|
+
content: [{ type: "text", text: formatPaymentFeeEstimate(result) }]
|
|
4217
|
+
};
|
|
4218
|
+
}
|
|
4219
|
+
/**
|
|
4220
|
+
* Handle t402/compareNetworkFees
|
|
4221
|
+
*/
|
|
4222
|
+
async handleCompareNetworkFees(args) {
|
|
4223
|
+
const input = compareNetworkFeesInputSchema.parse(args);
|
|
4224
|
+
const result = await executeCompareNetworkFees(input, {
|
|
4225
|
+
rpcUrls: this.config.rpcUrls,
|
|
4226
|
+
demoMode: this.config.demoMode
|
|
4227
|
+
});
|
|
4228
|
+
return {
|
|
4229
|
+
content: [{ type: "text", text: formatNetworkFeeComparison(result) }]
|
|
4230
|
+
};
|
|
4231
|
+
}
|
|
4232
|
+
// ---- Quote-based Tool Handlers ----
|
|
4233
|
+
/**
|
|
4234
|
+
* Handle t402/quoteBridge
|
|
4235
|
+
*/
|
|
4236
|
+
async handleQuoteBridge(args) {
|
|
4237
|
+
const input = quoteBridgeInputSchema.parse(args);
|
|
4238
|
+
const result = this.config.demoMode ? executeQuoteBridgeDemo(input) : await executeQuoteBridge(input, this.config.rpcUrls);
|
|
4239
|
+
return {
|
|
4240
|
+
content: [{ type: "text", text: formatBridgeQuoteResult(result) }]
|
|
4241
|
+
};
|
|
4242
|
+
}
|
|
4243
|
+
/**
|
|
4244
|
+
* Handle t402/executeBridgeQuote
|
|
4245
|
+
*/
|
|
4246
|
+
async handleExecuteBridgeQuote(args) {
|
|
4247
|
+
if (!this.config.privateKey && !this.config.demoMode) {
|
|
4248
|
+
throw new Error(
|
|
4249
|
+
"Private key not configured. Set T402_PRIVATE_KEY environment variable or enable demo mode."
|
|
4250
|
+
);
|
|
4251
|
+
}
|
|
4252
|
+
const input = executeBridgeFromQuoteInputSchema.parse(args);
|
|
4253
|
+
const result = this.config.demoMode ? executeExecuteBridgeFromQuoteDemo(input) : await executeExecuteBridgeFromQuote(input, {
|
|
4254
|
+
privateKey: this.config.privateKey || "0x",
|
|
4255
|
+
demoMode: this.config.demoMode
|
|
4256
|
+
});
|
|
4257
|
+
if ("needsConfirmation" in result) {
|
|
4258
|
+
return this.formatConfirmation(result);
|
|
4259
|
+
}
|
|
4260
|
+
return {
|
|
4261
|
+
content: [{ type: "text", text: formatBridgeResult(result) }]
|
|
4262
|
+
};
|
|
4263
|
+
}
|
|
4264
|
+
/**
|
|
4265
|
+
* Handle wdk/quoteSwap
|
|
4266
|
+
*/
|
|
4267
|
+
async handleWdkQuoteSwap(args) {
|
|
4268
|
+
const input = wdkQuoteSwapInputSchema.parse(args);
|
|
4269
|
+
const result = this.config.demoMode || !this.wdk ? executeWdkQuoteSwapDemo(input) : await executeWdkQuoteSwap(input, this.wdk);
|
|
4270
|
+
return {
|
|
4271
|
+
content: [{ type: "text", text: formatSwapQuoteResult(result) }]
|
|
4272
|
+
};
|
|
4273
|
+
}
|
|
4274
|
+
/**
|
|
4275
|
+
* Handle wdk/executeSwap
|
|
4276
|
+
*/
|
|
4277
|
+
async handleWdkExecuteSwap(args) {
|
|
4278
|
+
const input = wdkExecuteSwapInputSchema.parse(args);
|
|
4279
|
+
const result = this.config.demoMode || !this.wdk ? executeWdkExecuteSwapDemo(input) : await executeWdkExecuteSwap(input, this.wdk);
|
|
4280
|
+
if ("needsConfirmation" in result) {
|
|
4281
|
+
return this.formatConfirmation(result);
|
|
4282
|
+
}
|
|
4283
|
+
return {
|
|
4284
|
+
content: [{ type: "text", text: formatExecuteSwapResult(result) }]
|
|
4285
|
+
};
|
|
4286
|
+
}
|
|
2853
4287
|
// ---- ERC-8004 Tool Handlers ----
|
|
2854
4288
|
/**
|
|
2855
4289
|
* Handle erc8004/resolveAgent
|
|
@@ -2896,6 +4330,16 @@ var T402McpServer = class {
|
|
|
2896
4330
|
*/
|
|
2897
4331
|
async run() {
|
|
2898
4332
|
await this.initWdk();
|
|
4333
|
+
const onExit = () => this.cleanup();
|
|
4334
|
+
process.on("exit", onExit);
|
|
4335
|
+
process.on("SIGINT", () => {
|
|
4336
|
+
onExit();
|
|
4337
|
+
process.exit(0);
|
|
4338
|
+
});
|
|
4339
|
+
process.on("SIGTERM", () => {
|
|
4340
|
+
onExit();
|
|
4341
|
+
process.exit(0);
|
|
4342
|
+
});
|
|
2899
4343
|
const transport = new import_stdio.StdioServerTransport();
|
|
2900
4344
|
await this.server.connect(transport);
|
|
2901
4345
|
console.error("t402 MCP Server running on stdio");
|