@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/tools/index.js
CHANGED
|
@@ -38,30 +38,53 @@ __export(tools_exports, {
|
|
|
38
38
|
WDK_TOOL_DEFINITIONS: () => WDK_TOOL_DEFINITIONS,
|
|
39
39
|
autoPayInputSchema: () => autoPayInputSchema,
|
|
40
40
|
bridgeInputSchema: () => bridgeInputSchema,
|
|
41
|
+
clearPriceCache: () => clearPriceCache,
|
|
42
|
+
clearQuoteStore: () => clearQuoteStore,
|
|
43
|
+
compareNetworkFeesInputSchema: () => compareNetworkFeesInputSchema,
|
|
44
|
+
createQuote: () => createQuote,
|
|
41
45
|
createTonBridgeToolSet: () => createTonBridgeToolSet,
|
|
46
|
+
deleteQuote: () => deleteQuote,
|
|
42
47
|
erc8004CheckReputationInputSchema: () => erc8004CheckReputationInputSchema,
|
|
43
48
|
erc8004ResolveAgentInputSchema: () => erc8004ResolveAgentInputSchema,
|
|
44
49
|
erc8004VerifyWalletInputSchema: () => erc8004VerifyWalletInputSchema,
|
|
50
|
+
estimatePaymentFeeInputSchema: () => estimatePaymentFeeInputSchema,
|
|
45
51
|
executeAutoPay: () => executeAutoPay,
|
|
46
52
|
executeAutoPayDemo: () => executeAutoPayDemo,
|
|
47
53
|
executeBridge: () => executeBridge,
|
|
54
|
+
executeBridgeFromQuoteInputSchema: () => executeBridgeFromQuoteInputSchema,
|
|
55
|
+
executeCompareNetworkFees: () => executeCompareNetworkFees,
|
|
48
56
|
executeErc8004CheckReputation: () => executeErc8004CheckReputation,
|
|
49
57
|
executeErc8004ResolveAgent: () => executeErc8004ResolveAgent,
|
|
50
58
|
executeErc8004VerifyWallet: () => executeErc8004VerifyWallet,
|
|
59
|
+
executeEstimatePaymentFee: () => executeEstimatePaymentFee,
|
|
60
|
+
executeExecuteBridgeFromQuote: () => executeExecuteBridgeFromQuote,
|
|
61
|
+
executeExecuteBridgeFromQuoteDemo: () => executeExecuteBridgeFromQuoteDemo,
|
|
51
62
|
executeGetAllBalances: () => executeGetAllBalances,
|
|
52
63
|
executeGetBalance: () => executeGetBalance,
|
|
53
64
|
executeGetBridgeFee: () => executeGetBridgeFee,
|
|
65
|
+
executeGetGasPrice: () => executeGetGasPrice,
|
|
66
|
+
executeGetHistoricalPrice: () => executeGetHistoricalPrice,
|
|
67
|
+
executeGetTokenPrice: () => executeGetTokenPrice,
|
|
68
|
+
executeGetTransferHistory: () => executeGetTransferHistory,
|
|
54
69
|
executePay: () => executePay,
|
|
55
70
|
executePayGasless: () => executePayGasless,
|
|
56
71
|
executePaymentPlan: () => executePaymentPlan,
|
|
57
72
|
executePaymentPlanDemo: () => executePaymentPlanDemo,
|
|
73
|
+
executeQuoteBridge: () => executeQuoteBridge,
|
|
74
|
+
executeQuoteBridgeDemo: () => executeQuoteBridgeDemo,
|
|
75
|
+
executeSignMessage: () => executeSignMessage,
|
|
58
76
|
executeSmartPay: () => executeSmartPay,
|
|
59
77
|
executeSmartPayDemo: () => executeSmartPayDemo,
|
|
60
78
|
executeTonBridgeTool: () => executeTonBridgeTool,
|
|
79
|
+
executeVerifySignature: () => executeVerifySignature,
|
|
80
|
+
executeWdkExecuteSwap: () => executeWdkExecuteSwap,
|
|
81
|
+
executeWdkExecuteSwapDemo: () => executeWdkExecuteSwapDemo,
|
|
61
82
|
executeWdkGetBalances: () => executeWdkGetBalances,
|
|
62
83
|
executeWdkGetBalancesDemo: () => executeWdkGetBalancesDemo,
|
|
63
84
|
executeWdkGetWallet: () => executeWdkGetWallet,
|
|
64
85
|
executeWdkGetWalletDemo: () => executeWdkGetWalletDemo,
|
|
86
|
+
executeWdkQuoteSwap: () => executeWdkQuoteSwap,
|
|
87
|
+
executeWdkQuoteSwapDemo: () => executeWdkQuoteSwapDemo,
|
|
65
88
|
executeWdkSwap: () => executeWdkSwap,
|
|
66
89
|
executeWdkSwapDemo: () => executeWdkSwapDemo,
|
|
67
90
|
executeWdkTransfer: () => executeWdkTransfer,
|
|
@@ -70,14 +93,26 @@ __export(tools_exports, {
|
|
|
70
93
|
formatAutoPayResult: () => formatAutoPayResult,
|
|
71
94
|
formatBalanceResult: () => formatBalanceResult,
|
|
72
95
|
formatBridgeFeeResult: () => formatBridgeFeeResult,
|
|
96
|
+
formatBridgeQuoteResult: () => formatBridgeQuoteResult,
|
|
73
97
|
formatBridgeResult: () => formatBridgeResult,
|
|
74
98
|
formatErc8004CheckReputationResult: () => formatErc8004CheckReputationResult,
|
|
75
99
|
formatErc8004ResolveAgentResult: () => formatErc8004ResolveAgentResult,
|
|
76
100
|
formatErc8004VerifyWalletResult: () => formatErc8004VerifyWalletResult,
|
|
101
|
+
formatExecuteBridgeFromQuoteResult: () => formatBridgeResult,
|
|
102
|
+
formatExecuteSwapResult: () => formatExecuteSwapResult,
|
|
103
|
+
formatGasPriceResult: () => formatGasPriceResult,
|
|
77
104
|
formatGaslessPaymentResult: () => formatGaslessPaymentResult,
|
|
105
|
+
formatHistoricalPriceResult: () => formatHistoricalPriceResult,
|
|
106
|
+
formatNetworkFeeComparison: () => formatNetworkFeeComparison,
|
|
107
|
+
formatPaymentFeeEstimate: () => formatPaymentFeeEstimate,
|
|
78
108
|
formatPaymentPlanResult: () => formatPaymentPlanResult,
|
|
79
109
|
formatPaymentResult: () => formatPaymentResult,
|
|
110
|
+
formatSignMessageResult: () => formatSignMessageResult,
|
|
80
111
|
formatSmartPayResult: () => formatSmartPayResult,
|
|
112
|
+
formatSwapQuoteResult: () => formatSwapQuoteResult,
|
|
113
|
+
formatTokenPriceResult: () => formatTokenPriceResult,
|
|
114
|
+
formatTransferHistoryResult: () => formatTransferHistoryResult,
|
|
115
|
+
formatVerifySignatureResult: () => formatVerifySignatureResult,
|
|
81
116
|
formatWdkBalancesResult: () => formatWdkBalancesResult,
|
|
82
117
|
formatWdkSwapResult: () => formatWdkSwapResult,
|
|
83
118
|
formatWdkTransferResult: () => formatWdkTransferResult,
|
|
@@ -85,12 +120,24 @@ __export(tools_exports, {
|
|
|
85
120
|
getAllBalancesInputSchema: () => getAllBalancesInputSchema,
|
|
86
121
|
getBalanceInputSchema: () => getBalanceInputSchema,
|
|
87
122
|
getBridgeFeeInputSchema: () => getBridgeFeeInputSchema,
|
|
123
|
+
getGasPriceInputSchema: () => getGasPriceInputSchema,
|
|
124
|
+
getHistoricalPriceInputSchema: () => getHistoricalPriceInputSchema,
|
|
125
|
+
getQuote: () => getQuote,
|
|
126
|
+
getTokenPriceInputSchema: () => getTokenPriceInputSchema,
|
|
127
|
+
getTokenPrices: () => getTokenPrices,
|
|
128
|
+
getTokenPricesDemo: () => getTokenPricesDemo,
|
|
129
|
+
getTransferHistoryInputSchema: () => getTransferHistoryInputSchema,
|
|
88
130
|
payGaslessInputSchema: () => payGaslessInputSchema,
|
|
89
131
|
payInputSchema: () => payInputSchema,
|
|
90
132
|
paymentPlanInputSchema: () => paymentPlanInputSchema,
|
|
133
|
+
quoteBridgeInputSchema: () => quoteBridgeInputSchema,
|
|
134
|
+
signMessageInputSchema: () => signMessageInputSchema,
|
|
91
135
|
smartPayInputSchema: () => smartPayInputSchema,
|
|
136
|
+
verifySignatureInputSchema: () => verifySignatureInputSchema,
|
|
137
|
+
wdkExecuteSwapInputSchema: () => wdkExecuteSwapInputSchema,
|
|
92
138
|
wdkGetBalancesInputSchema: () => wdkGetBalancesInputSchema,
|
|
93
139
|
wdkGetWalletInputSchema: () => wdkGetWalletInputSchema,
|
|
140
|
+
wdkQuoteSwapInputSchema: () => wdkQuoteSwapInputSchema,
|
|
94
141
|
wdkSwapInputSchema: () => wdkSwapInputSchema,
|
|
95
142
|
wdkTransferInputSchema: () => wdkTransferInputSchema
|
|
96
143
|
});
|
|
@@ -518,7 +565,8 @@ var payInputSchema = import_zod3.z.object({
|
|
|
518
565
|
"berachain",
|
|
519
566
|
"unichain"
|
|
520
567
|
]).describe("Network to execute payment on"),
|
|
521
|
-
memo: import_zod3.z.string().optional().describe("Optional memo/reference for the payment")
|
|
568
|
+
memo: import_zod3.z.string().optional().describe("Optional memo/reference for the payment"),
|
|
569
|
+
confirmed: import_zod3.z.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
522
570
|
});
|
|
523
571
|
function getViemChain2(network) {
|
|
524
572
|
switch (network) {
|
|
@@ -547,6 +595,13 @@ function getViemChain2(network) {
|
|
|
547
595
|
async function executePay(input, options) {
|
|
548
596
|
const { to, amount, token, network, memo: _memo } = input;
|
|
549
597
|
const { privateKey, rpcUrl, demoMode } = options;
|
|
598
|
+
if (!input.confirmed) {
|
|
599
|
+
return {
|
|
600
|
+
needsConfirmation: true,
|
|
601
|
+
summary: `Send ${amount} ${token} on ${network} to ${to}`,
|
|
602
|
+
details: { to, amount, token, network }
|
|
603
|
+
};
|
|
604
|
+
}
|
|
550
605
|
if (!supportsToken(network, token)) {
|
|
551
606
|
throw new Error(`Token ${token} is not supported on ${network}`);
|
|
552
607
|
}
|
|
@@ -631,7 +686,8 @@ var payGaslessInputSchema = import_zod4.z.object({
|
|
|
631
686
|
to: import_zod4.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address"),
|
|
632
687
|
amount: import_zod4.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to pay (e.g., '10.50' for 10.50 USDC)"),
|
|
633
688
|
token: import_zod4.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to use for payment"),
|
|
634
|
-
network: import_zod4.z.enum(["ethereum", "base", "arbitrum", "optimism", "polygon", "avalanche"]).describe("Network to execute gasless payment on (must support ERC-4337)")
|
|
689
|
+
network: import_zod4.z.enum(["ethereum", "base", "arbitrum", "optimism", "polygon", "avalanche"]).describe("Network to execute gasless payment on (must support ERC-4337)"),
|
|
690
|
+
confirmed: import_zod4.z.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
635
691
|
});
|
|
636
692
|
var GASLESS_SUPPORTED_NETWORKS = [
|
|
637
693
|
"ethereum",
|
|
@@ -668,6 +724,13 @@ function getViemChain3(network) {
|
|
|
668
724
|
async function executePayGasless(input, options) {
|
|
669
725
|
const { to, amount, token, network } = input;
|
|
670
726
|
const { privateKey, bundlerUrl, paymasterUrl: _paymasterUrl, rpcUrl, demoMode } = options;
|
|
727
|
+
if (!input.confirmed) {
|
|
728
|
+
return {
|
|
729
|
+
needsConfirmation: true,
|
|
730
|
+
summary: `Send ${amount} ${token} gasless on ${network} to ${to}`,
|
|
731
|
+
details: { to, amount, token, network }
|
|
732
|
+
};
|
|
733
|
+
}
|
|
671
734
|
if (!GASLESS_SUPPORTED_NETWORKS.includes(network)) {
|
|
672
735
|
throw new Error(
|
|
673
736
|
`Network ${network} does not support ERC-4337 gasless transactions. Supported: ${GASLESS_SUPPORTED_NETWORKS.join(", ")}`
|
|
@@ -953,7 +1016,8 @@ var bridgeInputSchema = import_zod6.z.object({
|
|
|
953
1016
|
fromChain: import_zod6.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Source chain to bridge from"),
|
|
954
1017
|
toChain: import_zod6.z.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Destination chain to bridge to"),
|
|
955
1018
|
amount: import_zod6.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"),
|
|
956
|
-
recipient: import_zod6.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain")
|
|
1019
|
+
recipient: import_zod6.z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain"),
|
|
1020
|
+
confirmed: import_zod6.z.boolean().optional().describe("Set to true to confirm and execute this bridge")
|
|
957
1021
|
});
|
|
958
1022
|
var LAYERZERO_ENDPOINT_IDS2 = {
|
|
959
1023
|
ethereum: 30101,
|
|
@@ -1080,6 +1144,13 @@ function addressToBytes322(address) {
|
|
|
1080
1144
|
async function executeBridge(input, options) {
|
|
1081
1145
|
const { fromChain, toChain, amount, recipient } = input;
|
|
1082
1146
|
const { privateKey, rpcUrl, demoMode, slippageTolerance = 0.5 } = options;
|
|
1147
|
+
if (!input.confirmed) {
|
|
1148
|
+
return {
|
|
1149
|
+
needsConfirmation: true,
|
|
1150
|
+
summary: `Bridge ${amount} USDT0 from ${fromChain} to ${toChain}`,
|
|
1151
|
+
details: { fromChain, toChain, amount, recipient }
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1083
1154
|
if (fromChain === toChain) {
|
|
1084
1155
|
throw new Error("Source and destination chains must be different");
|
|
1085
1156
|
}
|
|
@@ -1209,10 +1280,10 @@ var import_zod7 = require("zod");
|
|
|
1209
1280
|
var wdkGetWalletInputSchema = import_zod7.z.object({});
|
|
1210
1281
|
async function executeWdkGetWallet(_input, wdk) {
|
|
1211
1282
|
const signer = await wdk.getSigner("ethereum");
|
|
1212
|
-
const
|
|
1283
|
+
const chains10 = wdk.getConfiguredChains();
|
|
1213
1284
|
return {
|
|
1214
1285
|
evmAddress: signer.address,
|
|
1215
|
-
chains:
|
|
1286
|
+
chains: chains10.length > 0 ? chains10 : ["ethereum"]
|
|
1216
1287
|
};
|
|
1217
1288
|
}
|
|
1218
1289
|
function executeWdkGetWalletDemo() {
|
|
@@ -1244,14 +1315,14 @@ function findTokenFormatted(tokens, symbol) {
|
|
|
1244
1315
|
}
|
|
1245
1316
|
async function executeWdkGetBalances(input, wdk) {
|
|
1246
1317
|
const balances = await wdk.getAggregatedBalances();
|
|
1247
|
-
const
|
|
1318
|
+
const chains10 = balances.chains.filter((c) => !input.chains || input.chains.includes(c.chain)).map((c) => ({
|
|
1248
1319
|
chain: c.chain,
|
|
1249
1320
|
usdt0: findTokenFormatted(c.tokens, "USDT0"),
|
|
1250
1321
|
usdc: findTokenFormatted(c.tokens, "USDC"),
|
|
1251
1322
|
native: (0, import_viem6.formatUnits)(c.native, 18)
|
|
1252
1323
|
}));
|
|
1253
1324
|
return {
|
|
1254
|
-
chains:
|
|
1325
|
+
chains: chains10,
|
|
1255
1326
|
totalUsdt0: (0, import_viem6.formatUnits)(balances.totalUsdt0, 6),
|
|
1256
1327
|
totalUsdc: (0, import_viem6.formatUnits)(balances.totalUsdc, 6)
|
|
1257
1328
|
};
|
|
@@ -1293,9 +1364,17 @@ var wdkTransferInputSchema = import_zod9.z.object({
|
|
|
1293
1364
|
to: import_zod9.z.string().describe("Recipient address"),
|
|
1294
1365
|
amount: import_zod9.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to send (e.g., '10.50')"),
|
|
1295
1366
|
token: import_zod9.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to transfer"),
|
|
1296
|
-
chain: import_zod9.z.string().describe('Chain to execute transfer on (e.g., "ethereum", "arbitrum")')
|
|
1367
|
+
chain: import_zod9.z.string().describe('Chain to execute transfer on (e.g., "ethereum", "arbitrum")'),
|
|
1368
|
+
confirmed: import_zod9.z.boolean().optional().describe("Set to true to confirm and execute this transfer")
|
|
1297
1369
|
});
|
|
1298
1370
|
async function executeWdkTransfer(input, wdk) {
|
|
1371
|
+
if (!input.confirmed) {
|
|
1372
|
+
return {
|
|
1373
|
+
needsConfirmation: true,
|
|
1374
|
+
summary: `Transfer ${input.amount} ${input.token} on ${input.chain} to ${input.to}`,
|
|
1375
|
+
details: { to: input.to, amount: input.amount, token: input.token, chain: input.chain }
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1299
1378
|
const signer = await wdk.getSigner(input.chain);
|
|
1300
1379
|
const result = await signer.sendTransaction({
|
|
1301
1380
|
to: input.to
|
|
@@ -1312,6 +1391,13 @@ async function executeWdkTransfer(input, wdk) {
|
|
|
1312
1391
|
};
|
|
1313
1392
|
}
|
|
1314
1393
|
function executeWdkTransferDemo(input) {
|
|
1394
|
+
if (!input.confirmed) {
|
|
1395
|
+
return {
|
|
1396
|
+
needsConfirmation: true,
|
|
1397
|
+
summary: `Transfer ${input.amount} ${input.token} on ${input.chain} to ${input.to}`,
|
|
1398
|
+
details: { to: input.to, amount: input.amount, token: input.token, chain: input.chain }
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
1315
1401
|
const demoTxHash = "0xdemo" + Math.random().toString(16).slice(2, 10);
|
|
1316
1402
|
return {
|
|
1317
1403
|
txHash: demoTxHash,
|
|
@@ -1341,9 +1427,22 @@ var wdkSwapInputSchema = import_zod10.z.object({
|
|
|
1341
1427
|
fromToken: import_zod10.z.string().describe('Token to swap from (e.g., "ETH", "USDC")'),
|
|
1342
1428
|
toToken: import_zod10.z.string().describe('Token to swap to (e.g., "USDT0", "USDC")'),
|
|
1343
1429
|
amount: import_zod10.z.string().regex(/^\d+(\.\d+)?$/).describe("Amount to swap (e.g., '1.0')"),
|
|
1344
|
-
chain: import_zod10.z.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")')
|
|
1430
|
+
chain: import_zod10.z.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")'),
|
|
1431
|
+
confirmed: import_zod10.z.boolean().optional().describe("Set to true to confirm and execute this swap")
|
|
1345
1432
|
});
|
|
1346
1433
|
async function executeWdkSwap(input, wdk) {
|
|
1434
|
+
if (!input.confirmed) {
|
|
1435
|
+
return {
|
|
1436
|
+
needsConfirmation: true,
|
|
1437
|
+
summary: `Swap ${input.amount} ${input.fromToken} to ${input.toToken} on ${input.chain}`,
|
|
1438
|
+
details: {
|
|
1439
|
+
fromToken: input.fromToken,
|
|
1440
|
+
toToken: input.toToken,
|
|
1441
|
+
amount: input.amount,
|
|
1442
|
+
chain: input.chain
|
|
1443
|
+
}
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1347
1446
|
const decimals = ["USDC", "USDT", "USDT0"].includes(input.fromToken.toUpperCase()) ? 6 : 18;
|
|
1348
1447
|
const amountBigInt = (0, import_viem7.parseUnits)(input.amount, decimals);
|
|
1349
1448
|
const quote = await wdk.getSwapQuote(input.chain, input.fromToken, amountBigInt);
|
|
@@ -1364,6 +1463,18 @@ async function executeWdkSwap(input, wdk) {
|
|
|
1364
1463
|
};
|
|
1365
1464
|
}
|
|
1366
1465
|
function executeWdkSwapDemo(input) {
|
|
1466
|
+
if (!input.confirmed) {
|
|
1467
|
+
return {
|
|
1468
|
+
needsConfirmation: true,
|
|
1469
|
+
summary: `Swap ${input.amount} ${input.fromToken} to ${input.toToken} on ${input.chain}`,
|
|
1470
|
+
details: {
|
|
1471
|
+
fromToken: input.fromToken,
|
|
1472
|
+
toToken: input.toToken,
|
|
1473
|
+
amount: input.amount,
|
|
1474
|
+
chain: input.chain
|
|
1475
|
+
}
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1367
1478
|
const inputAmount = parseFloat(input.amount);
|
|
1368
1479
|
const outputAmount = (inputAmount * 0.997).toFixed(6);
|
|
1369
1480
|
return {
|
|
@@ -1396,25 +1507,52 @@ var autoPayInputSchema = import_zod11.z.object({
|
|
|
1396
1507
|
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.'),
|
|
1397
1508
|
preferredChain: import_zod11.z.string().optional().describe(
|
|
1398
1509
|
'Preferred chain for payment (e.g., "arbitrum"). If not specified, uses first available.'
|
|
1399
|
-
)
|
|
1510
|
+
),
|
|
1511
|
+
confirmed: import_zod11.z.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
1400
1512
|
});
|
|
1401
1513
|
async function executeAutoPay(input, wdk) {
|
|
1402
|
-
|
|
1514
|
+
if (!input.confirmed) {
|
|
1515
|
+
return {
|
|
1516
|
+
needsConfirmation: true,
|
|
1517
|
+
summary: `Auto-pay for ${input.url}${input.maxAmount ? ` (max ${input.maxAmount})` : ""}`,
|
|
1518
|
+
details: {
|
|
1519
|
+
url: input.url,
|
|
1520
|
+
...input.maxAmount ? { maxAmount: input.maxAmount } : {},
|
|
1521
|
+
...input.preferredChain ? { preferredChain: input.preferredChain } : {}
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
const chains10 = input.preferredChain ? [input.preferredChain] : ["ethereum", "arbitrum", "base"];
|
|
1403
1526
|
const { T402Protocol } = await import("@t402/wdk-protocol");
|
|
1404
|
-
const protocol = await T402Protocol.create(wdk, { chains:
|
|
1405
|
-
|
|
1406
|
-
if (receipt && input.maxAmount) {
|
|
1407
|
-
const paidAmount = parseFloat(receipt.amount) / 1e6;
|
|
1527
|
+
const protocol = await T402Protocol.create(wdk, { chains: chains10 });
|
|
1528
|
+
if (input.maxAmount) {
|
|
1408
1529
|
const maxAmount = parseFloat(input.maxAmount);
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
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
|
+
}
|
|
1416
1553
|
}
|
|
1417
1554
|
}
|
|
1555
|
+
const { response, receipt } = await protocol.fetch(input.url);
|
|
1418
1556
|
const contentType = response.headers.get("content-type") ?? void 0;
|
|
1419
1557
|
let body = "";
|
|
1420
1558
|
try {
|
|
@@ -1439,6 +1577,17 @@ async function executeAutoPay(input, wdk) {
|
|
|
1439
1577
|
};
|
|
1440
1578
|
}
|
|
1441
1579
|
function executeAutoPayDemo(input) {
|
|
1580
|
+
if (!input.confirmed) {
|
|
1581
|
+
return {
|
|
1582
|
+
needsConfirmation: true,
|
|
1583
|
+
summary: `Auto-pay for ${input.url}${input.maxAmount ? ` (max ${input.maxAmount})` : ""}`,
|
|
1584
|
+
details: {
|
|
1585
|
+
url: input.url,
|
|
1586
|
+
...input.maxAmount ? { maxAmount: input.maxAmount } : {},
|
|
1587
|
+
...input.preferredChain ? { preferredChain: input.preferredChain } : {}
|
|
1588
|
+
}
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1442
1591
|
return {
|
|
1443
1592
|
success: true,
|
|
1444
1593
|
statusCode: 200,
|
|
@@ -1890,175 +2039,1307 @@ function formatErc8004VerifyWalletResult(result) {
|
|
|
1890
2039
|
return lines.join("\n");
|
|
1891
2040
|
}
|
|
1892
2041
|
|
|
1893
|
-
// src/tools/
|
|
2042
|
+
// src/tools/priceService.ts
|
|
2043
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2044
|
+
var COINGECKO_API = "https://api.coingecko.com/api/v3/simple/price";
|
|
2045
|
+
var TOKEN_TO_COINGECKO_ID = {
|
|
2046
|
+
ETH: "ethereum",
|
|
2047
|
+
MATIC: "matic-network",
|
|
2048
|
+
AVAX: "avalanche-2",
|
|
2049
|
+
BERA: "berachain-bera",
|
|
2050
|
+
USDC: "usd-coin",
|
|
2051
|
+
USDT: "tether",
|
|
2052
|
+
USDT0: "tether"
|
|
2053
|
+
};
|
|
2054
|
+
var cache = /* @__PURE__ */ new Map();
|
|
2055
|
+
async function getTokenPrices(tokens, currency = "usd") {
|
|
2056
|
+
const cacheKey = `${currency}:${tokens.sort().join(",")}`;
|
|
2057
|
+
const cached = cache.get(cacheKey);
|
|
2058
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
|
|
2059
|
+
return cached.prices;
|
|
2060
|
+
}
|
|
2061
|
+
const coinIds = /* @__PURE__ */ new Set();
|
|
2062
|
+
const tokenToCoinId = /* @__PURE__ */ new Map();
|
|
2063
|
+
for (const token of tokens) {
|
|
2064
|
+
const coinId = TOKEN_TO_COINGECKO_ID[token.toUpperCase()] ?? token.toLowerCase();
|
|
2065
|
+
coinIds.add(coinId);
|
|
2066
|
+
tokenToCoinId.set(token.toUpperCase(), coinId);
|
|
2067
|
+
}
|
|
2068
|
+
const url = `${COINGECKO_API}?ids=${[...coinIds].join(",")}&vs_currencies=${currency}`;
|
|
2069
|
+
const response = await fetch(url);
|
|
2070
|
+
if (!response.ok) {
|
|
2071
|
+
throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
|
|
2072
|
+
}
|
|
2073
|
+
const data = await response.json();
|
|
2074
|
+
const prices = {};
|
|
2075
|
+
for (const token of tokens) {
|
|
2076
|
+
const coinId = tokenToCoinId.get(token.toUpperCase()) ?? token.toLowerCase();
|
|
2077
|
+
prices[token.toUpperCase()] = data[coinId]?.[currency] ?? 0;
|
|
2078
|
+
}
|
|
2079
|
+
cache.set(cacheKey, { prices, timestamp: Date.now() });
|
|
2080
|
+
return prices;
|
|
2081
|
+
}
|
|
2082
|
+
function getTokenPricesDemo(tokens) {
|
|
2083
|
+
const demoPrices = {
|
|
2084
|
+
ETH: 3250.42,
|
|
2085
|
+
MATIC: 0.58,
|
|
2086
|
+
AVAX: 24.15,
|
|
2087
|
+
BERA: 3.82,
|
|
2088
|
+
USDC: 1,
|
|
2089
|
+
USDT: 1,
|
|
2090
|
+
USDT0: 1
|
|
2091
|
+
};
|
|
2092
|
+
const prices = {};
|
|
2093
|
+
for (const token of tokens) {
|
|
2094
|
+
prices[token.toUpperCase()] = demoPrices[token.toUpperCase()] ?? 0;
|
|
2095
|
+
}
|
|
2096
|
+
return prices;
|
|
2097
|
+
}
|
|
2098
|
+
function clearPriceCache() {
|
|
2099
|
+
cache.clear();
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
// src/tools/getTokenPrice.ts
|
|
1894
2103
|
var import_zod15 = require("zod");
|
|
1895
|
-
var
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
preferredNetwork: import_zod15.z.string().optional().describe("Preferred network for payment (optional)")
|
|
1899
|
-
});
|
|
1900
|
-
var paymentPlanInputSchema = import_zod15.z.object({
|
|
1901
|
-
paymentRequired: import_zod15.z.object({
|
|
1902
|
-
scheme: import_zod15.z.string().optional(),
|
|
1903
|
-
network: import_zod15.z.string().optional(),
|
|
1904
|
-
maxAmountRequired: import_zod15.z.string().optional(),
|
|
1905
|
-
resource: import_zod15.z.string().optional(),
|
|
1906
|
-
description: import_zod15.z.string().optional(),
|
|
1907
|
-
payTo: import_zod15.z.string().optional(),
|
|
1908
|
-
maxDeadline: import_zod15.z.number().optional()
|
|
1909
|
-
}).passthrough().describe("The 402 PaymentRequired response")
|
|
2104
|
+
var getTokenPriceInputSchema = import_zod15.z.object({
|
|
2105
|
+
tokens: import_zod15.z.array(import_zod15.z.string()).min(1).describe('Token symbols to get prices for (e.g., ["ETH", "MATIC", "USDC"])'),
|
|
2106
|
+
currency: import_zod15.z.string().optional().describe('Target currency (default: "usd"). Supports: usd, eur, gbp, etc.')
|
|
1910
2107
|
});
|
|
1911
|
-
|
|
1912
|
-
"
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
type: "string",
|
|
1925
|
-
description: "Preferred network for payment (optional)"
|
|
1926
|
-
}
|
|
1927
|
-
},
|
|
1928
|
-
required: ["url"]
|
|
1929
|
-
}
|
|
1930
|
-
},
|
|
1931
|
-
"t402/paymentPlan": {
|
|
1932
|
-
name: "t402/paymentPlan",
|
|
1933
|
-
description: "Analyze a 402 response and create an optimal payment plan considering balances across all chains. Returns recommended network, bridge requirements, and balance overview.",
|
|
1934
|
-
inputSchema: {
|
|
1935
|
-
type: "object",
|
|
1936
|
-
properties: {
|
|
1937
|
-
paymentRequired: {
|
|
1938
|
-
type: "object",
|
|
1939
|
-
description: "The 402 PaymentRequired response"
|
|
1940
|
-
}
|
|
1941
|
-
},
|
|
1942
|
-
required: ["paymentRequired"]
|
|
2108
|
+
async function executeGetTokenPrice(input, options) {
|
|
2109
|
+
const currency = input.currency ?? "usd";
|
|
2110
|
+
const prices = options.demoMode ? getTokenPricesDemo(input.tokens) : await getTokenPrices(input.tokens, currency);
|
|
2111
|
+
return { prices, currency };
|
|
2112
|
+
}
|
|
2113
|
+
function formatTokenPriceResult(result) {
|
|
2114
|
+
const lines = ["## Token Prices", ""];
|
|
2115
|
+
const currencyUpper = result.currency.toUpperCase();
|
|
2116
|
+
for (const [token, price] of Object.entries(result.prices)) {
|
|
2117
|
+
if (price > 0) {
|
|
2118
|
+
lines.push(`- **${token}:** ${price.toLocaleString()} ${currencyUpper}`);
|
|
2119
|
+
} else {
|
|
2120
|
+
lines.push(`- **${token}:** Price unavailable`);
|
|
1943
2121
|
}
|
|
1944
2122
|
}
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
2123
|
+
return lines.join("\n");
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
// src/tools/getGasPrice.ts
|
|
2127
|
+
var import_zod16 = require("zod");
|
|
2128
|
+
var import_viem9 = require("viem");
|
|
2129
|
+
var chains7 = __toESM(require("viem/chains"));
|
|
2130
|
+
var getGasPriceInputSchema = import_zod16.z.object({
|
|
2131
|
+
network: import_zod16.z.enum([
|
|
2132
|
+
"ethereum",
|
|
2133
|
+
"base",
|
|
2134
|
+
"arbitrum",
|
|
2135
|
+
"optimism",
|
|
2136
|
+
"polygon",
|
|
2137
|
+
"avalanche",
|
|
2138
|
+
"ink",
|
|
2139
|
+
"berachain",
|
|
2140
|
+
"unichain"
|
|
2141
|
+
]).describe("Blockchain network to check gas price on")
|
|
2142
|
+
});
|
|
2143
|
+
function getViemChain6(network) {
|
|
2144
|
+
switch (network) {
|
|
2145
|
+
case "ethereum":
|
|
2146
|
+
return chains7.mainnet;
|
|
2147
|
+
case "base":
|
|
2148
|
+
return chains7.base;
|
|
2149
|
+
case "arbitrum":
|
|
2150
|
+
return chains7.arbitrum;
|
|
2151
|
+
case "optimism":
|
|
2152
|
+
return chains7.optimism;
|
|
2153
|
+
case "polygon":
|
|
2154
|
+
return chains7.polygon;
|
|
2155
|
+
case "avalanche":
|
|
2156
|
+
return chains7.avalanche;
|
|
2157
|
+
case "ink":
|
|
2158
|
+
return chains7.ink;
|
|
2159
|
+
case "berachain":
|
|
2160
|
+
return chains7.berachain;
|
|
2161
|
+
case "unichain":
|
|
2162
|
+
return chains7.unichain;
|
|
2163
|
+
default:
|
|
2164
|
+
return chains7.mainnet;
|
|
1968
2165
|
}
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2166
|
+
}
|
|
2167
|
+
async function executeGetGasPrice(input, options) {
|
|
2168
|
+
const { network } = input;
|
|
2169
|
+
if (options.demoMode) {
|
|
2170
|
+
const demoGasPrices = {
|
|
2171
|
+
ethereum: 25000000000n,
|
|
2172
|
+
// 25 gwei
|
|
2173
|
+
base: 50000000n,
|
|
2174
|
+
// 0.05 gwei
|
|
2175
|
+
arbitrum: 100000000n,
|
|
2176
|
+
// 0.1 gwei
|
|
2177
|
+
optimism: 50000000n,
|
|
2178
|
+
// 0.05 gwei
|
|
2179
|
+
polygon: 30000000000n,
|
|
2180
|
+
// 30 gwei
|
|
2181
|
+
avalanche: 25000000000n,
|
|
2182
|
+
// 25 nAVAX
|
|
2183
|
+
ink: 50000000n,
|
|
2184
|
+
// 0.05 gwei
|
|
2185
|
+
berachain: 1000000000n,
|
|
2186
|
+
// 1 gwei
|
|
2187
|
+
unichain: 50000000n
|
|
2188
|
+
// 0.05 gwei
|
|
2189
|
+
};
|
|
2190
|
+
const gasPrice2 = demoGasPrices[network] ?? 1000000000n;
|
|
2191
|
+
return {
|
|
2192
|
+
network,
|
|
2193
|
+
gasPriceWei: gasPrice2.toString(),
|
|
2194
|
+
gasPriceGwei: (0, import_viem9.formatGwei)(gasPrice2),
|
|
2195
|
+
nativeSymbol: NATIVE_SYMBOLS[network]
|
|
2196
|
+
};
|
|
1978
2197
|
}
|
|
2198
|
+
const chain = getViemChain6(network);
|
|
2199
|
+
const transport = (0, import_viem9.http)(options.rpcUrl ?? DEFAULT_RPC_URLS[network]);
|
|
2200
|
+
const client = (0, import_viem9.createPublicClient)({ chain, transport });
|
|
2201
|
+
const gasPrice = await client.getGasPrice();
|
|
1979
2202
|
return {
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
steps,
|
|
1985
|
-
payment: receipt ? {
|
|
1986
|
-
network: receipt.network,
|
|
1987
|
-
scheme: receipt.scheme,
|
|
1988
|
-
amount: receipt.amount,
|
|
1989
|
-
payTo: receipt.payTo
|
|
1990
|
-
} : void 0
|
|
2203
|
+
network,
|
|
2204
|
+
gasPriceWei: gasPrice.toString(),
|
|
2205
|
+
gasPriceGwei: (0, import_viem9.formatGwei)(gasPrice),
|
|
2206
|
+
nativeSymbol: NATIVE_SYMBOLS[network]
|
|
1991
2207
|
};
|
|
1992
2208
|
}
|
|
1993
|
-
function
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2209
|
+
function formatGasPriceResult(result) {
|
|
2210
|
+
return [
|
|
2211
|
+
"## Gas Price",
|
|
2212
|
+
"",
|
|
2213
|
+
`- **Network:** ${result.network}`,
|
|
2214
|
+
`- **Gas Price:** ${result.gasPriceGwei} gwei`,
|
|
2215
|
+
`- **Native Token:** ${result.nativeSymbol}`
|
|
2216
|
+
].join("\n");
|
|
2217
|
+
}
|
|
1999
2218
|
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2219
|
+
// src/tools/estimatePaymentFee.ts
|
|
2220
|
+
var import_zod17 = require("zod");
|
|
2221
|
+
var import_viem10 = require("viem");
|
|
2222
|
+
var chains8 = __toESM(require("viem/chains"));
|
|
2223
|
+
var estimatePaymentFeeInputSchema = import_zod17.z.object({
|
|
2224
|
+
network: import_zod17.z.enum([
|
|
2225
|
+
"ethereum",
|
|
2226
|
+
"base",
|
|
2227
|
+
"arbitrum",
|
|
2228
|
+
"optimism",
|
|
2229
|
+
"polygon",
|
|
2230
|
+
"avalanche",
|
|
2231
|
+
"ink",
|
|
2232
|
+
"berachain",
|
|
2233
|
+
"unichain"
|
|
2234
|
+
]).describe("Network to estimate fee on"),
|
|
2235
|
+
amount: import_zod17.z.string().regex(/^\d+(\.\d+)?$/).describe("Payment amount (e.g., '100')"),
|
|
2236
|
+
token: import_zod17.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to use for payment")
|
|
2237
|
+
});
|
|
2238
|
+
function getViemChain7(network) {
|
|
2239
|
+
switch (network) {
|
|
2240
|
+
case "ethereum":
|
|
2241
|
+
return chains8.mainnet;
|
|
2242
|
+
case "base":
|
|
2243
|
+
return chains8.base;
|
|
2244
|
+
case "arbitrum":
|
|
2245
|
+
return chains8.arbitrum;
|
|
2246
|
+
case "optimism":
|
|
2247
|
+
return chains8.optimism;
|
|
2248
|
+
case "polygon":
|
|
2249
|
+
return chains8.polygon;
|
|
2250
|
+
case "avalanche":
|
|
2251
|
+
return chains8.avalanche;
|
|
2252
|
+
case "ink":
|
|
2253
|
+
return chains8.ink;
|
|
2254
|
+
case "berachain":
|
|
2255
|
+
return chains8.berachain;
|
|
2256
|
+
case "unichain":
|
|
2257
|
+
return chains8.unichain;
|
|
2258
|
+
default:
|
|
2259
|
+
return chains8.mainnet;
|
|
2260
|
+
}
|
|
2015
2261
|
}
|
|
2016
|
-
async function
|
|
2017
|
-
const
|
|
2018
|
-
const
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2262
|
+
async function executeEstimatePaymentFee(input, options) {
|
|
2263
|
+
const { network, amount, token } = input;
|
|
2264
|
+
const nativeSymbol = NATIVE_SYMBOLS[network];
|
|
2265
|
+
if (options.demoMode) {
|
|
2266
|
+
const demoEstimates = {
|
|
2267
|
+
ethereum: { gasLimit: 65000n, gasPrice: 25000000000n, nativePrice: 3250.42 },
|
|
2268
|
+
base: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 },
|
|
2269
|
+
arbitrum: { gasLimit: 65000n, gasPrice: 100000000n, nativePrice: 3250.42 },
|
|
2270
|
+
optimism: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 },
|
|
2271
|
+
polygon: { gasLimit: 65000n, gasPrice: 30000000000n, nativePrice: 0.58 },
|
|
2272
|
+
avalanche: { gasLimit: 65000n, gasPrice: 25000000000n, nativePrice: 24.15 },
|
|
2273
|
+
ink: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 },
|
|
2274
|
+
berachain: { gasLimit: 65000n, gasPrice: 1000000000n, nativePrice: 3.82 },
|
|
2275
|
+
unichain: { gasLimit: 65000n, gasPrice: 50000000n, nativePrice: 3250.42 }
|
|
2027
2276
|
};
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
if (bestChain) {
|
|
2032
|
-
const needsBridge = targetNetwork ? !bestChain.chain.includes(targetNetwork) : false;
|
|
2277
|
+
const est = demoEstimates[network] ?? demoEstimates["ethereum"];
|
|
2278
|
+
const nativeCost2 = est.gasLimit * est.gasPrice;
|
|
2279
|
+
const usdCost2 = Number(nativeCost2) / 1e18 * est.nativePrice;
|
|
2033
2280
|
return {
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
toChain: targetNetwork ?? bestChain.chain,
|
|
2041
|
-
amount: requiredAmount ?? "0",
|
|
2042
|
-
estimatedFee: "0.001"
|
|
2043
|
-
} : void 0,
|
|
2044
|
-
balances
|
|
2281
|
+
network,
|
|
2282
|
+
gasLimit: est.gasLimit.toString(),
|
|
2283
|
+
gasPriceGwei: (0, import_viem10.formatGwei)(est.gasPrice),
|
|
2284
|
+
nativeCost: (0, import_viem10.formatEther)(nativeCost2),
|
|
2285
|
+
nativeSymbol,
|
|
2286
|
+
usdCost: `$${usdCost2.toFixed(4)}`
|
|
2045
2287
|
};
|
|
2046
2288
|
}
|
|
2289
|
+
const tokenAddress = getTokenAddress(network, token);
|
|
2290
|
+
if (!tokenAddress) {
|
|
2291
|
+
throw new Error(`Token ${token} is not supported on ${network}`);
|
|
2292
|
+
}
|
|
2293
|
+
const chain = getViemChain7(network);
|
|
2294
|
+
const transport = (0, import_viem10.http)(options.rpcUrl ?? DEFAULT_RPC_URLS[network]);
|
|
2295
|
+
const client = (0, import_viem10.createPublicClient)({ chain, transport });
|
|
2296
|
+
const amountBigInt = (0, import_viem10.parseUnits)(amount, 6);
|
|
2297
|
+
const dummyTo = "0x000000000000000000000000000000000000dEaD";
|
|
2298
|
+
let gasLimit;
|
|
2299
|
+
try {
|
|
2300
|
+
gasLimit = await client.estimateGas({
|
|
2301
|
+
to: tokenAddress,
|
|
2302
|
+
data: `0xa9059cbb${dummyTo.slice(2).padStart(64, "0")}${amountBigInt.toString(16).padStart(64, "0")}`
|
|
2303
|
+
});
|
|
2304
|
+
} catch {
|
|
2305
|
+
gasLimit = 65000n;
|
|
2306
|
+
}
|
|
2307
|
+
const gasPrice = await client.getGasPrice();
|
|
2308
|
+
const nativeCost = gasLimit * gasPrice;
|
|
2309
|
+
let usdCost;
|
|
2310
|
+
try {
|
|
2311
|
+
const prices = await getTokenPrices([nativeSymbol]);
|
|
2312
|
+
const nativePrice = prices[nativeSymbol] ?? 0;
|
|
2313
|
+
const cost = Number(nativeCost) / 1e18 * nativePrice;
|
|
2314
|
+
usdCost = `$${cost.toFixed(4)}`;
|
|
2315
|
+
} catch {
|
|
2316
|
+
usdCost = "N/A";
|
|
2317
|
+
}
|
|
2047
2318
|
return {
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2319
|
+
network,
|
|
2320
|
+
gasLimit: gasLimit.toString(),
|
|
2321
|
+
gasPriceGwei: (0, import_viem10.formatGwei)(gasPrice),
|
|
2322
|
+
nativeCost: (0, import_viem10.formatEther)(nativeCost),
|
|
2323
|
+
nativeSymbol,
|
|
2324
|
+
usdCost
|
|
2052
2325
|
};
|
|
2053
2326
|
}
|
|
2054
|
-
function
|
|
2055
|
-
return
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2327
|
+
function formatPaymentFeeEstimate(result) {
|
|
2328
|
+
return [
|
|
2329
|
+
"## Payment Fee Estimate",
|
|
2330
|
+
"",
|
|
2331
|
+
`- **Network:** ${result.network}`,
|
|
2332
|
+
`- **Estimated Gas:** ${result.gasLimit}`,
|
|
2333
|
+
`- **Gas Price:** ${result.gasPriceGwei} gwei`,
|
|
2334
|
+
`- **Native Cost:** ${result.nativeCost} ${result.nativeSymbol}`,
|
|
2335
|
+
`- **USD Cost:** ${result.usdCost}`
|
|
2336
|
+
].join("\n");
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
// src/tools/compareNetworkFees.ts
|
|
2340
|
+
var import_zod18 = require("zod");
|
|
2341
|
+
var compareNetworkFeesInputSchema = import_zod18.z.object({
|
|
2342
|
+
amount: import_zod18.z.string().regex(/^\d+(\.\d+)?$/).describe("Payment amount (e.g., '100')"),
|
|
2343
|
+
token: import_zod18.z.enum(["USDC", "USDT", "USDT0"]).describe("Token to use for payment"),
|
|
2344
|
+
networks: import_zod18.z.array(import_zod18.z.string()).optional().describe(
|
|
2345
|
+
"Networks to compare. If not provided, compares all networks that support the token."
|
|
2346
|
+
)
|
|
2347
|
+
});
|
|
2348
|
+
var ALL_NETWORKS2 = [
|
|
2349
|
+
"ethereum",
|
|
2350
|
+
"base",
|
|
2351
|
+
"arbitrum",
|
|
2352
|
+
"optimism",
|
|
2353
|
+
"polygon",
|
|
2354
|
+
"avalanche",
|
|
2355
|
+
"ink",
|
|
2356
|
+
"berachain",
|
|
2357
|
+
"unichain"
|
|
2358
|
+
];
|
|
2359
|
+
async function executeCompareNetworkFees(input, options) {
|
|
2360
|
+
const { amount, token } = input;
|
|
2361
|
+
const requestedNetworks = input.networks ? input.networks : ALL_NETWORKS2;
|
|
2362
|
+
const networks = requestedNetworks.filter((n) => supportsToken(n, token));
|
|
2363
|
+
if (networks.length === 0) {
|
|
2364
|
+
throw new Error(`No supported networks found for token ${token}`);
|
|
2365
|
+
}
|
|
2366
|
+
const results = await Promise.allSettled(
|
|
2367
|
+
networks.map(
|
|
2368
|
+
(network) => executeEstimatePaymentFee(
|
|
2369
|
+
{ network, amount, token },
|
|
2370
|
+
{
|
|
2371
|
+
rpcUrl: options.rpcUrls?.[network],
|
|
2372
|
+
demoMode: options.demoMode
|
|
2373
|
+
}
|
|
2374
|
+
)
|
|
2375
|
+
)
|
|
2376
|
+
);
|
|
2377
|
+
const fees = [];
|
|
2378
|
+
for (const result of results) {
|
|
2379
|
+
if (result.status === "fulfilled") {
|
|
2380
|
+
fees.push(result.value);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
if (fees.length === 0) {
|
|
2384
|
+
throw new Error("Failed to estimate fees on any network");
|
|
2385
|
+
}
|
|
2386
|
+
fees.sort((a, b) => {
|
|
2387
|
+
const costA = parseFloat(a.nativeCost) || Infinity;
|
|
2388
|
+
const costB = parseFloat(b.nativeCost) || Infinity;
|
|
2389
|
+
const usdA = parseFloat(a.usdCost.replace("$", "")) || Infinity;
|
|
2390
|
+
const usdB = parseFloat(b.usdCost.replace("$", "")) || Infinity;
|
|
2391
|
+
return usdA - usdB || costA - costB;
|
|
2392
|
+
});
|
|
2393
|
+
return {
|
|
2394
|
+
token,
|
|
2395
|
+
amount,
|
|
2396
|
+
fees,
|
|
2397
|
+
cheapest: fees[0].network
|
|
2398
|
+
};
|
|
2399
|
+
}
|
|
2400
|
+
function formatNetworkFeeComparison(result) {
|
|
2401
|
+
const lines = [
|
|
2402
|
+
"## Network Fee Comparison",
|
|
2403
|
+
"",
|
|
2404
|
+
`**Token:** ${result.token} | **Amount:** ${result.amount}`,
|
|
2405
|
+
`**Cheapest:** ${result.cheapest}`,
|
|
2406
|
+
"",
|
|
2407
|
+
"| Network | Gas Price | Native Cost | USD Cost |",
|
|
2408
|
+
"|---------|----------|-------------|----------|"
|
|
2409
|
+
];
|
|
2410
|
+
for (const fee of result.fees) {
|
|
2411
|
+
const marker = fee.network === result.cheapest ? " *" : "";
|
|
2412
|
+
lines.push(
|
|
2413
|
+
`| ${fee.network}${marker} | ${fee.gasPriceGwei} gwei | ${fee.nativeCost} ${fee.nativeSymbol} | ${fee.usdCost} |`
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
return lines.join("\n");
|
|
2417
|
+
}
|
|
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
|
+
|
|
2803
|
+
// src/tools/quoteStore.ts
|
|
2804
|
+
var import_crypto = require("crypto");
|
|
2805
|
+
var DEFAULT_TTL_MS = 5 * 60 * 1e3;
|
|
2806
|
+
var quotes = /* @__PURE__ */ new Map();
|
|
2807
|
+
var cleanupInterval = null;
|
|
2808
|
+
function ensureCleanup() {
|
|
2809
|
+
if (cleanupInterval) return;
|
|
2810
|
+
cleanupInterval = setInterval(() => {
|
|
2811
|
+
const now = Date.now();
|
|
2812
|
+
for (const [id, quote] of quotes) {
|
|
2813
|
+
if (now > quote.expiresAt) {
|
|
2814
|
+
quotes.delete(id);
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}, 6e4);
|
|
2818
|
+
if (cleanupInterval.unref) {
|
|
2819
|
+
cleanupInterval.unref();
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
function createQuote(type, data, ttlMs = DEFAULT_TTL_MS) {
|
|
2823
|
+
ensureCleanup();
|
|
2824
|
+
const id = (0, import_crypto.randomUUID)();
|
|
2825
|
+
const now = Date.now();
|
|
2826
|
+
quotes.set(id, {
|
|
2827
|
+
id,
|
|
2828
|
+
type,
|
|
2829
|
+
createdAt: now,
|
|
2830
|
+
expiresAt: now + ttlMs,
|
|
2831
|
+
data
|
|
2832
|
+
});
|
|
2833
|
+
return id;
|
|
2834
|
+
}
|
|
2835
|
+
function getQuote(quoteId) {
|
|
2836
|
+
const quote = quotes.get(quoteId);
|
|
2837
|
+
if (!quote) return null;
|
|
2838
|
+
if (Date.now() > quote.expiresAt) {
|
|
2839
|
+
quotes.delete(quoteId);
|
|
2840
|
+
return null;
|
|
2841
|
+
}
|
|
2842
|
+
return quote;
|
|
2843
|
+
}
|
|
2844
|
+
function deleteQuote(quoteId) {
|
|
2845
|
+
quotes.delete(quoteId);
|
|
2846
|
+
}
|
|
2847
|
+
function clearQuoteStore() {
|
|
2848
|
+
quotes.clear();
|
|
2849
|
+
}
|
|
2850
|
+
|
|
2851
|
+
// src/tools/wdkQuoteSwap.ts
|
|
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")')
|
|
2859
|
+
});
|
|
2860
|
+
async function executeWdkQuoteSwap(input, wdk) {
|
|
2861
|
+
const decimals = ["USDC", "USDT", "USDT0"].includes(input.fromToken.toUpperCase()) ? 6 : 18;
|
|
2862
|
+
const amountBigInt = (0, import_viem13.parseUnits)(input.amount, decimals);
|
|
2863
|
+
const quote = await wdk.getSwapQuote(input.chain, input.fromToken, amountBigInt);
|
|
2864
|
+
const outputDecimals = ["USDC", "USDT", "USDT0"].includes(input.toToken.toUpperCase()) ? 6 : 18;
|
|
2865
|
+
const outputDivisor = 10 ** outputDecimals;
|
|
2866
|
+
const toAmount = (Number(quote.outputAmount) / outputDivisor).toFixed(outputDecimals === 6 ? 6 : 8);
|
|
2867
|
+
const inputAmount = parseFloat(input.amount);
|
|
2868
|
+
const outputAmount = parseFloat(toAmount);
|
|
2869
|
+
const exchangeRate = inputAmount > 0 ? (outputAmount / inputAmount).toFixed(6) : "0";
|
|
2870
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
2871
|
+
const quoteId = createQuote("swap", {
|
|
2872
|
+
fromToken: input.fromToken,
|
|
2873
|
+
toToken: input.toToken,
|
|
2874
|
+
fromAmount: input.amount,
|
|
2875
|
+
toAmount,
|
|
2876
|
+
chain: input.chain,
|
|
2877
|
+
exchangeRate
|
|
2878
|
+
});
|
|
2879
|
+
return {
|
|
2880
|
+
quoteId,
|
|
2881
|
+
fromToken: input.fromToken,
|
|
2882
|
+
toToken: input.toToken,
|
|
2883
|
+
fromAmount: input.amount,
|
|
2884
|
+
toAmount,
|
|
2885
|
+
exchangeRate,
|
|
2886
|
+
fee: "0.3%",
|
|
2887
|
+
priceImpact: "< 0.1%",
|
|
2888
|
+
expiresAt,
|
|
2889
|
+
chain: input.chain
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
function executeWdkQuoteSwapDemo(input) {
|
|
2893
|
+
const inputAmount = parseFloat(input.amount);
|
|
2894
|
+
const toAmount = (inputAmount * 0.997).toFixed(6);
|
|
2895
|
+
const exchangeRate = 0.997.toFixed(6);
|
|
2896
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
2897
|
+
const quoteId = createQuote("swap", {
|
|
2898
|
+
fromToken: input.fromToken,
|
|
2899
|
+
toToken: input.toToken,
|
|
2900
|
+
fromAmount: input.amount,
|
|
2901
|
+
toAmount,
|
|
2902
|
+
chain: input.chain,
|
|
2903
|
+
exchangeRate
|
|
2904
|
+
});
|
|
2905
|
+
return {
|
|
2906
|
+
quoteId,
|
|
2907
|
+
fromToken: input.fromToken,
|
|
2908
|
+
toToken: input.toToken,
|
|
2909
|
+
fromAmount: input.amount,
|
|
2910
|
+
toAmount,
|
|
2911
|
+
exchangeRate,
|
|
2912
|
+
fee: "0.3%",
|
|
2913
|
+
priceImpact: "< 0.1%",
|
|
2914
|
+
expiresAt,
|
|
2915
|
+
chain: input.chain
|
|
2916
|
+
};
|
|
2917
|
+
}
|
|
2918
|
+
function formatSwapQuoteResult(result) {
|
|
2919
|
+
return [
|
|
2920
|
+
"## Swap Quote",
|
|
2921
|
+
"",
|
|
2922
|
+
`- **Quote ID:** \`${result.quoteId}\``,
|
|
2923
|
+
`- **From:** ${result.fromAmount} ${result.fromToken}`,
|
|
2924
|
+
`- **To:** ${result.toAmount} ${result.toToken}`,
|
|
2925
|
+
`- **Exchange Rate:** ${result.exchangeRate}`,
|
|
2926
|
+
`- **Fee:** ${result.fee}`,
|
|
2927
|
+
`- **Price Impact:** ${result.priceImpact}`,
|
|
2928
|
+
`- **Chain:** ${result.chain}`,
|
|
2929
|
+
`- **Expires:** ${result.expiresAt}`,
|
|
2930
|
+
"",
|
|
2931
|
+
"_Call `wdk/executeSwap` with the quoteId to execute this swap._"
|
|
2932
|
+
].join("\n");
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
// src/tools/wdkExecuteSwap.ts
|
|
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")
|
|
2941
|
+
});
|
|
2942
|
+
async function executeWdkExecuteSwap(input, wdk) {
|
|
2943
|
+
const quote = getQuote(input.quoteId);
|
|
2944
|
+
if (!quote) {
|
|
2945
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
2946
|
+
}
|
|
2947
|
+
if (quote.type !== "swap") {
|
|
2948
|
+
throw new Error("Invalid quote type. Expected a swap quote.");
|
|
2949
|
+
}
|
|
2950
|
+
const { fromToken, toToken, fromAmount, toAmount, chain } = quote.data;
|
|
2951
|
+
if (!input.confirmed) {
|
|
2952
|
+
return {
|
|
2953
|
+
needsConfirmation: true,
|
|
2954
|
+
summary: `Swap ${fromAmount} ${fromToken} to ${toAmount} ${toToken} on ${chain}`,
|
|
2955
|
+
details: { fromToken, toToken, fromAmount, toAmount, chain, quoteId: input.quoteId }
|
|
2956
|
+
};
|
|
2957
|
+
}
|
|
2958
|
+
const decimals = ["USDC", "USDT", "USDT0"].includes(fromToken.toUpperCase()) ? 6 : 18;
|
|
2959
|
+
const amountBigInt = (0, import_viem14.parseUnits)(fromAmount, decimals);
|
|
2960
|
+
const result = await wdk.swapAndPay({
|
|
2961
|
+
chain,
|
|
2962
|
+
fromToken,
|
|
2963
|
+
amount: amountBigInt
|
|
2964
|
+
});
|
|
2965
|
+
deleteQuote(input.quoteId);
|
|
2966
|
+
return {
|
|
2967
|
+
fromAmount,
|
|
2968
|
+
fromToken,
|
|
2969
|
+
toAmount,
|
|
2970
|
+
toToken,
|
|
2971
|
+
chain,
|
|
2972
|
+
txHash: result?.txHash ?? "0x"
|
|
2973
|
+
};
|
|
2974
|
+
}
|
|
2975
|
+
function executeWdkExecuteSwapDemo(input) {
|
|
2976
|
+
const quote = getQuote(input.quoteId);
|
|
2977
|
+
if (!quote) {
|
|
2978
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
2979
|
+
}
|
|
2980
|
+
if (quote.type !== "swap") {
|
|
2981
|
+
throw new Error("Invalid quote type. Expected a swap quote.");
|
|
2982
|
+
}
|
|
2983
|
+
const { fromToken, toToken, fromAmount, toAmount, chain } = quote.data;
|
|
2984
|
+
if (!input.confirmed) {
|
|
2985
|
+
return {
|
|
2986
|
+
needsConfirmation: true,
|
|
2987
|
+
summary: `Swap ${fromAmount} ${fromToken} to ${toAmount} ${toToken} on ${chain}`,
|
|
2988
|
+
details: { fromToken, toToken, fromAmount, toAmount, chain, quoteId: input.quoteId }
|
|
2989
|
+
};
|
|
2990
|
+
}
|
|
2991
|
+
deleteQuote(input.quoteId);
|
|
2992
|
+
return {
|
|
2993
|
+
fromAmount,
|
|
2994
|
+
fromToken,
|
|
2995
|
+
toAmount,
|
|
2996
|
+
toToken,
|
|
2997
|
+
chain,
|
|
2998
|
+
txHash: "0xdemo" + Math.random().toString(16).slice(2, 10)
|
|
2999
|
+
};
|
|
3000
|
+
}
|
|
3001
|
+
function formatExecuteSwapResult(result) {
|
|
3002
|
+
return [
|
|
3003
|
+
"## Swap Executed",
|
|
3004
|
+
"",
|
|
3005
|
+
`- **From:** ${result.fromAmount} ${result.fromToken}`,
|
|
3006
|
+
`- **To:** ${result.toAmount} ${result.toToken}`,
|
|
3007
|
+
`- **Chain:** ${result.chain}`,
|
|
3008
|
+
`- **Tx Hash:** \`${result.txHash}\``
|
|
3009
|
+
].join("\n");
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
// src/tools/quoteBridge.ts
|
|
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")
|
|
3019
|
+
});
|
|
3020
|
+
async function executeQuoteBridge(input, rpcUrls) {
|
|
3021
|
+
const feeResult = await executeGetBridgeFee(input, rpcUrls);
|
|
3022
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
3023
|
+
const quoteId = createQuote("bridge", {
|
|
3024
|
+
fromChain: input.fromChain,
|
|
3025
|
+
toChain: input.toChain,
|
|
3026
|
+
amount: input.amount,
|
|
3027
|
+
recipient: input.recipient,
|
|
3028
|
+
nativeFee: feeResult.nativeFee,
|
|
3029
|
+
nativeFeeFormatted: feeResult.nativeFeeFormatted,
|
|
3030
|
+
estimatedTime: feeResult.estimatedTime
|
|
3031
|
+
});
|
|
3032
|
+
return {
|
|
3033
|
+
quoteId,
|
|
3034
|
+
fromChain: input.fromChain,
|
|
3035
|
+
toChain: input.toChain,
|
|
3036
|
+
amount: input.amount,
|
|
3037
|
+
recipient: input.recipient,
|
|
3038
|
+
nativeFee: feeResult.nativeFee,
|
|
3039
|
+
nativeFeeFormatted: feeResult.nativeFeeFormatted,
|
|
3040
|
+
estimatedTime: feeResult.estimatedTime,
|
|
3041
|
+
expiresAt
|
|
3042
|
+
};
|
|
3043
|
+
}
|
|
3044
|
+
function executeQuoteBridgeDemo(input) {
|
|
3045
|
+
const expiresAt = new Date(Date.now() + 5 * 60 * 1e3).toISOString();
|
|
3046
|
+
const estimatedTime = input.toChain === "ethereum" ? 900 : 300;
|
|
3047
|
+
const quoteId = createQuote("bridge", {
|
|
3048
|
+
fromChain: input.fromChain,
|
|
3049
|
+
toChain: input.toChain,
|
|
3050
|
+
amount: input.amount,
|
|
3051
|
+
recipient: input.recipient,
|
|
3052
|
+
nativeFee: "1000000000000000",
|
|
3053
|
+
nativeFeeFormatted: "0.001 ETH",
|
|
3054
|
+
estimatedTime
|
|
3055
|
+
});
|
|
3056
|
+
return {
|
|
3057
|
+
quoteId,
|
|
3058
|
+
fromChain: input.fromChain,
|
|
3059
|
+
toChain: input.toChain,
|
|
3060
|
+
amount: input.amount,
|
|
3061
|
+
recipient: input.recipient,
|
|
3062
|
+
nativeFee: "1000000000000000",
|
|
3063
|
+
nativeFeeFormatted: "0.001 ETH",
|
|
3064
|
+
estimatedTime,
|
|
3065
|
+
expiresAt
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
function formatBridgeQuoteResult(result) {
|
|
3069
|
+
const minutes = Math.ceil(result.estimatedTime / 60);
|
|
3070
|
+
return [
|
|
3071
|
+
"## Bridge Quote",
|
|
3072
|
+
"",
|
|
3073
|
+
`- **Quote ID:** \`${result.quoteId}\``,
|
|
3074
|
+
`- **Route:** ${result.fromChain} -> ${result.toChain}`,
|
|
3075
|
+
`- **Amount:** ${result.amount} USDT0`,
|
|
3076
|
+
`- **Recipient:** \`${result.recipient}\``,
|
|
3077
|
+
`- **Fee:** ${result.nativeFeeFormatted}`,
|
|
3078
|
+
`- **Estimated Time:** ~${minutes} minutes`,
|
|
3079
|
+
`- **Expires:** ${result.expiresAt}`,
|
|
3080
|
+
"",
|
|
3081
|
+
"_Call `t402/executeBridge` with the quoteId to execute this bridge._"
|
|
3082
|
+
].join("\n");
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
// src/tools/executeBridgeFromQuote.ts
|
|
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")
|
|
3090
|
+
});
|
|
3091
|
+
async function executeExecuteBridgeFromQuote(input, options) {
|
|
3092
|
+
const quote = getQuote(input.quoteId);
|
|
3093
|
+
if (!quote) {
|
|
3094
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
3095
|
+
}
|
|
3096
|
+
if (quote.type !== "bridge") {
|
|
3097
|
+
throw new Error("Invalid quote type. Expected a bridge quote.");
|
|
3098
|
+
}
|
|
3099
|
+
const { fromChain, toChain, amount, recipient } = quote.data;
|
|
3100
|
+
if (!input.confirmed) {
|
|
3101
|
+
return {
|
|
3102
|
+
needsConfirmation: true,
|
|
3103
|
+
summary: `Bridge ${amount} USDT0 from ${fromChain} to ${toChain}`,
|
|
3104
|
+
details: { fromChain, toChain, amount, recipient, quoteId: input.quoteId }
|
|
3105
|
+
};
|
|
3106
|
+
}
|
|
3107
|
+
const result = await executeBridge(
|
|
3108
|
+
{ fromChain, toChain, amount, recipient, confirmed: true },
|
|
3109
|
+
options
|
|
3110
|
+
);
|
|
3111
|
+
if ("needsConfirmation" in result) {
|
|
3112
|
+
return result;
|
|
3113
|
+
}
|
|
3114
|
+
deleteQuote(input.quoteId);
|
|
3115
|
+
return result;
|
|
3116
|
+
}
|
|
3117
|
+
function executeExecuteBridgeFromQuoteDemo(input) {
|
|
3118
|
+
const quote = getQuote(input.quoteId);
|
|
3119
|
+
if (!quote) {
|
|
3120
|
+
throw new Error("Quote not found or expired. Please request a new quote.");
|
|
3121
|
+
}
|
|
3122
|
+
if (quote.type !== "bridge") {
|
|
3123
|
+
throw new Error("Invalid quote type. Expected a bridge quote.");
|
|
3124
|
+
}
|
|
3125
|
+
const { fromChain, toChain, amount, recipient } = quote.data;
|
|
3126
|
+
if (!input.confirmed) {
|
|
3127
|
+
return {
|
|
3128
|
+
needsConfirmation: true,
|
|
3129
|
+
summary: `Bridge ${amount} USDT0 from ${fromChain} to ${toChain}`,
|
|
3130
|
+
details: { fromChain, toChain, amount, recipient, quoteId: input.quoteId }
|
|
3131
|
+
};
|
|
3132
|
+
}
|
|
3133
|
+
deleteQuote(input.quoteId);
|
|
3134
|
+
const fakeTxHash = `0x${"a".repeat(64)}`;
|
|
3135
|
+
const fakeGuid = `0x${"b".repeat(64)}`;
|
|
3136
|
+
return {
|
|
3137
|
+
txHash: fakeTxHash,
|
|
3138
|
+
messageGuid: fakeGuid,
|
|
3139
|
+
amount,
|
|
3140
|
+
fromChain,
|
|
3141
|
+
toChain,
|
|
3142
|
+
estimatedTime: quote.data.estimatedTime ?? 300,
|
|
3143
|
+
trackingUrl: `https://layerzeroscan.com/tx/${fakeGuid}`
|
|
3144
|
+
};
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
// src/tools/unified.ts
|
|
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")
|
|
3154
|
+
});
|
|
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()
|
|
3164
|
+
}).passthrough().describe("The 402 PaymentRequired response")
|
|
3165
|
+
});
|
|
3166
|
+
var UNIFIED_TOOL_DEFINITIONS = {
|
|
3167
|
+
"t402/smartPay": {
|
|
3168
|
+
name: "t402/smartPay",
|
|
3169
|
+
description: "Intelligent payment that automatically checks balance, bridges if needed, and pays. Handles the entire payment flow for 402-protected resources.",
|
|
3170
|
+
inputSchema: {
|
|
3171
|
+
type: "object",
|
|
3172
|
+
properties: {
|
|
3173
|
+
url: { type: "string", description: "URL of the 402-protected resource" },
|
|
3174
|
+
maxBridgeFee: {
|
|
3175
|
+
type: "string",
|
|
3176
|
+
description: "Maximum acceptable bridge fee in native token (optional)"
|
|
3177
|
+
},
|
|
3178
|
+
preferredNetwork: {
|
|
3179
|
+
type: "string",
|
|
3180
|
+
description: "Preferred network for payment (optional)"
|
|
3181
|
+
},
|
|
3182
|
+
confirmed: {
|
|
3183
|
+
type: "boolean",
|
|
3184
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3185
|
+
}
|
|
3186
|
+
},
|
|
3187
|
+
required: ["url"]
|
|
3188
|
+
}
|
|
3189
|
+
},
|
|
3190
|
+
"t402/paymentPlan": {
|
|
3191
|
+
name: "t402/paymentPlan",
|
|
3192
|
+
description: "Analyze a 402 response and create an optimal payment plan considering balances across all chains. Returns recommended network, bridge requirements, and balance overview.",
|
|
3193
|
+
inputSchema: {
|
|
3194
|
+
type: "object",
|
|
3195
|
+
properties: {
|
|
3196
|
+
paymentRequired: {
|
|
3197
|
+
type: "object",
|
|
3198
|
+
description: "The 402 PaymentRequired response"
|
|
3199
|
+
}
|
|
3200
|
+
},
|
|
3201
|
+
required: ["paymentRequired"]
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
};
|
|
3205
|
+
async function executeSmartPay(input, wdk) {
|
|
3206
|
+
if (!input.confirmed) {
|
|
3207
|
+
return {
|
|
3208
|
+
needsConfirmation: true,
|
|
3209
|
+
summary: `Smart-pay for ${input.url}${input.preferredNetwork ? ` on ${input.preferredNetwork}` : ""}`,
|
|
3210
|
+
details: {
|
|
3211
|
+
url: input.url,
|
|
3212
|
+
...input.maxBridgeFee ? { maxBridgeFee: input.maxBridgeFee } : {},
|
|
3213
|
+
...input.preferredNetwork ? { preferredNetwork: input.preferredNetwork } : {}
|
|
3214
|
+
}
|
|
3215
|
+
};
|
|
3216
|
+
}
|
|
3217
|
+
const steps = [];
|
|
3218
|
+
const chains10 = input.preferredNetwork ? [input.preferredNetwork] : ["ethereum", "arbitrum", "base"];
|
|
3219
|
+
steps.push({
|
|
3220
|
+
action: "check_balance",
|
|
3221
|
+
status: "success",
|
|
3222
|
+
detail: `Checking balances on ${chains10.join(", ")}`
|
|
3223
|
+
});
|
|
3224
|
+
const { T402Protocol } = await import("@t402/wdk-protocol");
|
|
3225
|
+
const protocol = await T402Protocol.create(wdk, { chains: chains10 });
|
|
3226
|
+
steps.push({
|
|
3227
|
+
action: "fetch",
|
|
3228
|
+
status: "success",
|
|
3229
|
+
detail: `Fetching ${input.url}`
|
|
3230
|
+
});
|
|
3231
|
+
const { response, receipt } = await protocol.fetch(input.url);
|
|
3232
|
+
if (receipt) {
|
|
3233
|
+
steps.push({
|
|
3234
|
+
action: "pay",
|
|
3235
|
+
status: "success",
|
|
3236
|
+
detail: `Payment made: ${receipt.amount} on ${receipt.network}`
|
|
3237
|
+
});
|
|
3238
|
+
}
|
|
3239
|
+
const contentType = response.headers.get("content-type") ?? void 0;
|
|
3240
|
+
let body = "";
|
|
3241
|
+
try {
|
|
3242
|
+
body = await response.text();
|
|
3243
|
+
if (body.length > 1e4) {
|
|
3244
|
+
body = body.slice(0, 1e4) + "\n... (truncated)";
|
|
3245
|
+
}
|
|
3246
|
+
} catch {
|
|
3247
|
+
body = "[Could not read response body]";
|
|
3248
|
+
}
|
|
3249
|
+
return {
|
|
3250
|
+
success: response.ok,
|
|
3251
|
+
statusCode: response.status,
|
|
3252
|
+
body,
|
|
3253
|
+
contentType,
|
|
3254
|
+
steps,
|
|
3255
|
+
payment: receipt ? {
|
|
3256
|
+
network: receipt.network,
|
|
3257
|
+
scheme: receipt.scheme,
|
|
3258
|
+
amount: receipt.amount,
|
|
3259
|
+
payTo: receipt.payTo
|
|
3260
|
+
} : void 0
|
|
3261
|
+
};
|
|
3262
|
+
}
|
|
3263
|
+
function executeSmartPayDemo(input) {
|
|
3264
|
+
if (!input.confirmed) {
|
|
3265
|
+
return {
|
|
3266
|
+
needsConfirmation: true,
|
|
3267
|
+
summary: `Smart-pay for ${input.url}${input.preferredNetwork ? ` on ${input.preferredNetwork}` : ""}`,
|
|
3268
|
+
details: {
|
|
3269
|
+
url: input.url,
|
|
3270
|
+
...input.maxBridgeFee ? { maxBridgeFee: input.maxBridgeFee } : {},
|
|
3271
|
+
...input.preferredNetwork ? { preferredNetwork: input.preferredNetwork } : {}
|
|
3272
|
+
}
|
|
3273
|
+
};
|
|
3274
|
+
}
|
|
3275
|
+
const network = input.preferredNetwork ?? "arbitrum";
|
|
3276
|
+
return {
|
|
3277
|
+
success: true,
|
|
3278
|
+
statusCode: 200,
|
|
3279
|
+
body: `[Demo] Premium content from ${input.url}
|
|
3280
|
+
|
|
3281
|
+
This is simulated content returned after smart payment.`,
|
|
3282
|
+
contentType: "text/plain",
|
|
3283
|
+
steps: [
|
|
3284
|
+
{ action: "check_balance", status: "success", detail: `Checked balances on ${network}` },
|
|
3285
|
+
{ action: "check_price", status: "success", detail: "Resource costs 1.00 USDT0" },
|
|
3286
|
+
{ action: "pay", status: "success", detail: `Paid 1000000 USDT0 on eip155:42161` },
|
|
3287
|
+
{ action: "fetch", status: "success", detail: `Fetched ${input.url}` }
|
|
3288
|
+
],
|
|
3289
|
+
payment: {
|
|
3290
|
+
network: "eip155:42161",
|
|
3291
|
+
scheme: "exact",
|
|
3292
|
+
amount: "1000000",
|
|
3293
|
+
payTo: "0xC88f67e776f16DcFBf42e6bDda1B82604448899B"
|
|
3294
|
+
}
|
|
3295
|
+
};
|
|
3296
|
+
}
|
|
3297
|
+
async function executePaymentPlan(input, wdk) {
|
|
3298
|
+
const targetNetwork = input.paymentRequired.network;
|
|
3299
|
+
const requiredAmount = input.paymentRequired.maxAmountRequired;
|
|
3300
|
+
const aggregated = await wdk.getAggregatedBalances();
|
|
3301
|
+
const balances = aggregated.chains.map((chain) => {
|
|
3302
|
+
const usdt0 = chain.tokens.find((t) => t.symbol === "USDT0");
|
|
3303
|
+
const usdc = chain.tokens.find((t) => t.symbol === "USDC");
|
|
3304
|
+
return {
|
|
3305
|
+
chain: chain.chain,
|
|
3306
|
+
usdt0: usdt0?.formatted ?? "0",
|
|
3307
|
+
usdc: usdc?.formatted ?? "0"
|
|
3308
|
+
};
|
|
3309
|
+
});
|
|
3310
|
+
const requiredBigint = requiredAmount ? BigInt(requiredAmount) : 0n;
|
|
3311
|
+
const bestChain = await wdk.findBestChainForPayment(requiredBigint);
|
|
3312
|
+
if (bestChain) {
|
|
3313
|
+
const needsBridge = targetNetwork ? !bestChain.chain.includes(targetNetwork) : false;
|
|
3314
|
+
return {
|
|
3315
|
+
viable: true,
|
|
3316
|
+
recommendedNetwork: bestChain.chain,
|
|
3317
|
+
availableBalance: bestChain.balance.toString(),
|
|
3318
|
+
bridgeRequired: needsBridge,
|
|
3319
|
+
bridgeDetails: needsBridge ? {
|
|
3320
|
+
fromChain: bestChain.chain,
|
|
3321
|
+
toChain: targetNetwork ?? bestChain.chain,
|
|
3322
|
+
amount: requiredAmount ?? "0",
|
|
3323
|
+
estimatedFee: "0.001"
|
|
3324
|
+
} : void 0,
|
|
3325
|
+
balances
|
|
3326
|
+
};
|
|
3327
|
+
}
|
|
3328
|
+
return {
|
|
3329
|
+
viable: false,
|
|
3330
|
+
bridgeRequired: false,
|
|
3331
|
+
balances,
|
|
3332
|
+
reason: "Insufficient balance across all chains"
|
|
3333
|
+
};
|
|
3334
|
+
}
|
|
3335
|
+
function executePaymentPlanDemo(_input) {
|
|
3336
|
+
return {
|
|
3337
|
+
viable: true,
|
|
3338
|
+
recommendedNetwork: "arbitrum",
|
|
3339
|
+
availableBalance: "500000000",
|
|
3340
|
+
bridgeRequired: false,
|
|
3341
|
+
balances: [
|
|
3342
|
+
{ chain: "ethereum", usdt0: "100.00", usdc: "250.00" },
|
|
2062
3343
|
{ chain: "arbitrum", usdt0: "500.00", usdc: "0" },
|
|
2063
3344
|
{ chain: "base", usdt0: "50.00", usdc: "100.00" }
|
|
2064
3345
|
]
|
|
@@ -2244,6 +3525,10 @@ var TOOL_DEFINITIONS = {
|
|
|
2244
3525
|
memo: {
|
|
2245
3526
|
type: "string",
|
|
2246
3527
|
description: "Optional memo/reference for the payment"
|
|
3528
|
+
},
|
|
3529
|
+
confirmed: {
|
|
3530
|
+
type: "boolean",
|
|
3531
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2247
3532
|
}
|
|
2248
3533
|
},
|
|
2249
3534
|
required: ["to", "amount", "token", "network"]
|
|
@@ -2274,6 +3559,10 @@ var TOOL_DEFINITIONS = {
|
|
|
2274
3559
|
type: "string",
|
|
2275
3560
|
enum: ["ethereum", "base", "arbitrum", "optimism", "polygon", "avalanche"],
|
|
2276
3561
|
description: "Network to execute gasless payment on (must support ERC-4337)"
|
|
3562
|
+
},
|
|
3563
|
+
confirmed: {
|
|
3564
|
+
type: "boolean",
|
|
3565
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2277
3566
|
}
|
|
2278
3567
|
},
|
|
2279
3568
|
required: ["to", "amount", "token", "network"]
|
|
@@ -2312,6 +3601,144 @@ var TOOL_DEFINITIONS = {
|
|
|
2312
3601
|
"t402/bridge": {
|
|
2313
3602
|
name: "t402/bridge",
|
|
2314
3603
|
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.",
|
|
3604
|
+
inputSchema: {
|
|
3605
|
+
type: "object",
|
|
3606
|
+
properties: {
|
|
3607
|
+
fromChain: {
|
|
3608
|
+
type: "string",
|
|
3609
|
+
enum: ["ethereum", "arbitrum", "ink", "berachain", "unichain"],
|
|
3610
|
+
description: "Source chain to bridge from"
|
|
3611
|
+
},
|
|
3612
|
+
toChain: {
|
|
3613
|
+
type: "string",
|
|
3614
|
+
enum: ["ethereum", "arbitrum", "ink", "berachain", "unichain"],
|
|
3615
|
+
description: "Destination chain to bridge to"
|
|
3616
|
+
},
|
|
3617
|
+
amount: {
|
|
3618
|
+
type: "string",
|
|
3619
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3620
|
+
description: "Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"
|
|
3621
|
+
},
|
|
3622
|
+
recipient: {
|
|
3623
|
+
type: "string",
|
|
3624
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
3625
|
+
description: "Recipient address on destination chain"
|
|
3626
|
+
},
|
|
3627
|
+
confirmed: {
|
|
3628
|
+
type: "boolean",
|
|
3629
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3630
|
+
}
|
|
3631
|
+
},
|
|
3632
|
+
required: ["fromChain", "toChain", "amount", "recipient"]
|
|
3633
|
+
}
|
|
3634
|
+
},
|
|
3635
|
+
"t402/getTokenPrice": {
|
|
3636
|
+
name: "t402/getTokenPrice",
|
|
3637
|
+
description: "Get current market prices for tokens (ETH, MATIC, AVAX, USDC, etc.) via CoinGecko. Cached for 5 minutes.",
|
|
3638
|
+
inputSchema: {
|
|
3639
|
+
type: "object",
|
|
3640
|
+
properties: {
|
|
3641
|
+
tokens: {
|
|
3642
|
+
type: "array",
|
|
3643
|
+
items: { type: "string" },
|
|
3644
|
+
description: 'Token symbols to get prices for (e.g., ["ETH", "MATIC", "USDC"])'
|
|
3645
|
+
},
|
|
3646
|
+
currency: {
|
|
3647
|
+
type: "string",
|
|
3648
|
+
description: 'Target currency (default: "usd")'
|
|
3649
|
+
}
|
|
3650
|
+
},
|
|
3651
|
+
required: ["tokens"]
|
|
3652
|
+
}
|
|
3653
|
+
},
|
|
3654
|
+
"t402/getGasPrice": {
|
|
3655
|
+
name: "t402/getGasPrice",
|
|
3656
|
+
description: "Get the current gas price on a specific blockchain network. Returns the price in gwei.",
|
|
3657
|
+
inputSchema: {
|
|
3658
|
+
type: "object",
|
|
3659
|
+
properties: {
|
|
3660
|
+
network: {
|
|
3661
|
+
type: "string",
|
|
3662
|
+
enum: [
|
|
3663
|
+
"ethereum",
|
|
3664
|
+
"base",
|
|
3665
|
+
"arbitrum",
|
|
3666
|
+
"optimism",
|
|
3667
|
+
"polygon",
|
|
3668
|
+
"avalanche",
|
|
3669
|
+
"ink",
|
|
3670
|
+
"berachain",
|
|
3671
|
+
"unichain"
|
|
3672
|
+
],
|
|
3673
|
+
description: "Blockchain network to check gas price on"
|
|
3674
|
+
}
|
|
3675
|
+
},
|
|
3676
|
+
required: ["network"]
|
|
3677
|
+
}
|
|
3678
|
+
},
|
|
3679
|
+
"t402/estimatePaymentFee": {
|
|
3680
|
+
name: "t402/estimatePaymentFee",
|
|
3681
|
+
description: "Estimate the gas cost (in native token and USD) for a stablecoin payment on a specific network.",
|
|
3682
|
+
inputSchema: {
|
|
3683
|
+
type: "object",
|
|
3684
|
+
properties: {
|
|
3685
|
+
network: {
|
|
3686
|
+
type: "string",
|
|
3687
|
+
enum: [
|
|
3688
|
+
"ethereum",
|
|
3689
|
+
"base",
|
|
3690
|
+
"arbitrum",
|
|
3691
|
+
"optimism",
|
|
3692
|
+
"polygon",
|
|
3693
|
+
"avalanche",
|
|
3694
|
+
"ink",
|
|
3695
|
+
"berachain",
|
|
3696
|
+
"unichain"
|
|
3697
|
+
],
|
|
3698
|
+
description: "Network to estimate fee on"
|
|
3699
|
+
},
|
|
3700
|
+
amount: {
|
|
3701
|
+
type: "string",
|
|
3702
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3703
|
+
description: "Payment amount (e.g., '100')"
|
|
3704
|
+
},
|
|
3705
|
+
token: {
|
|
3706
|
+
type: "string",
|
|
3707
|
+
enum: ["USDC", "USDT", "USDT0"],
|
|
3708
|
+
description: "Token to use for payment"
|
|
3709
|
+
}
|
|
3710
|
+
},
|
|
3711
|
+
required: ["network", "amount", "token"]
|
|
3712
|
+
}
|
|
3713
|
+
},
|
|
3714
|
+
"t402/compareNetworkFees": {
|
|
3715
|
+
name: "t402/compareNetworkFees",
|
|
3716
|
+
description: "Compare payment fees across multiple networks for the same token. Returns a sorted table from cheapest to most expensive.",
|
|
3717
|
+
inputSchema: {
|
|
3718
|
+
type: "object",
|
|
3719
|
+
properties: {
|
|
3720
|
+
amount: {
|
|
3721
|
+
type: "string",
|
|
3722
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
3723
|
+
description: "Payment amount (e.g., '100')"
|
|
3724
|
+
},
|
|
3725
|
+
token: {
|
|
3726
|
+
type: "string",
|
|
3727
|
+
enum: ["USDC", "USDT", "USDT0"],
|
|
3728
|
+
description: "Token to use for payment"
|
|
3729
|
+
},
|
|
3730
|
+
networks: {
|
|
3731
|
+
type: "array",
|
|
3732
|
+
items: { type: "string" },
|
|
3733
|
+
description: "Networks to compare. If not provided, compares all networks that support the token."
|
|
3734
|
+
}
|
|
3735
|
+
},
|
|
3736
|
+
required: ["amount", "token"]
|
|
3737
|
+
}
|
|
3738
|
+
},
|
|
3739
|
+
"t402/quoteBridge": {
|
|
3740
|
+
name: "t402/quoteBridge",
|
|
3741
|
+
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.",
|
|
2315
3742
|
inputSchema: {
|
|
2316
3743
|
type: "object",
|
|
2317
3744
|
properties: {
|
|
@@ -2338,6 +3765,149 @@ var TOOL_DEFINITIONS = {
|
|
|
2338
3765
|
},
|
|
2339
3766
|
required: ["fromChain", "toChain", "amount", "recipient"]
|
|
2340
3767
|
}
|
|
3768
|
+
},
|
|
3769
|
+
"t402/executeBridgeQuote": {
|
|
3770
|
+
name: "t402/executeBridgeQuote",
|
|
3771
|
+
description: "Execute a bridge using a quoteId from t402/quoteBridge. Requires confirmation.",
|
|
3772
|
+
inputSchema: {
|
|
3773
|
+
type: "object",
|
|
3774
|
+
properties: {
|
|
3775
|
+
quoteId: {
|
|
3776
|
+
type: "string",
|
|
3777
|
+
description: "Quote ID from t402/quoteBridge"
|
|
3778
|
+
},
|
|
3779
|
+
confirmed: {
|
|
3780
|
+
type: "boolean",
|
|
3781
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
3782
|
+
}
|
|
3783
|
+
},
|
|
3784
|
+
required: ["quoteId"]
|
|
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
|
+
}
|
|
2341
3911
|
}
|
|
2342
3912
|
};
|
|
2343
3913
|
var WDK_TOOL_DEFINITIONS = {
|
|
@@ -2388,6 +3958,10 @@ var WDK_TOOL_DEFINITIONS = {
|
|
|
2388
3958
|
chain: {
|
|
2389
3959
|
type: "string",
|
|
2390
3960
|
description: 'Chain to execute transfer on (e.g., "ethereum", "arbitrum")'
|
|
3961
|
+
},
|
|
3962
|
+
confirmed: {
|
|
3963
|
+
type: "boolean",
|
|
3964
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2391
3965
|
}
|
|
2392
3966
|
},
|
|
2393
3967
|
required: ["to", "amount", "token", "chain"]
|
|
@@ -2415,6 +3989,10 @@ var WDK_TOOL_DEFINITIONS = {
|
|
|
2415
3989
|
chain: {
|
|
2416
3990
|
type: "string",
|
|
2417
3991
|
description: 'Chain to execute swap on (e.g., "ethereum", "arbitrum")'
|
|
3992
|
+
},
|
|
3993
|
+
confirmed: {
|
|
3994
|
+
type: "boolean",
|
|
3995
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2418
3996
|
}
|
|
2419
3997
|
},
|
|
2420
3998
|
required: ["fromToken", "toToken", "amount", "chain"]
|
|
@@ -2438,10 +4016,59 @@ var WDK_TOOL_DEFINITIONS = {
|
|
|
2438
4016
|
preferredChain: {
|
|
2439
4017
|
type: "string",
|
|
2440
4018
|
description: 'Preferred chain for payment (e.g., "arbitrum"). If not specified, uses first available.'
|
|
4019
|
+
},
|
|
4020
|
+
confirmed: {
|
|
4021
|
+
type: "boolean",
|
|
4022
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
2441
4023
|
}
|
|
2442
4024
|
},
|
|
2443
4025
|
required: ["url"]
|
|
2444
4026
|
}
|
|
4027
|
+
},
|
|
4028
|
+
"wdk/quoteSwap": {
|
|
4029
|
+
name: "wdk/quoteSwap",
|
|
4030
|
+
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.",
|
|
4031
|
+
inputSchema: {
|
|
4032
|
+
type: "object",
|
|
4033
|
+
properties: {
|
|
4034
|
+
fromToken: {
|
|
4035
|
+
type: "string",
|
|
4036
|
+
description: 'Token to swap from (e.g., "ETH", "USDC")'
|
|
4037
|
+
},
|
|
4038
|
+
toToken: {
|
|
4039
|
+
type: "string",
|
|
4040
|
+
description: 'Token to swap to (e.g., "USDT0", "USDC")'
|
|
4041
|
+
},
|
|
4042
|
+
amount: {
|
|
4043
|
+
type: "string",
|
|
4044
|
+
pattern: "^\\d+(\\.\\d+)?$",
|
|
4045
|
+
description: "Amount to swap (e.g., '1.0')"
|
|
4046
|
+
},
|
|
4047
|
+
chain: {
|
|
4048
|
+
type: "string",
|
|
4049
|
+
description: 'Chain to execute swap on (e.g., "ethereum", "arbitrum")'
|
|
4050
|
+
}
|
|
4051
|
+
},
|
|
4052
|
+
required: ["fromToken", "toToken", "amount", "chain"]
|
|
4053
|
+
}
|
|
4054
|
+
},
|
|
4055
|
+
"wdk/executeSwap": {
|
|
4056
|
+
name: "wdk/executeSwap",
|
|
4057
|
+
description: "Execute a swap using a quoteId from wdk/quoteSwap. Requires confirmation.",
|
|
4058
|
+
inputSchema: {
|
|
4059
|
+
type: "object",
|
|
4060
|
+
properties: {
|
|
4061
|
+
quoteId: {
|
|
4062
|
+
type: "string",
|
|
4063
|
+
description: "Quote ID from wdk/quoteSwap"
|
|
4064
|
+
},
|
|
4065
|
+
confirmed: {
|
|
4066
|
+
type: "boolean",
|
|
4067
|
+
description: "Set to true to confirm and execute. Omit for a preview/confirmation prompt."
|
|
4068
|
+
}
|
|
4069
|
+
},
|
|
4070
|
+
required: ["quoteId"]
|
|
4071
|
+
}
|
|
2445
4072
|
}
|
|
2446
4073
|
};
|
|
2447
4074
|
var ERC8004_TOOL_DEFINITIONS = {
|
|
@@ -2529,30 +4156,53 @@ var ERC8004_TOOL_DEFINITIONS = {
|
|
|
2529
4156
|
WDK_TOOL_DEFINITIONS,
|
|
2530
4157
|
autoPayInputSchema,
|
|
2531
4158
|
bridgeInputSchema,
|
|
4159
|
+
clearPriceCache,
|
|
4160
|
+
clearQuoteStore,
|
|
4161
|
+
compareNetworkFeesInputSchema,
|
|
4162
|
+
createQuote,
|
|
2532
4163
|
createTonBridgeToolSet,
|
|
4164
|
+
deleteQuote,
|
|
2533
4165
|
erc8004CheckReputationInputSchema,
|
|
2534
4166
|
erc8004ResolveAgentInputSchema,
|
|
2535
4167
|
erc8004VerifyWalletInputSchema,
|
|
4168
|
+
estimatePaymentFeeInputSchema,
|
|
2536
4169
|
executeAutoPay,
|
|
2537
4170
|
executeAutoPayDemo,
|
|
2538
4171
|
executeBridge,
|
|
4172
|
+
executeBridgeFromQuoteInputSchema,
|
|
4173
|
+
executeCompareNetworkFees,
|
|
2539
4174
|
executeErc8004CheckReputation,
|
|
2540
4175
|
executeErc8004ResolveAgent,
|
|
2541
4176
|
executeErc8004VerifyWallet,
|
|
4177
|
+
executeEstimatePaymentFee,
|
|
4178
|
+
executeExecuteBridgeFromQuote,
|
|
4179
|
+
executeExecuteBridgeFromQuoteDemo,
|
|
2542
4180
|
executeGetAllBalances,
|
|
2543
4181
|
executeGetBalance,
|
|
2544
4182
|
executeGetBridgeFee,
|
|
4183
|
+
executeGetGasPrice,
|
|
4184
|
+
executeGetHistoricalPrice,
|
|
4185
|
+
executeGetTokenPrice,
|
|
4186
|
+
executeGetTransferHistory,
|
|
2545
4187
|
executePay,
|
|
2546
4188
|
executePayGasless,
|
|
2547
4189
|
executePaymentPlan,
|
|
2548
4190
|
executePaymentPlanDemo,
|
|
4191
|
+
executeQuoteBridge,
|
|
4192
|
+
executeQuoteBridgeDemo,
|
|
4193
|
+
executeSignMessage,
|
|
2549
4194
|
executeSmartPay,
|
|
2550
4195
|
executeSmartPayDemo,
|
|
2551
4196
|
executeTonBridgeTool,
|
|
4197
|
+
executeVerifySignature,
|
|
4198
|
+
executeWdkExecuteSwap,
|
|
4199
|
+
executeWdkExecuteSwapDemo,
|
|
2552
4200
|
executeWdkGetBalances,
|
|
2553
4201
|
executeWdkGetBalancesDemo,
|
|
2554
4202
|
executeWdkGetWallet,
|
|
2555
4203
|
executeWdkGetWalletDemo,
|
|
4204
|
+
executeWdkQuoteSwap,
|
|
4205
|
+
executeWdkQuoteSwapDemo,
|
|
2556
4206
|
executeWdkSwap,
|
|
2557
4207
|
executeWdkSwapDemo,
|
|
2558
4208
|
executeWdkTransfer,
|
|
@@ -2561,14 +4211,26 @@ var ERC8004_TOOL_DEFINITIONS = {
|
|
|
2561
4211
|
formatAutoPayResult,
|
|
2562
4212
|
formatBalanceResult,
|
|
2563
4213
|
formatBridgeFeeResult,
|
|
4214
|
+
formatBridgeQuoteResult,
|
|
2564
4215
|
formatBridgeResult,
|
|
2565
4216
|
formatErc8004CheckReputationResult,
|
|
2566
4217
|
formatErc8004ResolveAgentResult,
|
|
2567
4218
|
formatErc8004VerifyWalletResult,
|
|
4219
|
+
formatExecuteBridgeFromQuoteResult,
|
|
4220
|
+
formatExecuteSwapResult,
|
|
4221
|
+
formatGasPriceResult,
|
|
2568
4222
|
formatGaslessPaymentResult,
|
|
4223
|
+
formatHistoricalPriceResult,
|
|
4224
|
+
formatNetworkFeeComparison,
|
|
4225
|
+
formatPaymentFeeEstimate,
|
|
2569
4226
|
formatPaymentPlanResult,
|
|
2570
4227
|
formatPaymentResult,
|
|
4228
|
+
formatSignMessageResult,
|
|
2571
4229
|
formatSmartPayResult,
|
|
4230
|
+
formatSwapQuoteResult,
|
|
4231
|
+
formatTokenPriceResult,
|
|
4232
|
+
formatTransferHistoryResult,
|
|
4233
|
+
formatVerifySignatureResult,
|
|
2572
4234
|
formatWdkBalancesResult,
|
|
2573
4235
|
formatWdkSwapResult,
|
|
2574
4236
|
formatWdkTransferResult,
|
|
@@ -2576,12 +4238,24 @@ var ERC8004_TOOL_DEFINITIONS = {
|
|
|
2576
4238
|
getAllBalancesInputSchema,
|
|
2577
4239
|
getBalanceInputSchema,
|
|
2578
4240
|
getBridgeFeeInputSchema,
|
|
4241
|
+
getGasPriceInputSchema,
|
|
4242
|
+
getHistoricalPriceInputSchema,
|
|
4243
|
+
getQuote,
|
|
4244
|
+
getTokenPriceInputSchema,
|
|
4245
|
+
getTokenPrices,
|
|
4246
|
+
getTokenPricesDemo,
|
|
4247
|
+
getTransferHistoryInputSchema,
|
|
2579
4248
|
payGaslessInputSchema,
|
|
2580
4249
|
payInputSchema,
|
|
2581
4250
|
paymentPlanInputSchema,
|
|
4251
|
+
quoteBridgeInputSchema,
|
|
4252
|
+
signMessageInputSchema,
|
|
2582
4253
|
smartPayInputSchema,
|
|
4254
|
+
verifySignatureInputSchema,
|
|
4255
|
+
wdkExecuteSwapInputSchema,
|
|
2583
4256
|
wdkGetBalancesInputSchema,
|
|
2584
4257
|
wdkGetWalletInputSchema,
|
|
4258
|
+
wdkQuoteSwapInputSchema,
|
|
2585
4259
|
wdkSwapInputSchema,
|
|
2586
4260
|
wdkTransferInputSchema
|
|
2587
4261
|
});
|