@t402/mcp 2.8.0 → 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.
@@ -63,16 +63,20 @@ __export(tools_exports, {
63
63
  executeGetBalance: () => executeGetBalance,
64
64
  executeGetBridgeFee: () => executeGetBridgeFee,
65
65
  executeGetGasPrice: () => executeGetGasPrice,
66
+ executeGetHistoricalPrice: () => executeGetHistoricalPrice,
66
67
  executeGetTokenPrice: () => executeGetTokenPrice,
68
+ executeGetTransferHistory: () => executeGetTransferHistory,
67
69
  executePay: () => executePay,
68
70
  executePayGasless: () => executePayGasless,
69
71
  executePaymentPlan: () => executePaymentPlan,
70
72
  executePaymentPlanDemo: () => executePaymentPlanDemo,
71
73
  executeQuoteBridge: () => executeQuoteBridge,
72
74
  executeQuoteBridgeDemo: () => executeQuoteBridgeDemo,
75
+ executeSignMessage: () => executeSignMessage,
73
76
  executeSmartPay: () => executeSmartPay,
74
77
  executeSmartPayDemo: () => executeSmartPayDemo,
75
78
  executeTonBridgeTool: () => executeTonBridgeTool,
79
+ executeVerifySignature: () => executeVerifySignature,
76
80
  executeWdkExecuteSwap: () => executeWdkExecuteSwap,
77
81
  executeWdkExecuteSwapDemo: () => executeWdkExecuteSwapDemo,
78
82
  executeWdkGetBalances: () => executeWdkGetBalances,
@@ -98,13 +102,17 @@ __export(tools_exports, {
98
102
  formatExecuteSwapResult: () => formatExecuteSwapResult,
99
103
  formatGasPriceResult: () => formatGasPriceResult,
100
104
  formatGaslessPaymentResult: () => formatGaslessPaymentResult,
105
+ formatHistoricalPriceResult: () => formatHistoricalPriceResult,
101
106
  formatNetworkFeeComparison: () => formatNetworkFeeComparison,
102
107
  formatPaymentFeeEstimate: () => formatPaymentFeeEstimate,
103
108
  formatPaymentPlanResult: () => formatPaymentPlanResult,
104
109
  formatPaymentResult: () => formatPaymentResult,
110
+ formatSignMessageResult: () => formatSignMessageResult,
105
111
  formatSmartPayResult: () => formatSmartPayResult,
106
112
  formatSwapQuoteResult: () => formatSwapQuoteResult,
107
113
  formatTokenPriceResult: () => formatTokenPriceResult,
114
+ formatTransferHistoryResult: () => formatTransferHistoryResult,
115
+ formatVerifySignatureResult: () => formatVerifySignatureResult,
108
116
  formatWdkBalancesResult: () => formatWdkBalancesResult,
109
117
  formatWdkSwapResult: () => formatWdkSwapResult,
110
118
  formatWdkTransferResult: () => formatWdkTransferResult,
@@ -113,15 +121,19 @@ __export(tools_exports, {
113
121
  getBalanceInputSchema: () => getBalanceInputSchema,
114
122
  getBridgeFeeInputSchema: () => getBridgeFeeInputSchema,
115
123
  getGasPriceInputSchema: () => getGasPriceInputSchema,
124
+ getHistoricalPriceInputSchema: () => getHistoricalPriceInputSchema,
116
125
  getQuote: () => getQuote,
117
126
  getTokenPriceInputSchema: () => getTokenPriceInputSchema,
118
127
  getTokenPrices: () => getTokenPrices,
119
128
  getTokenPricesDemo: () => getTokenPricesDemo,
129
+ getTransferHistoryInputSchema: () => getTransferHistoryInputSchema,
120
130
  payGaslessInputSchema: () => payGaslessInputSchema,
121
131
  payInputSchema: () => payInputSchema,
122
132
  paymentPlanInputSchema: () => paymentPlanInputSchema,
123
133
  quoteBridgeInputSchema: () => quoteBridgeInputSchema,
134
+ signMessageInputSchema: () => signMessageInputSchema,
124
135
  smartPayInputSchema: () => smartPayInputSchema,
136
+ verifySignatureInputSchema: () => verifySignatureInputSchema,
125
137
  wdkExecuteSwapInputSchema: () => wdkExecuteSwapInputSchema,
126
138
  wdkGetBalancesInputSchema: () => wdkGetBalancesInputSchema,
127
139
  wdkGetWalletInputSchema: () => wdkGetWalletInputSchema,
@@ -1268,10 +1280,10 @@ var import_zod7 = require("zod");
1268
1280
  var wdkGetWalletInputSchema = import_zod7.z.object({});
1269
1281
  async function executeWdkGetWallet(_input, wdk) {
1270
1282
  const signer = await wdk.getSigner("ethereum");
1271
- const chains9 = wdk.getConfiguredChains();
1283
+ const chains10 = wdk.getConfiguredChains();
1272
1284
  return {
1273
1285
  evmAddress: signer.address,
1274
- chains: chains9.length > 0 ? chains9 : ["ethereum"]
1286
+ chains: chains10.length > 0 ? chains10 : ["ethereum"]
1275
1287
  };
1276
1288
  }
1277
1289
  function executeWdkGetWalletDemo() {
@@ -1303,14 +1315,14 @@ function findTokenFormatted(tokens, symbol) {
1303
1315
  }
1304
1316
  async function executeWdkGetBalances(input, wdk) {
1305
1317
  const balances = await wdk.getAggregatedBalances();
1306
- const chains9 = balances.chains.filter((c) => !input.chains || input.chains.includes(c.chain)).map((c) => ({
1318
+ const chains10 = balances.chains.filter((c) => !input.chains || input.chains.includes(c.chain)).map((c) => ({
1307
1319
  chain: c.chain,
1308
1320
  usdt0: findTokenFormatted(c.tokens, "USDT0"),
1309
1321
  usdc: findTokenFormatted(c.tokens, "USDC"),
1310
1322
  native: (0, import_viem6.formatUnits)(c.native, 18)
1311
1323
  }));
1312
1324
  return {
1313
- chains: chains9,
1325
+ chains: chains10,
1314
1326
  totalUsdt0: (0, import_viem6.formatUnits)(balances.totalUsdt0, 6),
1315
1327
  totalUsdc: (0, import_viem6.formatUnits)(balances.totalUsdc, 6)
1316
1328
  };
@@ -1510,22 +1522,37 @@ async function executeAutoPay(input, wdk) {
1510
1522
  }
1511
1523
  };
1512
1524
  }
1513
- const chains9 = input.preferredChain ? [input.preferredChain] : ["ethereum", "arbitrum", "base"];
1525
+ const chains10 = input.preferredChain ? [input.preferredChain] : ["ethereum", "arbitrum", "base"];
1514
1526
  const { T402Protocol } = await import("@t402/wdk-protocol");
1515
- const protocol = await T402Protocol.create(wdk, { chains: chains9 });
1516
- const { response, receipt } = await protocol.fetch(input.url);
1517
- if (receipt && input.maxAmount) {
1518
- const paidAmount = parseFloat(receipt.amount) / 1e6;
1527
+ const protocol = await T402Protocol.create(wdk, { chains: chains10 });
1528
+ if (input.maxAmount) {
1519
1529
  const maxAmount = parseFloat(input.maxAmount);
1520
- if (paidAmount > maxAmount) {
1521
- return {
1522
- success: false,
1523
- statusCode: 402,
1524
- body: "",
1525
- error: `Payment amount (${paidAmount}) exceeds max allowed (${maxAmount})`
1526
- };
1530
+ const preflightResponse = await fetch(input.url);
1531
+ if (preflightResponse.status === 402) {
1532
+ const requirementsHeader = preflightResponse.headers.get("x-payment") || preflightResponse.headers.get("x-payment-requirements");
1533
+ if (requirementsHeader) {
1534
+ try {
1535
+ const requirements = JSON.parse(requirementsHeader);
1536
+ const reqArray = Array.isArray(requirements) ? requirements : [requirements];
1537
+ for (const req of reqArray) {
1538
+ if (req.amount) {
1539
+ const reqAmount = parseFloat(req.amount) / 1e6;
1540
+ if (reqAmount > maxAmount) {
1541
+ return {
1542
+ success: false,
1543
+ statusCode: 402,
1544
+ body: "",
1545
+ error: `Required payment amount (${reqAmount}) exceeds max allowed (${maxAmount})`
1546
+ };
1547
+ }
1548
+ }
1549
+ }
1550
+ } catch {
1551
+ }
1552
+ }
1527
1553
  }
1528
1554
  }
1555
+ const { response, receipt } = await protocol.fetch(input.url);
1529
1556
  const contentType = response.headers.get("content-type") ?? void 0;
1530
1557
  let body = "";
1531
1558
  try {
@@ -2389,6 +2416,390 @@ function formatNetworkFeeComparison(result) {
2389
2416
  return lines.join("\n");
2390
2417
  }
2391
2418
 
2419
+ // src/tools/signMessage.ts
2420
+ var import_zod19 = require("zod");
2421
+ var signMessageInputSchema = import_zod19.z.object({
2422
+ chain: import_zod19.z.enum([
2423
+ "ethereum",
2424
+ "base",
2425
+ "arbitrum",
2426
+ "optimism",
2427
+ "polygon",
2428
+ "avalanche",
2429
+ "ink",
2430
+ "berachain",
2431
+ "unichain"
2432
+ ]).describe("Blockchain network context for signing"),
2433
+ message: import_zod19.z.string().min(1).describe("Message to sign")
2434
+ });
2435
+ async function executeSignMessage(_input) {
2436
+ throw new Error(
2437
+ "Wallet not configured. To sign messages, configure a private key via the T402_PRIVATE_KEY environment variable."
2438
+ );
2439
+ }
2440
+ function formatSignMessageResult(result) {
2441
+ const lines = [
2442
+ `## Message Signed on ${result.network}`,
2443
+ "",
2444
+ `- **Signer:** ${result.address}`,
2445
+ `- **Message:** ${result.message.length > 100 ? result.message.slice(0, 100) + "..." : result.message}`,
2446
+ `- **Signature:** \`${result.signature}\``
2447
+ ];
2448
+ return lines.join("\n");
2449
+ }
2450
+
2451
+ // src/tools/verifySignature.ts
2452
+ var import_zod20 = require("zod");
2453
+ var import_viem11 = require("viem");
2454
+ var verifySignatureInputSchema = import_zod20.z.object({
2455
+ chain: import_zod20.z.enum([
2456
+ "ethereum",
2457
+ "base",
2458
+ "arbitrum",
2459
+ "optimism",
2460
+ "polygon",
2461
+ "avalanche",
2462
+ "ink",
2463
+ "berachain",
2464
+ "unichain"
2465
+ ]).describe("Blockchain network context for verification"),
2466
+ message: import_zod20.z.string().min(1).describe("The original message that was signed"),
2467
+ signature: import_zod20.z.string().regex(/^0x[a-fA-F0-9]+$/).describe("The signature to verify (hex string)"),
2468
+ address: import_zod20.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("The expected signer address")
2469
+ });
2470
+ async function executeVerifySignature(input) {
2471
+ const { chain, message, signature, address } = input;
2472
+ try {
2473
+ const valid = await (0, import_viem11.verifyMessage)({
2474
+ address,
2475
+ message,
2476
+ signature
2477
+ });
2478
+ return {
2479
+ valid,
2480
+ address,
2481
+ message,
2482
+ network: chain
2483
+ };
2484
+ } catch (err) {
2485
+ return {
2486
+ valid: false,
2487
+ address,
2488
+ message,
2489
+ network: chain,
2490
+ error: err instanceof Error ? err.message : "Unknown verification error"
2491
+ };
2492
+ }
2493
+ }
2494
+ function formatVerifySignatureResult(result) {
2495
+ const status = result.valid ? "VALID" : "INVALID";
2496
+ const lines = [
2497
+ `## Signature Verification: ${status}`,
2498
+ "",
2499
+ `- **Address:** ${result.address}`,
2500
+ `- **Network:** ${result.network}`,
2501
+ `- **Message:** ${result.message.length > 100 ? result.message.slice(0, 100) + "..." : result.message}`,
2502
+ `- **Result:** ${result.valid ? "Signature is valid and matches the address" : "Signature does NOT match the address"}`
2503
+ ];
2504
+ if (result.error) {
2505
+ lines.push(`- **Error:** ${result.error}`);
2506
+ }
2507
+ return lines.join("\n");
2508
+ }
2509
+
2510
+ // src/tools/getTransferHistory.ts
2511
+ var import_zod21 = require("zod");
2512
+ var import_viem12 = require("viem");
2513
+ var chains9 = __toESM(require("viem/chains"));
2514
+ var getTransferHistoryInputSchema = import_zod21.z.object({
2515
+ network: import_zod21.z.enum([
2516
+ "ethereum",
2517
+ "base",
2518
+ "arbitrum",
2519
+ "optimism",
2520
+ "polygon",
2521
+ "avalanche",
2522
+ "ink",
2523
+ "berachain",
2524
+ "unichain"
2525
+ ]).describe("Blockchain network to query"),
2526
+ address: import_zod21.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Wallet address to get transfer history for"),
2527
+ token: import_zod21.z.enum(["USDC", "USDT", "USDT0"]).optional().describe("Filter by specific token. If not provided, queries all supported stablecoins."),
2528
+ limit: import_zod21.z.number().int().min(1).max(100).optional().describe("Maximum number of transfers to return (default: 10, max: 100)")
2529
+ });
2530
+ function getViemChain8(network) {
2531
+ switch (network) {
2532
+ case "ethereum":
2533
+ return chains9.mainnet;
2534
+ case "base":
2535
+ return chains9.base;
2536
+ case "arbitrum":
2537
+ return chains9.arbitrum;
2538
+ case "optimism":
2539
+ return chains9.optimism;
2540
+ case "polygon":
2541
+ return chains9.polygon;
2542
+ case "avalanche":
2543
+ return chains9.avalanche;
2544
+ case "ink":
2545
+ return chains9.ink;
2546
+ case "berachain":
2547
+ return chains9.berachain;
2548
+ case "unichain":
2549
+ return chains9.unichain;
2550
+ default:
2551
+ return chains9.mainnet;
2552
+ }
2553
+ }
2554
+ var TOKEN_DECIMALS = {
2555
+ USDC: 6,
2556
+ USDT: 6,
2557
+ USDT0: 6
2558
+ };
2559
+ async function executeGetTransferHistory(input, rpcUrls) {
2560
+ const { network, address, token, limit = 10 } = input;
2561
+ const walletAddress = address.toLowerCase();
2562
+ const rpcUrl = rpcUrls?.[network] || DEFAULT_RPC_URLS[network];
2563
+ const chain = getViemChain8(network);
2564
+ const client = (0, import_viem12.createPublicClient)({
2565
+ chain,
2566
+ transport: (0, import_viem12.http)(rpcUrl)
2567
+ });
2568
+ const tokenContracts = [];
2569
+ if (token) {
2570
+ const addresses = token === "USDC" ? USDC_ADDRESSES : token === "USDT" ? USDT_ADDRESSES : USDT0_ADDRESSES;
2571
+ const addr = addresses[network];
2572
+ if (addr) {
2573
+ tokenContracts.push({ address: addr, symbol: token });
2574
+ }
2575
+ } else {
2576
+ if (USDC_ADDRESSES[network]) {
2577
+ tokenContracts.push({ address: USDC_ADDRESSES[network], symbol: "USDC" });
2578
+ }
2579
+ if (USDT_ADDRESSES[network]) {
2580
+ tokenContracts.push({ address: USDT_ADDRESSES[network], symbol: "USDT" });
2581
+ }
2582
+ if (USDT0_ADDRESSES[network]) {
2583
+ tokenContracts.push({ address: USDT0_ADDRESSES[network], symbol: "USDT0" });
2584
+ }
2585
+ }
2586
+ if (tokenContracts.length === 0) {
2587
+ return {
2588
+ network,
2589
+ chainId: CHAIN_IDS[network],
2590
+ address,
2591
+ transfers: [],
2592
+ explorerUrl: EXPLORER_URLS[network]
2593
+ };
2594
+ }
2595
+ const currentBlock = await client.getBlockNumber();
2596
+ const fromBlock = currentBlock > 50000n ? currentBlock - 50000n : 0n;
2597
+ const transferEvent = (0, import_viem12.parseAbiItem)(
2598
+ "event Transfer(address indexed from, address indexed to, uint256 value)"
2599
+ );
2600
+ const allTransfers = [];
2601
+ for (const tokenContract of tokenContracts) {
2602
+ const decimals = TOKEN_DECIMALS[tokenContract.symbol] ?? 6;
2603
+ const [sentLogs, receivedLogs] = await Promise.all([
2604
+ client.getLogs({
2605
+ address: tokenContract.address,
2606
+ event: transferEvent,
2607
+ args: { from: walletAddress },
2608
+ fromBlock,
2609
+ toBlock: "latest"
2610
+ }),
2611
+ client.getLogs({
2612
+ address: tokenContract.address,
2613
+ event: transferEvent,
2614
+ args: { to: walletAddress },
2615
+ fromBlock,
2616
+ toBlock: "latest"
2617
+ })
2618
+ ]);
2619
+ for (const log of sentLogs) {
2620
+ allTransfers.push({
2621
+ txHash: log.transactionHash,
2622
+ blockNumber: (log.blockNumber ?? 0n).toString(),
2623
+ from: log.args.from ?? "",
2624
+ to: log.args.to ?? "",
2625
+ amount: (0, import_viem12.formatUnits)(log.args.value ?? 0n, decimals),
2626
+ token: tokenContract.symbol,
2627
+ tokenAddress: tokenContract.address,
2628
+ direction: "out"
2629
+ });
2630
+ }
2631
+ for (const log of receivedLogs) {
2632
+ allTransfers.push({
2633
+ txHash: log.transactionHash,
2634
+ blockNumber: (log.blockNumber ?? 0n).toString(),
2635
+ from: log.args.from ?? "",
2636
+ to: log.args.to ?? "",
2637
+ amount: (0, import_viem12.formatUnits)(log.args.value ?? 0n, decimals),
2638
+ token: tokenContract.symbol,
2639
+ tokenAddress: tokenContract.address,
2640
+ direction: "in"
2641
+ });
2642
+ }
2643
+ }
2644
+ allTransfers.sort((a, b) => {
2645
+ const blockA = BigInt(a.blockNumber);
2646
+ const blockB = BigInt(b.blockNumber);
2647
+ if (blockB > blockA) return 1;
2648
+ if (blockB < blockA) return -1;
2649
+ return 0;
2650
+ });
2651
+ return {
2652
+ network,
2653
+ chainId: CHAIN_IDS[network],
2654
+ address,
2655
+ transfers: allTransfers.slice(0, limit),
2656
+ explorerUrl: EXPLORER_URLS[network]
2657
+ };
2658
+ }
2659
+ function formatTransferHistoryResult(result) {
2660
+ const lines = [
2661
+ `## Transfer History on ${result.network} (Chain ID: ${result.chainId})`,
2662
+ "",
2663
+ `**Address:** ${result.address}`,
2664
+ ""
2665
+ ];
2666
+ if (result.transfers.length === 0) {
2667
+ lines.push("_No recent transfers found_");
2668
+ return lines.join("\n");
2669
+ }
2670
+ lines.push(`Found ${result.transfers.length} recent transfer(s):`, "");
2671
+ for (const tx of result.transfers) {
2672
+ const arrow = tx.direction === "in" ? "RECEIVED" : "SENT";
2673
+ const counterparty = tx.direction === "in" ? `from ${tx.from}` : `to ${tx.to}`;
2674
+ lines.push(
2675
+ `- **${arrow}** ${tx.amount} ${tx.token} ${counterparty}`,
2676
+ ` Block: ${tx.blockNumber} | [View Tx](${result.explorerUrl}/tx/${tx.txHash})`,
2677
+ ""
2678
+ );
2679
+ }
2680
+ return lines.join("\n");
2681
+ }
2682
+
2683
+ // src/tools/getHistoricalPrice.ts
2684
+ var import_zod22 = require("zod");
2685
+ var getHistoricalPriceInputSchema = import_zod22.z.object({
2686
+ token: import_zod22.z.string().min(1).describe('Token symbol (e.g., "ETH", "USDC", "USDT", "MATIC", "AVAX")'),
2687
+ days: import_zod22.z.number().int().min(1).max(365).optional().describe("Number of days of history to retrieve (default: 7, max: 365)")
2688
+ });
2689
+ var COINGECKO_MARKET_CHART = "https://api.coingecko.com/api/v3/coins";
2690
+ var TOKEN_TO_COINGECKO_ID2 = {
2691
+ ETH: "ethereum",
2692
+ MATIC: "matic-network",
2693
+ AVAX: "avalanche-2",
2694
+ BERA: "berachain-bera",
2695
+ USDC: "usd-coin",
2696
+ USDT: "tether",
2697
+ USDT0: "tether",
2698
+ BTC: "bitcoin",
2699
+ SOL: "solana",
2700
+ TON: "the-open-network",
2701
+ TRX: "tron"
2702
+ };
2703
+ async function executeGetHistoricalPrice(input, options = {}) {
2704
+ const { token, days = 7 } = input;
2705
+ const tokenUpper = token.toUpperCase();
2706
+ const coinId = TOKEN_TO_COINGECKO_ID2[tokenUpper] ?? token.toLowerCase();
2707
+ const currency = "usd";
2708
+ if (options.demoMode) {
2709
+ return generateDemoData(tokenUpper, coinId, days);
2710
+ }
2711
+ const url = `${COINGECKO_MARKET_CHART}/${coinId}/market_chart?vs_currency=${currency}&days=${days}`;
2712
+ const response = await fetch(url);
2713
+ if (!response.ok) {
2714
+ throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
2715
+ }
2716
+ const data = await response.json();
2717
+ const prices = data.prices.map(([timestamp, price]) => ({
2718
+ timestamp,
2719
+ date: new Date(timestamp).toISOString(),
2720
+ price
2721
+ }));
2722
+ const priceValues = prices.map((p) => p.price);
2723
+ const firstPrice = priceValues[0] ?? 0;
2724
+ const lastPrice = priceValues[priceValues.length - 1] ?? 0;
2725
+ const high = Math.max(...priceValues);
2726
+ const low = Math.min(...priceValues);
2727
+ const absolute = lastPrice - firstPrice;
2728
+ const percentage = firstPrice > 0 ? absolute / firstPrice * 100 : 0;
2729
+ return {
2730
+ token: tokenUpper,
2731
+ coinId,
2732
+ currency,
2733
+ days,
2734
+ prices,
2735
+ priceChange: {
2736
+ absolute: Math.round(absolute * 100) / 100,
2737
+ percentage: Math.round(percentage * 100) / 100,
2738
+ high: Math.round(high * 100) / 100,
2739
+ low: Math.round(low * 100) / 100
2740
+ }
2741
+ };
2742
+ }
2743
+ function generateDemoData(token, coinId, days) {
2744
+ const basePrices = {
2745
+ ETH: 3250,
2746
+ MATIC: 0.58,
2747
+ AVAX: 24.15,
2748
+ BERA: 3.82,
2749
+ USDC: 1,
2750
+ USDT: 1,
2751
+ USDT0: 1,
2752
+ BTC: 62e3,
2753
+ SOL: 145,
2754
+ TON: 5.2,
2755
+ TRX: 0.12
2756
+ };
2757
+ const basePrice = basePrices[token] ?? 1;
2758
+ const now = Date.now();
2759
+ const interval = days * 24 * 60 * 60 * 1e3 / Math.min(days * 24, 168);
2760
+ const numPoints = Math.min(days * 24, 168);
2761
+ const prices = [];
2762
+ for (let i = 0; i < numPoints; i++) {
2763
+ const timestamp = now - (numPoints - i) * interval;
2764
+ const fluctuation = 1 + (Math.sin(i * 0.5) * 0.03 + Math.cos(i * 0.3) * 0.02);
2765
+ const price = Math.round(basePrice * fluctuation * 100) / 100;
2766
+ prices.push({
2767
+ timestamp,
2768
+ date: new Date(timestamp).toISOString(),
2769
+ price
2770
+ });
2771
+ }
2772
+ const priceValues = prices.map((p) => p.price);
2773
+ const firstPrice = priceValues[0] ?? 0;
2774
+ const lastPrice = priceValues[priceValues.length - 1] ?? 0;
2775
+ return {
2776
+ token,
2777
+ coinId,
2778
+ currency: "usd",
2779
+ days,
2780
+ prices,
2781
+ priceChange: {
2782
+ absolute: Math.round((lastPrice - firstPrice) * 100) / 100,
2783
+ percentage: firstPrice > 0 ? Math.round((lastPrice - firstPrice) / firstPrice * 1e4) / 100 : 0,
2784
+ high: Math.round(Math.max(...priceValues) * 100) / 100,
2785
+ low: Math.round(Math.min(...priceValues) * 100) / 100
2786
+ }
2787
+ };
2788
+ }
2789
+ function formatHistoricalPriceResult(result) {
2790
+ const lines = [
2791
+ `## ${result.token} Price History (${result.days} day${result.days > 1 ? "s" : ""})`,
2792
+ "",
2793
+ `- **Current:** $${result.prices[result.prices.length - 1]?.price.toLocaleString() ?? "N/A"}`,
2794
+ `- **High:** $${result.priceChange.high.toLocaleString()}`,
2795
+ `- **Low:** $${result.priceChange.low.toLocaleString()}`,
2796
+ `- **Change:** ${result.priceChange.absolute >= 0 ? "+" : ""}$${result.priceChange.absolute.toLocaleString()} (${result.priceChange.percentage >= 0 ? "+" : ""}${result.priceChange.percentage}%)`,
2797
+ "",
2798
+ `_${result.prices.length} data points from CoinGecko_`
2799
+ ];
2800
+ return lines.join("\n");
2801
+ }
2802
+
2392
2803
  // src/tools/quoteStore.ts
2393
2804
  var import_crypto = require("crypto");
2394
2805
  var DEFAULT_TTL_MS = 5 * 60 * 1e3;
@@ -2438,17 +2849,17 @@ function clearQuoteStore() {
2438
2849
  }
2439
2850
 
2440
2851
  // src/tools/wdkQuoteSwap.ts
2441
- var import_zod19 = require("zod");
2442
- var import_viem11 = require("viem");
2443
- var wdkQuoteSwapInputSchema = import_zod19.z.object({
2444
- fromToken: import_zod19.z.string().describe('Token to swap from (e.g., "ETH", "USDC")'),
2445
- toToken: import_zod19.z.string().describe('Token to swap to (e.g., "USDT0", "USDC")'),
2446
- amount: import_zod19.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to swap (e.g., '1.0')"),
2447
- chain: import_zod19.z.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")')
2852
+ var import_zod23 = require("zod");
2853
+ var import_viem13 = require("viem");
2854
+ var wdkQuoteSwapInputSchema = import_zod23.z.object({
2855
+ fromToken: import_zod23.z.string().describe('Token to swap from (e.g., "ETH", "USDC")'),
2856
+ toToken: import_zod23.z.string().describe('Token to swap to (e.g., "USDT0", "USDC")'),
2857
+ amount: import_zod23.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to swap (e.g., '1.0')"),
2858
+ chain: import_zod23.z.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")')
2448
2859
  });
2449
2860
  async function executeWdkQuoteSwap(input, wdk) {
2450
2861
  const decimals = ["USDC", "USDT", "USDT0"].includes(input.fromToken.toUpperCase()) ? 6 : 18;
2451
- const amountBigInt = (0, import_viem11.parseUnits)(input.amount, decimals);
2862
+ const amountBigInt = (0, import_viem13.parseUnits)(input.amount, decimals);
2452
2863
  const quote = await wdk.getSwapQuote(input.chain, input.fromToken, amountBigInt);
2453
2864
  const outputDecimals = ["USDC", "USDT", "USDT0"].includes(input.toToken.toUpperCase()) ? 6 : 18;
2454
2865
  const outputDivisor = 10 ** outputDecimals;
@@ -2522,11 +2933,11 @@ function formatSwapQuoteResult(result) {
2522
2933
  }
2523
2934
 
2524
2935
  // src/tools/wdkExecuteSwap.ts
2525
- var import_zod20 = require("zod");
2526
- var import_viem12 = require("viem");
2527
- var wdkExecuteSwapInputSchema = import_zod20.z.object({
2528
- quoteId: import_zod20.z.string().uuid().describe("Quote ID from wdk/quoteSwap"),
2529
- confirmed: import_zod20.z.boolean().optional().describe("Set to true to confirm and execute this swap")
2936
+ var import_zod24 = require("zod");
2937
+ var import_viem14 = require("viem");
2938
+ var wdkExecuteSwapInputSchema = import_zod24.z.object({
2939
+ quoteId: import_zod24.z.string().uuid().describe("Quote ID from wdk/quoteSwap"),
2940
+ confirmed: import_zod24.z.boolean().optional().describe("Set to true to confirm and execute this swap")
2530
2941
  });
2531
2942
  async function executeWdkExecuteSwap(input, wdk) {
2532
2943
  const quote = getQuote(input.quoteId);
@@ -2545,7 +2956,7 @@ async function executeWdkExecuteSwap(input, wdk) {
2545
2956
  };
2546
2957
  }
2547
2958
  const decimals = ["USDC", "USDT", "USDT0"].includes(fromToken.toUpperCase()) ? 6 : 18;
2548
- const amountBigInt = (0, import_viem12.parseUnits)(fromAmount, decimals);
2959
+ const amountBigInt = (0, import_viem14.parseUnits)(fromAmount, decimals);
2549
2960
  const result = await wdk.swapAndPay({
2550
2961
  chain,
2551
2962
  fromToken,
@@ -2599,12 +3010,12 @@ function formatExecuteSwapResult(result) {
2599
3010
  }
2600
3011
 
2601
3012
  // src/tools/quoteBridge.ts
2602
- var import_zod21 = require("zod");
2603
- var quoteBridgeInputSchema = import_zod21.z.object({
2604
- fromChain: import_zod21.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Source chain to bridge from"),
2605
- toChain: import_zod21.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Destination chain to bridge to"),
2606
- amount: import_zod21.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"),
2607
- recipient: import_zod21.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain")
3013
+ var import_zod25 = require("zod");
3014
+ var quoteBridgeInputSchema = import_zod25.z.object({
3015
+ fromChain: import_zod25.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Source chain to bridge from"),
3016
+ toChain: import_zod25.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Destination chain to bridge to"),
3017
+ amount: import_zod25.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"),
3018
+ recipient: import_zod25.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain")
2608
3019
  });
2609
3020
  async function executeQuoteBridge(input, rpcUrls) {
2610
3021
  const feeResult = await executeGetBridgeFee(input, rpcUrls);
@@ -2672,10 +3083,10 @@ function formatBridgeQuoteResult(result) {
2672
3083
  }
2673
3084
 
2674
3085
  // src/tools/executeBridgeFromQuote.ts
2675
- var import_zod22 = require("zod");
2676
- var executeBridgeFromQuoteInputSchema = import_zod22.z.object({
2677
- quoteId: import_zod22.z.string().uuid().describe("Quote ID from t402/quoteBridge"),
2678
- confirmed: import_zod22.z.boolean().optional().describe("Set to true to confirm and execute this bridge")
3086
+ var import_zod26 = require("zod");
3087
+ var executeBridgeFromQuoteInputSchema = import_zod26.z.object({
3088
+ quoteId: import_zod26.z.string().uuid().describe("Quote ID from t402/quoteBridge"),
3089
+ confirmed: import_zod26.z.boolean().optional().describe("Set to true to confirm and execute this bridge")
2679
3090
  });
2680
3091
  async function executeExecuteBridgeFromQuote(input, options) {
2681
3092
  const quote = getQuote(input.quoteId);
@@ -2734,22 +3145,22 @@ function executeExecuteBridgeFromQuoteDemo(input) {
2734
3145
  }
2735
3146
 
2736
3147
  // src/tools/unified.ts
2737
- var import_zod23 = require("zod");
2738
- var smartPayInputSchema = import_zod23.z.object({
2739
- url: import_zod23.z.string().url().describe("URL of the 402-protected resource"),
2740
- maxBridgeFee: import_zod23.z.string().regex(/^\d+(\.\d+)?$/).optional().describe("Maximum acceptable bridge fee in native token (optional)"),
2741
- preferredNetwork: import_zod23.z.string().optional().describe("Preferred network for payment (optional)"),
2742
- confirmed: import_zod23.z.boolean().optional().describe("Set to true to confirm and execute this payment")
3148
+ var import_zod27 = require("zod");
3149
+ var smartPayInputSchema = import_zod27.z.object({
3150
+ url: import_zod27.z.string().url().describe("URL of the 402-protected resource"),
3151
+ maxBridgeFee: import_zod27.z.string().regex(/^\d+(\.\d+)?$/).optional().describe("Maximum acceptable bridge fee in native token (optional)"),
3152
+ preferredNetwork: import_zod27.z.string().optional().describe("Preferred network for payment (optional)"),
3153
+ confirmed: import_zod27.z.boolean().optional().describe("Set to true to confirm and execute this payment")
2743
3154
  });
2744
- var paymentPlanInputSchema = import_zod23.z.object({
2745
- paymentRequired: import_zod23.z.object({
2746
- scheme: import_zod23.z.string().optional(),
2747
- network: import_zod23.z.string().optional(),
2748
- maxAmountRequired: import_zod23.z.string().optional(),
2749
- resource: import_zod23.z.string().optional(),
2750
- description: import_zod23.z.string().optional(),
2751
- payTo: import_zod23.z.string().optional(),
2752
- maxDeadline: import_zod23.z.number().optional()
3155
+ var paymentPlanInputSchema = import_zod27.z.object({
3156
+ paymentRequired: import_zod27.z.object({
3157
+ scheme: import_zod27.z.string().optional(),
3158
+ network: import_zod27.z.string().optional(),
3159
+ maxAmountRequired: import_zod27.z.string().optional(),
3160
+ resource: import_zod27.z.string().optional(),
3161
+ description: import_zod27.z.string().optional(),
3162
+ payTo: import_zod27.z.string().optional(),
3163
+ maxDeadline: import_zod27.z.number().optional()
2753
3164
  }).passthrough().describe("The 402 PaymentRequired response")
2754
3165
  });
2755
3166
  var UNIFIED_TOOL_DEFINITIONS = {
@@ -2804,14 +3215,14 @@ async function executeSmartPay(input, wdk) {
2804
3215
  };
2805
3216
  }
2806
3217
  const steps = [];
2807
- const chains9 = input.preferredNetwork ? [input.preferredNetwork] : ["ethereum", "arbitrum", "base"];
3218
+ const chains10 = input.preferredNetwork ? [input.preferredNetwork] : ["ethereum", "arbitrum", "base"];
2808
3219
  steps.push({
2809
3220
  action: "check_balance",
2810
3221
  status: "success",
2811
- detail: `Checking balances on ${chains9.join(", ")}`
3222
+ detail: `Checking balances on ${chains10.join(", ")}`
2812
3223
  });
2813
3224
  const { T402Protocol } = await import("@t402/wdk-protocol");
2814
- const protocol = await T402Protocol.create(wdk, { chains: chains9 });
3225
+ const protocol = await T402Protocol.create(wdk, { chains: chains10 });
2815
3226
  steps.push({
2816
3227
  action: "fetch",
2817
3228
  status: "success",
@@ -3372,6 +3783,131 @@ var TOOL_DEFINITIONS = {
3372
3783
  },
3373
3784
  required: ["quoteId"]
3374
3785
  }
3786
+ },
3787
+ "t402/signMessage": {
3788
+ name: "t402/signMessage",
3789
+ description: "Sign a message using the configured wallet. Returns an EIP-191 personal signature. Requires a configured private key.",
3790
+ inputSchema: {
3791
+ type: "object",
3792
+ properties: {
3793
+ chain: {
3794
+ type: "string",
3795
+ enum: [
3796
+ "ethereum",
3797
+ "base",
3798
+ "arbitrum",
3799
+ "optimism",
3800
+ "polygon",
3801
+ "avalanche",
3802
+ "ink",
3803
+ "berachain",
3804
+ "unichain"
3805
+ ],
3806
+ description: "Blockchain network context for signing"
3807
+ },
3808
+ message: {
3809
+ type: "string",
3810
+ description: "Message to sign"
3811
+ }
3812
+ },
3813
+ required: ["chain", "message"]
3814
+ }
3815
+ },
3816
+ "t402/verifySignature": {
3817
+ name: "t402/verifySignature",
3818
+ 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.",
3819
+ inputSchema: {
3820
+ type: "object",
3821
+ properties: {
3822
+ chain: {
3823
+ type: "string",
3824
+ enum: [
3825
+ "ethereum",
3826
+ "base",
3827
+ "arbitrum",
3828
+ "optimism",
3829
+ "polygon",
3830
+ "avalanche",
3831
+ "ink",
3832
+ "berachain",
3833
+ "unichain"
3834
+ ],
3835
+ description: "Blockchain network context for verification"
3836
+ },
3837
+ message: {
3838
+ type: "string",
3839
+ description: "The original message that was signed"
3840
+ },
3841
+ signature: {
3842
+ type: "string",
3843
+ pattern: "^0x[a-fA-F0-9]+$",
3844
+ description: "The signature to verify (hex string)"
3845
+ },
3846
+ address: {
3847
+ type: "string",
3848
+ pattern: "^0x[a-fA-F0-9]{40}$",
3849
+ description: "The expected signer address"
3850
+ }
3851
+ },
3852
+ required: ["chain", "message", "signature", "address"]
3853
+ }
3854
+ },
3855
+ "t402/getTransferHistory": {
3856
+ name: "t402/getTransferHistory",
3857
+ 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.",
3858
+ inputSchema: {
3859
+ type: "object",
3860
+ properties: {
3861
+ network: {
3862
+ type: "string",
3863
+ enum: [
3864
+ "ethereum",
3865
+ "base",
3866
+ "arbitrum",
3867
+ "optimism",
3868
+ "polygon",
3869
+ "avalanche",
3870
+ "ink",
3871
+ "berachain",
3872
+ "unichain"
3873
+ ],
3874
+ description: "Blockchain network to query"
3875
+ },
3876
+ address: {
3877
+ type: "string",
3878
+ pattern: "^0x[a-fA-F0-9]{40}$",
3879
+ description: "Wallet address to get transfer history for"
3880
+ },
3881
+ token: {
3882
+ type: "string",
3883
+ enum: ["USDC", "USDT", "USDT0"],
3884
+ description: "Filter by specific token. If not provided, queries all supported stablecoins."
3885
+ },
3886
+ limit: {
3887
+ type: "number",
3888
+ description: "Maximum number of transfers to return (default: 10, max: 100)"
3889
+ }
3890
+ },
3891
+ required: ["network", "address"]
3892
+ }
3893
+ },
3894
+ "t402/getHistoricalPrice": {
3895
+ name: "t402/getHistoricalPrice",
3896
+ 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.",
3897
+ inputSchema: {
3898
+ type: "object",
3899
+ properties: {
3900
+ token: {
3901
+ type: "string",
3902
+ description: 'Token symbol (e.g., "ETH", "USDC", "USDT", "MATIC", "AVAX", "BTC", "SOL")'
3903
+ },
3904
+ days: {
3905
+ type: "number",
3906
+ description: "Number of days of history to retrieve (default: 7, max: 365)"
3907
+ }
3908
+ },
3909
+ required: ["token"]
3910
+ }
3375
3911
  }
3376
3912
  };
3377
3913
  var WDK_TOOL_DEFINITIONS = {
@@ -3645,16 +4181,20 @@ var ERC8004_TOOL_DEFINITIONS = {
3645
4181
  executeGetBalance,
3646
4182
  executeGetBridgeFee,
3647
4183
  executeGetGasPrice,
4184
+ executeGetHistoricalPrice,
3648
4185
  executeGetTokenPrice,
4186
+ executeGetTransferHistory,
3649
4187
  executePay,
3650
4188
  executePayGasless,
3651
4189
  executePaymentPlan,
3652
4190
  executePaymentPlanDemo,
3653
4191
  executeQuoteBridge,
3654
4192
  executeQuoteBridgeDemo,
4193
+ executeSignMessage,
3655
4194
  executeSmartPay,
3656
4195
  executeSmartPayDemo,
3657
4196
  executeTonBridgeTool,
4197
+ executeVerifySignature,
3658
4198
  executeWdkExecuteSwap,
3659
4199
  executeWdkExecuteSwapDemo,
3660
4200
  executeWdkGetBalances,
@@ -3680,13 +4220,17 @@ var ERC8004_TOOL_DEFINITIONS = {
3680
4220
  formatExecuteSwapResult,
3681
4221
  formatGasPriceResult,
3682
4222
  formatGaslessPaymentResult,
4223
+ formatHistoricalPriceResult,
3683
4224
  formatNetworkFeeComparison,
3684
4225
  formatPaymentFeeEstimate,
3685
4226
  formatPaymentPlanResult,
3686
4227
  formatPaymentResult,
4228
+ formatSignMessageResult,
3687
4229
  formatSmartPayResult,
3688
4230
  formatSwapQuoteResult,
3689
4231
  formatTokenPriceResult,
4232
+ formatTransferHistoryResult,
4233
+ formatVerifySignatureResult,
3690
4234
  formatWdkBalancesResult,
3691
4235
  formatWdkSwapResult,
3692
4236
  formatWdkTransferResult,
@@ -3695,15 +4239,19 @@ var ERC8004_TOOL_DEFINITIONS = {
3695
4239
  getBalanceInputSchema,
3696
4240
  getBridgeFeeInputSchema,
3697
4241
  getGasPriceInputSchema,
4242
+ getHistoricalPriceInputSchema,
3698
4243
  getQuote,
3699
4244
  getTokenPriceInputSchema,
3700
4245
  getTokenPrices,
3701
4246
  getTokenPricesDemo,
4247
+ getTransferHistoryInputSchema,
3702
4248
  payGaslessInputSchema,
3703
4249
  payInputSchema,
3704
4250
  paymentPlanInputSchema,
3705
4251
  quoteBridgeInputSchema,
4252
+ signMessageInputSchema,
3706
4253
  smartPayInputSchema,
4254
+ verifySignatureInputSchema,
3707
4255
  wdkExecuteSwapInputSchema,
3708
4256
  wdkGetBalancesInputSchema,
3709
4257
  wdkGetWalletInputSchema,