@t402/mcp 2.5.0 → 2.6.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/bin/t402-mcp.js +9 -3
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +569 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/index.d.ts +22 -2
- package/dist/cjs/server/index.js +551 -1
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/{types-CwwW_c2B.d.ts → ton-bridge-BN3RKhNy.d.ts} +89 -1
- package/dist/cjs/tools/index.d.ts +219 -2
- package/dist/cjs/tools/index.js +514 -0
- package/dist/cjs/tools/index.js.map +1 -1
- package/dist/esm/{chunk-KTG47TRY.mjs → chunk-3FGPOVUZ.mjs} +82 -3
- package/dist/esm/chunk-3FGPOVUZ.mjs.map +1 -0
- package/dist/esm/{chunk-5UOBQKXW.mjs → chunk-RDQ7AMR4.mjs} +503 -1
- package/dist/esm/chunk-RDQ7AMR4.mjs.map +1 -0
- package/dist/esm/index.d.mts +3 -3
- package/dist/esm/index.mjs +20 -2
- package/dist/esm/server/index.d.mts +22 -2
- package/dist/esm/server/index.mjs +2 -2
- package/dist/esm/{types-CwwW_c2B.d.mts → ton-bridge-BN3RKhNy.d.mts} +89 -1
- package/dist/esm/tools/index.d.mts +219 -2
- package/dist/esm/tools/index.mjs +25 -1
- package/package.json +20 -12
- package/dist/esm/chunk-5UOBQKXW.mjs.map +0 -1
- package/dist/esm/chunk-KTG47TRY.mjs.map +0 -1
package/dist/cjs/index.js
CHANGED
|
@@ -40,6 +40,7 @@ __export(src_exports, {
|
|
|
40
40
|
NATIVE_SYMBOLS: () => NATIVE_SYMBOLS,
|
|
41
41
|
T402McpServer: () => T402McpServer,
|
|
42
42
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
43
|
+
UNIFIED_TOOL_DEFINITIONS: () => UNIFIED_TOOL_DEFINITIONS,
|
|
43
44
|
USDC_ADDRESSES: () => USDC_ADDRESSES,
|
|
44
45
|
USDT0_ADDRESSES: () => USDT0_ADDRESSES,
|
|
45
46
|
USDT_ADDRESSES: () => USDT_ADDRESSES,
|
|
@@ -51,12 +52,18 @@ __export(src_exports, {
|
|
|
51
52
|
executeGetBridgeFee: () => executeGetBridgeFee,
|
|
52
53
|
executePay: () => executePay,
|
|
53
54
|
executePayGasless: () => executePayGasless,
|
|
55
|
+
executePaymentPlan: () => executePaymentPlan,
|
|
56
|
+
executePaymentPlanDemo: () => executePaymentPlanDemo,
|
|
57
|
+
executeSmartPay: () => executeSmartPay,
|
|
58
|
+
executeSmartPayDemo: () => executeSmartPayDemo,
|
|
54
59
|
formatAllBalancesResult: () => formatAllBalancesResult,
|
|
55
60
|
formatBalanceResult: () => formatBalanceResult,
|
|
56
61
|
formatBridgeFeeResult: () => formatBridgeFeeResult,
|
|
57
62
|
formatBridgeResult: () => formatBridgeResult,
|
|
58
63
|
formatGaslessPaymentResult: () => formatGaslessPaymentResult,
|
|
64
|
+
formatPaymentPlanResult: () => formatPaymentPlanResult,
|
|
59
65
|
formatPaymentResult: () => formatPaymentResult,
|
|
66
|
+
formatSmartPayResult: () => formatSmartPayResult,
|
|
60
67
|
formatTokenAmount: () => formatTokenAmount,
|
|
61
68
|
getAllBalancesInputSchema: () => getAllBalancesInputSchema,
|
|
62
69
|
getBalanceInputSchema: () => getBalanceInputSchema,
|
|
@@ -68,6 +75,8 @@ __export(src_exports, {
|
|
|
68
75
|
parseTokenAmount: () => parseTokenAmount,
|
|
69
76
|
payGaslessInputSchema: () => payGaslessInputSchema,
|
|
70
77
|
payInputSchema: () => payInputSchema,
|
|
78
|
+
paymentPlanInputSchema: () => paymentPlanInputSchema,
|
|
79
|
+
smartPayInputSchema: () => smartPayInputSchema,
|
|
71
80
|
supportsToken: () => supportsToken
|
|
72
81
|
});
|
|
73
82
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -1479,6 +1488,488 @@ function formatAutoPayResult(result) {
|
|
|
1479
1488
|
return lines.join("\n");
|
|
1480
1489
|
}
|
|
1481
1490
|
|
|
1491
|
+
// src/tools/ton-bridge.ts
|
|
1492
|
+
var TON_BRIDGE_TOOLS = {
|
|
1493
|
+
"ton/getBalance": {
|
|
1494
|
+
name: "ton/getBalance",
|
|
1495
|
+
description: "Get TON and Jetton balances for a wallet address on the TON blockchain.",
|
|
1496
|
+
inputSchema: {
|
|
1497
|
+
type: "object",
|
|
1498
|
+
properties: {
|
|
1499
|
+
address: {
|
|
1500
|
+
type: "string",
|
|
1501
|
+
description: "TON wallet address (friendly or raw format)"
|
|
1502
|
+
}
|
|
1503
|
+
},
|
|
1504
|
+
required: ["address"]
|
|
1505
|
+
}
|
|
1506
|
+
},
|
|
1507
|
+
"ton/transfer": {
|
|
1508
|
+
name: "ton/transfer",
|
|
1509
|
+
description: "Send TON to a recipient address on the TON blockchain.",
|
|
1510
|
+
inputSchema: {
|
|
1511
|
+
type: "object",
|
|
1512
|
+
properties: {
|
|
1513
|
+
to: {
|
|
1514
|
+
type: "string",
|
|
1515
|
+
description: "Recipient TON address"
|
|
1516
|
+
},
|
|
1517
|
+
amount: {
|
|
1518
|
+
type: "string",
|
|
1519
|
+
description: 'Amount of TON to send (e.g., "1.5")'
|
|
1520
|
+
},
|
|
1521
|
+
memo: {
|
|
1522
|
+
type: "string",
|
|
1523
|
+
description: "Optional memo/comment for the transfer"
|
|
1524
|
+
}
|
|
1525
|
+
},
|
|
1526
|
+
required: ["to", "amount"]
|
|
1527
|
+
}
|
|
1528
|
+
},
|
|
1529
|
+
"ton/getJettonBalance": {
|
|
1530
|
+
name: "ton/getJettonBalance",
|
|
1531
|
+
description: "Get the balance of a specific Jetton (TON token) for a wallet address.",
|
|
1532
|
+
inputSchema: {
|
|
1533
|
+
type: "object",
|
|
1534
|
+
properties: {
|
|
1535
|
+
address: {
|
|
1536
|
+
type: "string",
|
|
1537
|
+
description: "TON wallet address"
|
|
1538
|
+
},
|
|
1539
|
+
jettonMaster: {
|
|
1540
|
+
type: "string",
|
|
1541
|
+
description: "Jetton master contract address"
|
|
1542
|
+
}
|
|
1543
|
+
},
|
|
1544
|
+
required: ["address", "jettonMaster"]
|
|
1545
|
+
}
|
|
1546
|
+
},
|
|
1547
|
+
"ton/swapJettons": {
|
|
1548
|
+
name: "ton/swapJettons",
|
|
1549
|
+
description: "Swap Jettons (TON tokens) using DEX aggregation on the TON network. Returns a raw transaction JSON to be sent via sendTransaction.",
|
|
1550
|
+
inputSchema: {
|
|
1551
|
+
type: "object",
|
|
1552
|
+
properties: {
|
|
1553
|
+
from: {
|
|
1554
|
+
type: "string",
|
|
1555
|
+
description: 'Source Jetton master address (or "TON" for native TON)'
|
|
1556
|
+
},
|
|
1557
|
+
to: {
|
|
1558
|
+
type: "string",
|
|
1559
|
+
description: 'Destination Jetton master address (or "TON" for native TON)'
|
|
1560
|
+
},
|
|
1561
|
+
amount: {
|
|
1562
|
+
type: "string",
|
|
1563
|
+
description: 'Amount to swap in human-readable format (e.g., "1.5")'
|
|
1564
|
+
},
|
|
1565
|
+
slippage: {
|
|
1566
|
+
type: "string",
|
|
1567
|
+
description: 'Slippage tolerance (e.g., "0.5" for 0.5%)'
|
|
1568
|
+
}
|
|
1569
|
+
},
|
|
1570
|
+
required: ["from", "to", "amount"]
|
|
1571
|
+
}
|
|
1572
|
+
},
|
|
1573
|
+
"ton/getTransactionStatus": {
|
|
1574
|
+
name: "ton/getTransactionStatus",
|
|
1575
|
+
description: "Check the status and details of a TON transaction by its hash.",
|
|
1576
|
+
inputSchema: {
|
|
1577
|
+
type: "object",
|
|
1578
|
+
properties: {
|
|
1579
|
+
txHash: {
|
|
1580
|
+
type: "string",
|
|
1581
|
+
description: "Transaction hash (BOC hash or message hash)"
|
|
1582
|
+
}
|
|
1583
|
+
},
|
|
1584
|
+
required: ["txHash"]
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
async function executeTonBridgeTool(toolName, args, config) {
|
|
1589
|
+
if (config.demoMode) {
|
|
1590
|
+
return executeTonBridgeToolDemo(toolName, args);
|
|
1591
|
+
}
|
|
1592
|
+
if (config.tonMcpEndpoint) {
|
|
1593
|
+
return proxyToTonMcp(toolName, args, config.tonMcpEndpoint);
|
|
1594
|
+
}
|
|
1595
|
+
if (config.tonApiKey) {
|
|
1596
|
+
return executeTonBridgeToolDirect(toolName, args, config.tonApiKey);
|
|
1597
|
+
}
|
|
1598
|
+
return {
|
|
1599
|
+
content: [
|
|
1600
|
+
{
|
|
1601
|
+
type: "text",
|
|
1602
|
+
text: `Error: TON MCP bridge not configured. Set tonMcpEndpoint or tonApiKey.`
|
|
1603
|
+
}
|
|
1604
|
+
],
|
|
1605
|
+
isError: true
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
function executeTonBridgeToolDemo(toolName, args) {
|
|
1609
|
+
const responses = {
|
|
1610
|
+
"ton/getBalance": `[DEMO] TON Balance for ${args.address ?? "unknown"}:
|
|
1611
|
+
- TON: 5.25
|
|
1612
|
+
- USDT0: 100.00`,
|
|
1613
|
+
"ton/transfer": `[DEMO] Transfer sent:
|
|
1614
|
+
- To: ${args.to ?? "unknown"}
|
|
1615
|
+
- Amount: ${args.amount ?? "0"} TON
|
|
1616
|
+
- TX: demo-ton-tx-hash-${Date.now().toString(36)}`,
|
|
1617
|
+
"ton/getJettonBalance": `[DEMO] Jetton Balance:
|
|
1618
|
+
- Address: ${args.address ?? "unknown"}
|
|
1619
|
+
- Jetton: ${args.jettonMaster ?? "unknown"}
|
|
1620
|
+
- Balance: 50.00`,
|
|
1621
|
+
"ton/swapJettons": `[DEMO] Swap quote received:
|
|
1622
|
+
- From: ${args.from ?? "unknown"}
|
|
1623
|
+
- To: ${args.to ?? "unknown"}
|
|
1624
|
+
- Amount: ${args.amount ?? "0"}
|
|
1625
|
+
- Transaction: {"validUntil":${Math.floor(Date.now() / 1e3) + 300},"messages":[{"address":"EQDemo...","amount":"${args.amount ?? "0"}","payload":"base64..."}]}`,
|
|
1626
|
+
"ton/getTransactionStatus": `[DEMO] Transaction Status:
|
|
1627
|
+
- Hash: ${args.txHash ?? "unknown"}
|
|
1628
|
+
- Status: Confirmed
|
|
1629
|
+
- Block: 12345678`
|
|
1630
|
+
};
|
|
1631
|
+
return {
|
|
1632
|
+
content: [
|
|
1633
|
+
{
|
|
1634
|
+
type: "text",
|
|
1635
|
+
text: responses[toolName] ?? `[DEMO] Unknown TON tool: ${toolName}`
|
|
1636
|
+
}
|
|
1637
|
+
]
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1640
|
+
async function proxyToTonMcp(toolName, args, endpoint) {
|
|
1641
|
+
try {
|
|
1642
|
+
const response = await fetch(endpoint, {
|
|
1643
|
+
method: "POST",
|
|
1644
|
+
headers: { "Content-Type": "application/json" },
|
|
1645
|
+
body: JSON.stringify({
|
|
1646
|
+
jsonrpc: "2.0",
|
|
1647
|
+
id: 1,
|
|
1648
|
+
method: "tools/call",
|
|
1649
|
+
params: { name: toolName, arguments: args }
|
|
1650
|
+
})
|
|
1651
|
+
});
|
|
1652
|
+
if (!response.ok) {
|
|
1653
|
+
throw new Error(`TON MCP server returned ${response.status}`);
|
|
1654
|
+
}
|
|
1655
|
+
const result = await response.json();
|
|
1656
|
+
if (result.error) {
|
|
1657
|
+
throw new Error(result.error.message);
|
|
1658
|
+
}
|
|
1659
|
+
return result.result ?? { content: [{ type: "text", text: "No result" }] };
|
|
1660
|
+
} catch (error) {
|
|
1661
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1662
|
+
return {
|
|
1663
|
+
content: [{ type: "text", text: `Error proxying to @ton/mcp: ${message}` }],
|
|
1664
|
+
isError: true
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
async function executeTonBridgeToolDirect(toolName, args, apiKey) {
|
|
1669
|
+
const baseUrl = "https://toncenter.com/api/v2";
|
|
1670
|
+
try {
|
|
1671
|
+
switch (toolName) {
|
|
1672
|
+
case "ton/getBalance": {
|
|
1673
|
+
const response = await fetch(
|
|
1674
|
+
`${baseUrl}/getAddressBalance?address=${encodeURIComponent(String(args.address))}&api_key=${apiKey}`
|
|
1675
|
+
);
|
|
1676
|
+
const data = await response.json();
|
|
1677
|
+
const balanceNano = BigInt(data.result);
|
|
1678
|
+
const balanceTon = Number(balanceNano) / 1e9;
|
|
1679
|
+
return {
|
|
1680
|
+
content: [{ type: "text", text: `TON Balance: ${balanceTon.toFixed(4)} TON` }]
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
case "ton/getTransactionStatus": {
|
|
1684
|
+
const response = await fetch(
|
|
1685
|
+
`${baseUrl}/getTransactions?hash=${encodeURIComponent(String(args.txHash))}&limit=1&api_key=${apiKey}`
|
|
1686
|
+
);
|
|
1687
|
+
const data = await response.json();
|
|
1688
|
+
if (data.result.length === 0) {
|
|
1689
|
+
return {
|
|
1690
|
+
content: [{ type: "text", text: "Transaction not found" }]
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
return {
|
|
1694
|
+
content: [
|
|
1695
|
+
{
|
|
1696
|
+
type: "text",
|
|
1697
|
+
text: `Transaction found:
|
|
1698
|
+
${JSON.stringify(data.result[0], null, 2)}`
|
|
1699
|
+
}
|
|
1700
|
+
]
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
default:
|
|
1704
|
+
return {
|
|
1705
|
+
content: [
|
|
1706
|
+
{
|
|
1707
|
+
type: "text",
|
|
1708
|
+
text: `Direct execution of ${toolName} is not supported. Configure tonMcpEndpoint to proxy to @ton/mcp.`
|
|
1709
|
+
}
|
|
1710
|
+
],
|
|
1711
|
+
isError: true
|
|
1712
|
+
};
|
|
1713
|
+
}
|
|
1714
|
+
} catch (error) {
|
|
1715
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1716
|
+
return {
|
|
1717
|
+
content: [{ type: "text", text: `Error executing TON API call: ${message}` }],
|
|
1718
|
+
isError: true
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
// src/tools/unified.ts
|
|
1724
|
+
var import_zod12 = require("zod");
|
|
1725
|
+
var import_wdk_protocol2 = require("@t402/wdk-protocol");
|
|
1726
|
+
var smartPayInputSchema = import_zod12.z.object({
|
|
1727
|
+
url: import_zod12.z.string().url().describe("URL of the 402-protected resource"),
|
|
1728
|
+
maxBridgeFee: import_zod12.z.string().regex(/^\d+(\.\d+)?$/).optional().describe("Maximum acceptable bridge fee in native token (optional)"),
|
|
1729
|
+
preferredNetwork: import_zod12.z.string().optional().describe("Preferred network for payment (optional)")
|
|
1730
|
+
});
|
|
1731
|
+
var paymentPlanInputSchema = import_zod12.z.object({
|
|
1732
|
+
paymentRequired: import_zod12.z.object({
|
|
1733
|
+
scheme: import_zod12.z.string().optional(),
|
|
1734
|
+
network: import_zod12.z.string().optional(),
|
|
1735
|
+
maxAmountRequired: import_zod12.z.string().optional(),
|
|
1736
|
+
resource: import_zod12.z.string().optional(),
|
|
1737
|
+
description: import_zod12.z.string().optional(),
|
|
1738
|
+
payTo: import_zod12.z.string().optional(),
|
|
1739
|
+
maxDeadline: import_zod12.z.number().optional()
|
|
1740
|
+
}).passthrough().describe("The 402 PaymentRequired response")
|
|
1741
|
+
});
|
|
1742
|
+
var UNIFIED_TOOL_DEFINITIONS = {
|
|
1743
|
+
"t402/smartPay": {
|
|
1744
|
+
name: "t402/smartPay",
|
|
1745
|
+
description: "Intelligent payment that automatically checks balance, bridges if needed, and pays. Handles the entire payment flow for 402-protected resources.",
|
|
1746
|
+
inputSchema: {
|
|
1747
|
+
type: "object",
|
|
1748
|
+
properties: {
|
|
1749
|
+
url: { type: "string", description: "URL of the 402-protected resource" },
|
|
1750
|
+
maxBridgeFee: {
|
|
1751
|
+
type: "string",
|
|
1752
|
+
description: "Maximum acceptable bridge fee in native token (optional)"
|
|
1753
|
+
},
|
|
1754
|
+
preferredNetwork: {
|
|
1755
|
+
type: "string",
|
|
1756
|
+
description: "Preferred network for payment (optional)"
|
|
1757
|
+
}
|
|
1758
|
+
},
|
|
1759
|
+
required: ["url"]
|
|
1760
|
+
}
|
|
1761
|
+
},
|
|
1762
|
+
"t402/paymentPlan": {
|
|
1763
|
+
name: "t402/paymentPlan",
|
|
1764
|
+
description: "Analyze a 402 response and create an optimal payment plan considering balances across all chains. Returns recommended network, bridge requirements, and balance overview.",
|
|
1765
|
+
inputSchema: {
|
|
1766
|
+
type: "object",
|
|
1767
|
+
properties: {
|
|
1768
|
+
paymentRequired: {
|
|
1769
|
+
type: "object",
|
|
1770
|
+
description: "The 402 PaymentRequired response"
|
|
1771
|
+
}
|
|
1772
|
+
},
|
|
1773
|
+
required: ["paymentRequired"]
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
};
|
|
1777
|
+
async function executeSmartPay(input, wdk) {
|
|
1778
|
+
const steps = [];
|
|
1779
|
+
const chains6 = input.preferredNetwork ? [input.preferredNetwork] : ["ethereum", "arbitrum", "base"];
|
|
1780
|
+
steps.push({
|
|
1781
|
+
action: "check_balance",
|
|
1782
|
+
status: "success",
|
|
1783
|
+
detail: `Checking balances on ${chains6.join(", ")}`
|
|
1784
|
+
});
|
|
1785
|
+
const protocol = await import_wdk_protocol2.T402Protocol.create(wdk, { chains: chains6 });
|
|
1786
|
+
steps.push({
|
|
1787
|
+
action: "fetch",
|
|
1788
|
+
status: "success",
|
|
1789
|
+
detail: `Fetching ${input.url}`
|
|
1790
|
+
});
|
|
1791
|
+
const { response, receipt } = await protocol.fetch(input.url);
|
|
1792
|
+
if (receipt) {
|
|
1793
|
+
steps.push({
|
|
1794
|
+
action: "pay",
|
|
1795
|
+
status: "success",
|
|
1796
|
+
detail: `Payment made: ${receipt.amount} on ${receipt.network}`
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
const contentType = response.headers.get("content-type") ?? void 0;
|
|
1800
|
+
let body = "";
|
|
1801
|
+
try {
|
|
1802
|
+
body = await response.text();
|
|
1803
|
+
if (body.length > 1e4) {
|
|
1804
|
+
body = body.slice(0, 1e4) + "\n... (truncated)";
|
|
1805
|
+
}
|
|
1806
|
+
} catch {
|
|
1807
|
+
body = "[Could not read response body]";
|
|
1808
|
+
}
|
|
1809
|
+
return {
|
|
1810
|
+
success: response.ok,
|
|
1811
|
+
statusCode: response.status,
|
|
1812
|
+
body,
|
|
1813
|
+
contentType,
|
|
1814
|
+
steps,
|
|
1815
|
+
payment: receipt ? {
|
|
1816
|
+
network: receipt.network,
|
|
1817
|
+
scheme: receipt.scheme,
|
|
1818
|
+
amount: receipt.amount,
|
|
1819
|
+
payTo: receipt.payTo
|
|
1820
|
+
} : void 0
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
function executeSmartPayDemo(input) {
|
|
1824
|
+
const network = input.preferredNetwork ?? "arbitrum";
|
|
1825
|
+
return {
|
|
1826
|
+
success: true,
|
|
1827
|
+
statusCode: 200,
|
|
1828
|
+
body: `[Demo] Premium content from ${input.url}
|
|
1829
|
+
|
|
1830
|
+
This is simulated content returned after smart payment.`,
|
|
1831
|
+
contentType: "text/plain",
|
|
1832
|
+
steps: [
|
|
1833
|
+
{ action: "check_balance", status: "success", detail: `Checked balances on ${network}` },
|
|
1834
|
+
{ action: "check_price", status: "success", detail: "Resource costs 1.00 USDT0" },
|
|
1835
|
+
{ action: "pay", status: "success", detail: `Paid 1000000 USDT0 on eip155:42161` },
|
|
1836
|
+
{ action: "fetch", status: "success", detail: `Fetched ${input.url}` }
|
|
1837
|
+
],
|
|
1838
|
+
payment: {
|
|
1839
|
+
network: "eip155:42161",
|
|
1840
|
+
scheme: "exact",
|
|
1841
|
+
amount: "1000000",
|
|
1842
|
+
payTo: "0xC88f67e776f16DcFBf42e6bDda1B82604448899B"
|
|
1843
|
+
}
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
async function executePaymentPlan(input, wdk) {
|
|
1847
|
+
const targetNetwork = input.paymentRequired.network;
|
|
1848
|
+
const requiredAmount = input.paymentRequired.maxAmountRequired;
|
|
1849
|
+
const aggregated = await wdk.getAggregatedBalances();
|
|
1850
|
+
const balances = aggregated.chains.map((chain) => {
|
|
1851
|
+
const usdt0 = chain.tokens.find((t) => t.symbol === "USDT0");
|
|
1852
|
+
const usdc = chain.tokens.find((t) => t.symbol === "USDC");
|
|
1853
|
+
return {
|
|
1854
|
+
chain: chain.chain,
|
|
1855
|
+
usdt0: usdt0?.formatted ?? "0",
|
|
1856
|
+
usdc: usdc?.formatted ?? "0"
|
|
1857
|
+
};
|
|
1858
|
+
});
|
|
1859
|
+
const requiredBigint = requiredAmount ? BigInt(requiredAmount) : 0n;
|
|
1860
|
+
const bestChain = await wdk.findBestChainForPayment(requiredBigint);
|
|
1861
|
+
if (bestChain) {
|
|
1862
|
+
const needsBridge = targetNetwork ? !bestChain.chain.includes(targetNetwork) : false;
|
|
1863
|
+
return {
|
|
1864
|
+
viable: true,
|
|
1865
|
+
recommendedNetwork: bestChain.chain,
|
|
1866
|
+
availableBalance: bestChain.balance.toString(),
|
|
1867
|
+
bridgeRequired: needsBridge,
|
|
1868
|
+
bridgeDetails: needsBridge ? {
|
|
1869
|
+
fromChain: bestChain.chain,
|
|
1870
|
+
toChain: targetNetwork ?? bestChain.chain,
|
|
1871
|
+
amount: requiredAmount ?? "0",
|
|
1872
|
+
estimatedFee: "0.001"
|
|
1873
|
+
} : void 0,
|
|
1874
|
+
balances
|
|
1875
|
+
};
|
|
1876
|
+
}
|
|
1877
|
+
return {
|
|
1878
|
+
viable: false,
|
|
1879
|
+
bridgeRequired: false,
|
|
1880
|
+
balances,
|
|
1881
|
+
reason: "Insufficient balance across all chains"
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
function executePaymentPlanDemo(_input) {
|
|
1885
|
+
return {
|
|
1886
|
+
viable: true,
|
|
1887
|
+
recommendedNetwork: "arbitrum",
|
|
1888
|
+
availableBalance: "500000000",
|
|
1889
|
+
bridgeRequired: false,
|
|
1890
|
+
balances: [
|
|
1891
|
+
{ chain: "ethereum", usdt0: "100.00", usdc: "250.00" },
|
|
1892
|
+
{ chain: "arbitrum", usdt0: "500.00", usdc: "0" },
|
|
1893
|
+
{ chain: "base", usdt0: "50.00", usdc: "100.00" }
|
|
1894
|
+
]
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
function formatSmartPayResult(result) {
|
|
1898
|
+
const lines = ["## SmartPay Result", ""];
|
|
1899
|
+
if (result.success) {
|
|
1900
|
+
lines.push(`**Status:** Success (${result.statusCode})`);
|
|
1901
|
+
} else {
|
|
1902
|
+
lines.push(`**Status:** Failed (${result.statusCode})`);
|
|
1903
|
+
}
|
|
1904
|
+
if (result.steps.length > 0) {
|
|
1905
|
+
lines.push("");
|
|
1906
|
+
lines.push("### Steps");
|
|
1907
|
+
for (const step of result.steps) {
|
|
1908
|
+
const icon = step.status === "success" ? "[OK]" : step.status === "skipped" ? "[SKIP]" : "[FAIL]";
|
|
1909
|
+
lines.push(`- ${icon} **${step.action}**: ${step.detail}`);
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
if (result.payment) {
|
|
1913
|
+
lines.push("");
|
|
1914
|
+
lines.push("### Payment Details");
|
|
1915
|
+
lines.push(`- **Network:** ${result.payment.network}`);
|
|
1916
|
+
lines.push(`- **Scheme:** ${result.payment.scheme}`);
|
|
1917
|
+
lines.push(`- **Amount:** ${result.payment.amount}`);
|
|
1918
|
+
lines.push(`- **Pay To:** \`${result.payment.payTo}\``);
|
|
1919
|
+
}
|
|
1920
|
+
if (result.error) {
|
|
1921
|
+
lines.push("");
|
|
1922
|
+
lines.push(`**Error:** ${result.error}`);
|
|
1923
|
+
}
|
|
1924
|
+
if (result.body) {
|
|
1925
|
+
lines.push("");
|
|
1926
|
+
lines.push("### Response Content");
|
|
1927
|
+
if (result.contentType) {
|
|
1928
|
+
lines.push(`_Content-Type: ${result.contentType}_`);
|
|
1929
|
+
}
|
|
1930
|
+
lines.push("");
|
|
1931
|
+
lines.push("```");
|
|
1932
|
+
lines.push(result.body);
|
|
1933
|
+
lines.push("```");
|
|
1934
|
+
}
|
|
1935
|
+
return lines.join("\n");
|
|
1936
|
+
}
|
|
1937
|
+
function formatPaymentPlanResult(result) {
|
|
1938
|
+
const lines = ["## Payment Plan", ""];
|
|
1939
|
+
if (result.viable) {
|
|
1940
|
+
lines.push(`**Viable:** Yes`);
|
|
1941
|
+
if (result.recommendedNetwork) {
|
|
1942
|
+
lines.push(`**Recommended Network:** ${result.recommendedNetwork}`);
|
|
1943
|
+
}
|
|
1944
|
+
if (result.availableBalance) {
|
|
1945
|
+
lines.push(`**Available Balance:** ${result.availableBalance}`);
|
|
1946
|
+
}
|
|
1947
|
+
} else {
|
|
1948
|
+
lines.push(`**Viable:** No`);
|
|
1949
|
+
if (result.reason) {
|
|
1950
|
+
lines.push(`**Reason:** ${result.reason}`);
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
if (result.bridgeRequired && result.bridgeDetails) {
|
|
1954
|
+
lines.push("");
|
|
1955
|
+
lines.push("### Bridge Required");
|
|
1956
|
+
lines.push(`- **From:** ${result.bridgeDetails.fromChain}`);
|
|
1957
|
+
lines.push(`- **To:** ${result.bridgeDetails.toChain}`);
|
|
1958
|
+
lines.push(`- **Amount:** ${result.bridgeDetails.amount}`);
|
|
1959
|
+
lines.push(`- **Estimated Fee:** ${result.bridgeDetails.estimatedFee}`);
|
|
1960
|
+
}
|
|
1961
|
+
if (result.balances.length > 0) {
|
|
1962
|
+
lines.push("");
|
|
1963
|
+
lines.push("### Chain Balances");
|
|
1964
|
+
lines.push("| Chain | USDT0 | USDC |");
|
|
1965
|
+
lines.push("|-------|-------|------|");
|
|
1966
|
+
for (const b of result.balances) {
|
|
1967
|
+
lines.push(`| ${b.chain} | ${b.usdt0} | ${b.usdc} |`);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
return lines.join("\n");
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1482
1973
|
// src/tools/index.ts
|
|
1483
1974
|
var TOOL_DEFINITIONS = {
|
|
1484
1975
|
"t402/getBalance": {
|
|
@@ -1790,6 +2281,8 @@ var T402McpServer = class {
|
|
|
1790
2281
|
__publicField(this, "server");
|
|
1791
2282
|
__publicField(this, "config");
|
|
1792
2283
|
__publicField(this, "wdk", null);
|
|
2284
|
+
/** TON MCP bridge configuration */
|
|
2285
|
+
__publicField(this, "tonBridgeConfig", null);
|
|
1793
2286
|
this.config = config;
|
|
1794
2287
|
this.server = new import_server.Server(
|
|
1795
2288
|
{
|
|
@@ -1823,13 +2316,27 @@ var T402McpServer = class {
|
|
|
1823
2316
|
}
|
|
1824
2317
|
}
|
|
1825
2318
|
/**
|
|
1826
|
-
*
|
|
2319
|
+
* Register TON bridge tools
|
|
2320
|
+
*
|
|
2321
|
+
* Enables AI agents to use @ton/mcp tools through the t402 MCP server.
|
|
2322
|
+
*/
|
|
2323
|
+
registerTonBridge(config) {
|
|
2324
|
+
this.tonBridgeConfig = config;
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Get all tool definitions (base + WDK if configured + unified if enabled + TON bridge if registered)
|
|
1827
2328
|
*/
|
|
1828
2329
|
getToolDefinitions() {
|
|
1829
2330
|
const tools = { ...TOOL_DEFINITIONS };
|
|
1830
2331
|
if (this.wdk || this.config.demoMode) {
|
|
1831
2332
|
Object.assign(tools, WDK_TOOL_DEFINITIONS);
|
|
1832
2333
|
}
|
|
2334
|
+
if (this.config.unifiedMode && (this.wdk || this.config.demoMode)) {
|
|
2335
|
+
Object.assign(tools, UNIFIED_TOOL_DEFINITIONS);
|
|
2336
|
+
}
|
|
2337
|
+
if (this.tonBridgeConfig) {
|
|
2338
|
+
Object.assign(tools, TON_BRIDGE_TOOLS);
|
|
2339
|
+
}
|
|
1833
2340
|
return tools;
|
|
1834
2341
|
}
|
|
1835
2342
|
/**
|
|
@@ -1868,6 +2375,18 @@ var T402McpServer = class {
|
|
|
1868
2375
|
return await this.handleWdkSwap(args);
|
|
1869
2376
|
case "t402/autoPay":
|
|
1870
2377
|
return await this.handleAutoPay(args);
|
|
2378
|
+
// Unified tools
|
|
2379
|
+
case "t402/smartPay":
|
|
2380
|
+
return await this.handleSmartPay(args);
|
|
2381
|
+
case "t402/paymentPlan":
|
|
2382
|
+
return await this.handlePaymentPlan(args);
|
|
2383
|
+
// TON bridge tools
|
|
2384
|
+
case "ton/getBalance":
|
|
2385
|
+
case "ton/transfer":
|
|
2386
|
+
case "ton/getJettonBalance":
|
|
2387
|
+
case "ton/swapJettons":
|
|
2388
|
+
case "ton/getTransactionStatus":
|
|
2389
|
+
return await this.handleTonBridgeTool(name, args);
|
|
1871
2390
|
default:
|
|
1872
2391
|
throw new Error(`Unknown tool: ${name}`);
|
|
1873
2392
|
}
|
|
@@ -2065,6 +2584,37 @@ var T402McpServer = class {
|
|
|
2065
2584
|
content: [{ type: "text", text: formatAutoPayResult(result) }]
|
|
2066
2585
|
};
|
|
2067
2586
|
}
|
|
2587
|
+
// ---- Unified Tool Handlers ----
|
|
2588
|
+
/**
|
|
2589
|
+
* Handle t402/smartPay
|
|
2590
|
+
*/
|
|
2591
|
+
async handleSmartPay(args) {
|
|
2592
|
+
const input = smartPayInputSchema.parse(args);
|
|
2593
|
+
const result = this.config.demoMode || !this.wdk ? executeSmartPayDemo(input) : await executeSmartPay(input, this.wdk);
|
|
2594
|
+
return {
|
|
2595
|
+
content: [{ type: "text", text: formatSmartPayResult(result) }]
|
|
2596
|
+
};
|
|
2597
|
+
}
|
|
2598
|
+
/**
|
|
2599
|
+
* Handle t402/paymentPlan
|
|
2600
|
+
*/
|
|
2601
|
+
async handlePaymentPlan(args) {
|
|
2602
|
+
const input = paymentPlanInputSchema.parse(args);
|
|
2603
|
+
const result = this.config.demoMode || !this.wdk ? executePaymentPlanDemo(input) : await executePaymentPlan(input, this.wdk);
|
|
2604
|
+
return {
|
|
2605
|
+
content: [{ type: "text", text: formatPaymentPlanResult(result) }]
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2608
|
+
// ---- TON Bridge Tool Handler ----
|
|
2609
|
+
/**
|
|
2610
|
+
* Handle TON bridge tool calls
|
|
2611
|
+
*/
|
|
2612
|
+
async handleTonBridgeTool(name, args) {
|
|
2613
|
+
if (!this.tonBridgeConfig) {
|
|
2614
|
+
throw new Error("TON bridge not configured. Call registerTonBridge() to enable TON tools.");
|
|
2615
|
+
}
|
|
2616
|
+
return executeTonBridgeTool(name, args ?? {}, this.tonBridgeConfig);
|
|
2617
|
+
}
|
|
2068
2618
|
/**
|
|
2069
2619
|
* Start the server using stdio transport
|
|
2070
2620
|
*/
|
|
@@ -2098,6 +2648,9 @@ function loadConfigFromEnv() {
|
|
|
2098
2648
|
if (process.env.T402_WDK_CHAINS) {
|
|
2099
2649
|
config.wdkChains = process.env.T402_WDK_CHAINS.split(",").map((c) => c.trim());
|
|
2100
2650
|
}
|
|
2651
|
+
if (process.env.T402_UNIFIED_MODE === "true") {
|
|
2652
|
+
config.unifiedMode = true;
|
|
2653
|
+
}
|
|
2101
2654
|
const rpcUrls = {};
|
|
2102
2655
|
const networks = [
|
|
2103
2656
|
"ethereum",
|
|
@@ -2119,6 +2672,12 @@ function loadConfigFromEnv() {
|
|
|
2119
2672
|
if (Object.keys(rpcUrls).length > 0) {
|
|
2120
2673
|
config.rpcUrls = rpcUrls;
|
|
2121
2674
|
}
|
|
2675
|
+
if (process.env.T402_TON_MCP_ENDPOINT) {
|
|
2676
|
+
config.tonMcpEndpoint = process.env.T402_TON_MCP_ENDPOINT;
|
|
2677
|
+
}
|
|
2678
|
+
if (process.env.T402_TON_API_KEY) {
|
|
2679
|
+
config.tonApiKey = process.env.T402_TON_API_KEY;
|
|
2680
|
+
}
|
|
2122
2681
|
return config;
|
|
2123
2682
|
}
|
|
2124
2683
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -2131,6 +2690,7 @@ function loadConfigFromEnv() {
|
|
|
2131
2690
|
NATIVE_SYMBOLS,
|
|
2132
2691
|
T402McpServer,
|
|
2133
2692
|
TOOL_DEFINITIONS,
|
|
2693
|
+
UNIFIED_TOOL_DEFINITIONS,
|
|
2134
2694
|
USDC_ADDRESSES,
|
|
2135
2695
|
USDT0_ADDRESSES,
|
|
2136
2696
|
USDT_ADDRESSES,
|
|
@@ -2142,12 +2702,18 @@ function loadConfigFromEnv() {
|
|
|
2142
2702
|
executeGetBridgeFee,
|
|
2143
2703
|
executePay,
|
|
2144
2704
|
executePayGasless,
|
|
2705
|
+
executePaymentPlan,
|
|
2706
|
+
executePaymentPlanDemo,
|
|
2707
|
+
executeSmartPay,
|
|
2708
|
+
executeSmartPayDemo,
|
|
2145
2709
|
formatAllBalancesResult,
|
|
2146
2710
|
formatBalanceResult,
|
|
2147
2711
|
formatBridgeFeeResult,
|
|
2148
2712
|
formatBridgeResult,
|
|
2149
2713
|
formatGaslessPaymentResult,
|
|
2714
|
+
formatPaymentPlanResult,
|
|
2150
2715
|
formatPaymentResult,
|
|
2716
|
+
formatSmartPayResult,
|
|
2151
2717
|
formatTokenAmount,
|
|
2152
2718
|
getAllBalancesInputSchema,
|
|
2153
2719
|
getBalanceInputSchema,
|
|
@@ -2159,6 +2725,8 @@ function loadConfigFromEnv() {
|
|
|
2159
2725
|
parseTokenAmount,
|
|
2160
2726
|
payGaslessInputSchema,
|
|
2161
2727
|
payInputSchema,
|
|
2728
|
+
paymentPlanInputSchema,
|
|
2729
|
+
smartPayInputSchema,
|
|
2162
2730
|
supportsToken
|
|
2163
2731
|
});
|
|
2164
2732
|
//# sourceMappingURL=index.js.map
|