@t402/mcp 2.8.0 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +286 -58
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/index.d.ts +5 -0
- package/dist/cjs/server/index.js +286 -58
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/tools/index.d.ts +322 -1
- package/dist/cjs/tools/index.js +606 -58
- package/dist/cjs/tools/index.js.map +1 -1
- package/dist/esm/{chunk-XOPD7VTU.mjs → chunk-4DCBAKH2.mjs} +25 -2
- package/dist/esm/chunk-4DCBAKH2.mjs.map +1 -0
- package/dist/esm/{chunk-SUDCVXHQ.mjs → chunk-OSPCSAZF.mjs} +591 -55
- package/dist/esm/chunk-OSPCSAZF.mjs.map +1 -0
- package/dist/esm/index.mjs +2 -2
- package/dist/esm/server/index.d.mts +5 -0
- package/dist/esm/server/index.mjs +2 -2
- package/dist/esm/tools/index.d.mts +322 -1
- package/dist/esm/tools/index.mjs +25 -1
- package/package.json +11 -11
- package/dist/esm/chunk-SUDCVXHQ.mjs.map +0 -1
- package/dist/esm/chunk-XOPD7VTU.mjs.map +0 -1
|
@@ -1156,10 +1156,10 @@ import { z as z7 } from "zod";
|
|
|
1156
1156
|
var wdkGetWalletInputSchema = z7.object({});
|
|
1157
1157
|
async function executeWdkGetWallet(_input, wdk) {
|
|
1158
1158
|
const signer = await wdk.getSigner("ethereum");
|
|
1159
|
-
const
|
|
1159
|
+
const chains10 = wdk.getConfiguredChains();
|
|
1160
1160
|
return {
|
|
1161
1161
|
evmAddress: signer.address,
|
|
1162
|
-
chains:
|
|
1162
|
+
chains: chains10.length > 0 ? chains10 : ["ethereum"]
|
|
1163
1163
|
};
|
|
1164
1164
|
}
|
|
1165
1165
|
function executeWdkGetWalletDemo() {
|
|
@@ -1191,14 +1191,14 @@ function findTokenFormatted(tokens, symbol) {
|
|
|
1191
1191
|
}
|
|
1192
1192
|
async function executeWdkGetBalances(input, wdk) {
|
|
1193
1193
|
const balances = await wdk.getAggregatedBalances();
|
|
1194
|
-
const
|
|
1194
|
+
const chains10 = balances.chains.filter((c) => !input.chains || input.chains.includes(c.chain)).map((c) => ({
|
|
1195
1195
|
chain: c.chain,
|
|
1196
1196
|
usdt0: findTokenFormatted(c.tokens, "USDT0"),
|
|
1197
1197
|
usdc: findTokenFormatted(c.tokens, "USDC"),
|
|
1198
1198
|
native: formatUnits2(c.native, 18)
|
|
1199
1199
|
}));
|
|
1200
1200
|
return {
|
|
1201
|
-
chains:
|
|
1201
|
+
chains: chains10,
|
|
1202
1202
|
totalUsdt0: formatUnits2(balances.totalUsdt0, 6),
|
|
1203
1203
|
totalUsdc: formatUnits2(balances.totalUsdc, 6)
|
|
1204
1204
|
};
|
|
@@ -1398,22 +1398,37 @@ async function executeAutoPay(input, wdk) {
|
|
|
1398
1398
|
}
|
|
1399
1399
|
};
|
|
1400
1400
|
}
|
|
1401
|
-
const
|
|
1401
|
+
const chains10 = input.preferredChain ? [input.preferredChain] : ["ethereum", "arbitrum", "base"];
|
|
1402
1402
|
const { T402Protocol } = await import("@t402/wdk-protocol");
|
|
1403
|
-
const protocol = await T402Protocol.create(wdk, { chains:
|
|
1404
|
-
|
|
1405
|
-
if (receipt && input.maxAmount) {
|
|
1406
|
-
const paidAmount = parseFloat(receipt.amount) / 1e6;
|
|
1403
|
+
const protocol = await T402Protocol.create(wdk, { chains: chains10 });
|
|
1404
|
+
if (input.maxAmount) {
|
|
1407
1405
|
const maxAmount = parseFloat(input.maxAmount);
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1406
|
+
const preflightResponse = await fetch(input.url);
|
|
1407
|
+
if (preflightResponse.status === 402) {
|
|
1408
|
+
const requirementsHeader = preflightResponse.headers.get("x-payment") || preflightResponse.headers.get("x-payment-requirements");
|
|
1409
|
+
if (requirementsHeader) {
|
|
1410
|
+
try {
|
|
1411
|
+
const requirements = JSON.parse(requirementsHeader);
|
|
1412
|
+
const reqArray = Array.isArray(requirements) ? requirements : [requirements];
|
|
1413
|
+
for (const req of reqArray) {
|
|
1414
|
+
if (req.amount) {
|
|
1415
|
+
const reqAmount = parseFloat(req.amount) / 1e6;
|
|
1416
|
+
if (reqAmount > maxAmount) {
|
|
1417
|
+
return {
|
|
1418
|
+
success: false,
|
|
1419
|
+
statusCode: 402,
|
|
1420
|
+
body: "",
|
|
1421
|
+
error: `Required payment amount (${reqAmount}) exceeds max allowed (${maxAmount})`
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
} catch {
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1415
1429
|
}
|
|
1416
1430
|
}
|
|
1431
|
+
const { response, receipt } = await protocol.fetch(input.url);
|
|
1417
1432
|
const contentType = response.headers.get("content-type") ?? void 0;
|
|
1418
1433
|
let body = "";
|
|
1419
1434
|
try {
|
|
@@ -2277,6 +2292,390 @@ function formatNetworkFeeComparison(result) {
|
|
|
2277
2292
|
return lines.join("\n");
|
|
2278
2293
|
}
|
|
2279
2294
|
|
|
2295
|
+
// src/tools/signMessage.ts
|
|
2296
|
+
import { z as z19 } from "zod";
|
|
2297
|
+
var signMessageInputSchema = z19.object({
|
|
2298
|
+
chain: z19.enum([
|
|
2299
|
+
"ethereum",
|
|
2300
|
+
"base",
|
|
2301
|
+
"arbitrum",
|
|
2302
|
+
"optimism",
|
|
2303
|
+
"polygon",
|
|
2304
|
+
"avalanche",
|
|
2305
|
+
"ink",
|
|
2306
|
+
"berachain",
|
|
2307
|
+
"unichain"
|
|
2308
|
+
]).describe("Blockchain network context for signing"),
|
|
2309
|
+
message: z19.string().min(1).describe("Message to sign")
|
|
2310
|
+
});
|
|
2311
|
+
async function executeSignMessage(_input) {
|
|
2312
|
+
throw new Error(
|
|
2313
|
+
"Wallet not configured. To sign messages, configure a private key via the T402_PRIVATE_KEY environment variable."
|
|
2314
|
+
);
|
|
2315
|
+
}
|
|
2316
|
+
function formatSignMessageResult(result) {
|
|
2317
|
+
const lines = [
|
|
2318
|
+
`## Message Signed on ${result.network}`,
|
|
2319
|
+
"",
|
|
2320
|
+
`- **Signer:** ${result.address}`,
|
|
2321
|
+
`- **Message:** ${result.message.length > 100 ? result.message.slice(0, 100) + "..." : result.message}`,
|
|
2322
|
+
`- **Signature:** \`${result.signature}\``
|
|
2323
|
+
];
|
|
2324
|
+
return lines.join("\n");
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
// src/tools/verifySignature.ts
|
|
2328
|
+
import { z as z20 } from "zod";
|
|
2329
|
+
import { verifyMessage } from "viem";
|
|
2330
|
+
var verifySignatureInputSchema = z20.object({
|
|
2331
|
+
chain: z20.enum([
|
|
2332
|
+
"ethereum",
|
|
2333
|
+
"base",
|
|
2334
|
+
"arbitrum",
|
|
2335
|
+
"optimism",
|
|
2336
|
+
"polygon",
|
|
2337
|
+
"avalanche",
|
|
2338
|
+
"ink",
|
|
2339
|
+
"berachain",
|
|
2340
|
+
"unichain"
|
|
2341
|
+
]).describe("Blockchain network context for verification"),
|
|
2342
|
+
message: z20.string().min(1).describe("The original message that was signed"),
|
|
2343
|
+
signature: z20.string().regex(/^0x[a-fA-F0-9]+$/).describe("The signature to verify (hex string)"),
|
|
2344
|
+
address: z20.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("The expected signer address")
|
|
2345
|
+
});
|
|
2346
|
+
async function executeVerifySignature(input) {
|
|
2347
|
+
const { chain, message, signature, address } = input;
|
|
2348
|
+
try {
|
|
2349
|
+
const valid = await verifyMessage({
|
|
2350
|
+
address,
|
|
2351
|
+
message,
|
|
2352
|
+
signature
|
|
2353
|
+
});
|
|
2354
|
+
return {
|
|
2355
|
+
valid,
|
|
2356
|
+
address,
|
|
2357
|
+
message,
|
|
2358
|
+
network: chain
|
|
2359
|
+
};
|
|
2360
|
+
} catch (err) {
|
|
2361
|
+
return {
|
|
2362
|
+
valid: false,
|
|
2363
|
+
address,
|
|
2364
|
+
message,
|
|
2365
|
+
network: chain,
|
|
2366
|
+
error: err instanceof Error ? err.message : "Unknown verification error"
|
|
2367
|
+
};
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
function formatVerifySignatureResult(result) {
|
|
2371
|
+
const status = result.valid ? "VALID" : "INVALID";
|
|
2372
|
+
const lines = [
|
|
2373
|
+
`## Signature Verification: ${status}`,
|
|
2374
|
+
"",
|
|
2375
|
+
`- **Address:** ${result.address}`,
|
|
2376
|
+
`- **Network:** ${result.network}`,
|
|
2377
|
+
`- **Message:** ${result.message.length > 100 ? result.message.slice(0, 100) + "..." : result.message}`,
|
|
2378
|
+
`- **Result:** ${result.valid ? "Signature is valid and matches the address" : "Signature does NOT match the address"}`
|
|
2379
|
+
];
|
|
2380
|
+
if (result.error) {
|
|
2381
|
+
lines.push(`- **Error:** ${result.error}`);
|
|
2382
|
+
}
|
|
2383
|
+
return lines.join("\n");
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
// src/tools/getTransferHistory.ts
|
|
2387
|
+
import { z as z21 } from "zod";
|
|
2388
|
+
import { createPublicClient as createPublicClient9, http as http9, formatUnits as formatUnits4, parseAbiItem } from "viem";
|
|
2389
|
+
import * as chains9 from "viem/chains";
|
|
2390
|
+
var getTransferHistoryInputSchema = z21.object({
|
|
2391
|
+
network: z21.enum([
|
|
2392
|
+
"ethereum",
|
|
2393
|
+
"base",
|
|
2394
|
+
"arbitrum",
|
|
2395
|
+
"optimism",
|
|
2396
|
+
"polygon",
|
|
2397
|
+
"avalanche",
|
|
2398
|
+
"ink",
|
|
2399
|
+
"berachain",
|
|
2400
|
+
"unichain"
|
|
2401
|
+
]).describe("Blockchain network to query"),
|
|
2402
|
+
address: z21.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Wallet address to get transfer history for"),
|
|
2403
|
+
token: z21.enum(["USDC", "USDT", "USDT0"]).optional().describe("Filter by specific token. If not provided, queries all supported stablecoins."),
|
|
2404
|
+
limit: z21.number().int().min(1).max(100).optional().describe("Maximum number of transfers to return (default: 10, max: 100)")
|
|
2405
|
+
});
|
|
2406
|
+
function getViemChain8(network) {
|
|
2407
|
+
switch (network) {
|
|
2408
|
+
case "ethereum":
|
|
2409
|
+
return chains9.mainnet;
|
|
2410
|
+
case "base":
|
|
2411
|
+
return chains9.base;
|
|
2412
|
+
case "arbitrum":
|
|
2413
|
+
return chains9.arbitrum;
|
|
2414
|
+
case "optimism":
|
|
2415
|
+
return chains9.optimism;
|
|
2416
|
+
case "polygon":
|
|
2417
|
+
return chains9.polygon;
|
|
2418
|
+
case "avalanche":
|
|
2419
|
+
return chains9.avalanche;
|
|
2420
|
+
case "ink":
|
|
2421
|
+
return chains9.ink;
|
|
2422
|
+
case "berachain":
|
|
2423
|
+
return chains9.berachain;
|
|
2424
|
+
case "unichain":
|
|
2425
|
+
return chains9.unichain;
|
|
2426
|
+
default:
|
|
2427
|
+
return chains9.mainnet;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
var TOKEN_DECIMALS = {
|
|
2431
|
+
USDC: 6,
|
|
2432
|
+
USDT: 6,
|
|
2433
|
+
USDT0: 6
|
|
2434
|
+
};
|
|
2435
|
+
async function executeGetTransferHistory(input, rpcUrls) {
|
|
2436
|
+
const { network, address, token, limit = 10 } = input;
|
|
2437
|
+
const walletAddress = address.toLowerCase();
|
|
2438
|
+
const rpcUrl = rpcUrls?.[network] || DEFAULT_RPC_URLS[network];
|
|
2439
|
+
const chain = getViemChain8(network);
|
|
2440
|
+
const client = createPublicClient9({
|
|
2441
|
+
chain,
|
|
2442
|
+
transport: http9(rpcUrl)
|
|
2443
|
+
});
|
|
2444
|
+
const tokenContracts = [];
|
|
2445
|
+
if (token) {
|
|
2446
|
+
const addresses = token === "USDC" ? USDC_ADDRESSES : token === "USDT" ? USDT_ADDRESSES : USDT0_ADDRESSES;
|
|
2447
|
+
const addr = addresses[network];
|
|
2448
|
+
if (addr) {
|
|
2449
|
+
tokenContracts.push({ address: addr, symbol: token });
|
|
2450
|
+
}
|
|
2451
|
+
} else {
|
|
2452
|
+
if (USDC_ADDRESSES[network]) {
|
|
2453
|
+
tokenContracts.push({ address: USDC_ADDRESSES[network], symbol: "USDC" });
|
|
2454
|
+
}
|
|
2455
|
+
if (USDT_ADDRESSES[network]) {
|
|
2456
|
+
tokenContracts.push({ address: USDT_ADDRESSES[network], symbol: "USDT" });
|
|
2457
|
+
}
|
|
2458
|
+
if (USDT0_ADDRESSES[network]) {
|
|
2459
|
+
tokenContracts.push({ address: USDT0_ADDRESSES[network], symbol: "USDT0" });
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
if (tokenContracts.length === 0) {
|
|
2463
|
+
return {
|
|
2464
|
+
network,
|
|
2465
|
+
chainId: CHAIN_IDS[network],
|
|
2466
|
+
address,
|
|
2467
|
+
transfers: [],
|
|
2468
|
+
explorerUrl: EXPLORER_URLS[network]
|
|
2469
|
+
};
|
|
2470
|
+
}
|
|
2471
|
+
const currentBlock = await client.getBlockNumber();
|
|
2472
|
+
const fromBlock = currentBlock > 50000n ? currentBlock - 50000n : 0n;
|
|
2473
|
+
const transferEvent = parseAbiItem(
|
|
2474
|
+
"event Transfer(address indexed from, address indexed to, uint256 value)"
|
|
2475
|
+
);
|
|
2476
|
+
const allTransfers = [];
|
|
2477
|
+
for (const tokenContract of tokenContracts) {
|
|
2478
|
+
const decimals = TOKEN_DECIMALS[tokenContract.symbol] ?? 6;
|
|
2479
|
+
const [sentLogs, receivedLogs] = await Promise.all([
|
|
2480
|
+
client.getLogs({
|
|
2481
|
+
address: tokenContract.address,
|
|
2482
|
+
event: transferEvent,
|
|
2483
|
+
args: { from: walletAddress },
|
|
2484
|
+
fromBlock,
|
|
2485
|
+
toBlock: "latest"
|
|
2486
|
+
}),
|
|
2487
|
+
client.getLogs({
|
|
2488
|
+
address: tokenContract.address,
|
|
2489
|
+
event: transferEvent,
|
|
2490
|
+
args: { to: walletAddress },
|
|
2491
|
+
fromBlock,
|
|
2492
|
+
toBlock: "latest"
|
|
2493
|
+
})
|
|
2494
|
+
]);
|
|
2495
|
+
for (const log of sentLogs) {
|
|
2496
|
+
allTransfers.push({
|
|
2497
|
+
txHash: log.transactionHash,
|
|
2498
|
+
blockNumber: (log.blockNumber ?? 0n).toString(),
|
|
2499
|
+
from: log.args.from ?? "",
|
|
2500
|
+
to: log.args.to ?? "",
|
|
2501
|
+
amount: formatUnits4(log.args.value ?? 0n, decimals),
|
|
2502
|
+
token: tokenContract.symbol,
|
|
2503
|
+
tokenAddress: tokenContract.address,
|
|
2504
|
+
direction: "out"
|
|
2505
|
+
});
|
|
2506
|
+
}
|
|
2507
|
+
for (const log of receivedLogs) {
|
|
2508
|
+
allTransfers.push({
|
|
2509
|
+
txHash: log.transactionHash,
|
|
2510
|
+
blockNumber: (log.blockNumber ?? 0n).toString(),
|
|
2511
|
+
from: log.args.from ?? "",
|
|
2512
|
+
to: log.args.to ?? "",
|
|
2513
|
+
amount: formatUnits4(log.args.value ?? 0n, decimals),
|
|
2514
|
+
token: tokenContract.symbol,
|
|
2515
|
+
tokenAddress: tokenContract.address,
|
|
2516
|
+
direction: "in"
|
|
2517
|
+
});
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
allTransfers.sort((a, b) => {
|
|
2521
|
+
const blockA = BigInt(a.blockNumber);
|
|
2522
|
+
const blockB = BigInt(b.blockNumber);
|
|
2523
|
+
if (blockB > blockA) return 1;
|
|
2524
|
+
if (blockB < blockA) return -1;
|
|
2525
|
+
return 0;
|
|
2526
|
+
});
|
|
2527
|
+
return {
|
|
2528
|
+
network,
|
|
2529
|
+
chainId: CHAIN_IDS[network],
|
|
2530
|
+
address,
|
|
2531
|
+
transfers: allTransfers.slice(0, limit),
|
|
2532
|
+
explorerUrl: EXPLORER_URLS[network]
|
|
2533
|
+
};
|
|
2534
|
+
}
|
|
2535
|
+
function formatTransferHistoryResult(result) {
|
|
2536
|
+
const lines = [
|
|
2537
|
+
`## Transfer History on ${result.network} (Chain ID: ${result.chainId})`,
|
|
2538
|
+
"",
|
|
2539
|
+
`**Address:** ${result.address}`,
|
|
2540
|
+
""
|
|
2541
|
+
];
|
|
2542
|
+
if (result.transfers.length === 0) {
|
|
2543
|
+
lines.push("_No recent transfers found_");
|
|
2544
|
+
return lines.join("\n");
|
|
2545
|
+
}
|
|
2546
|
+
lines.push(`Found ${result.transfers.length} recent transfer(s):`, "");
|
|
2547
|
+
for (const tx of result.transfers) {
|
|
2548
|
+
const arrow = tx.direction === "in" ? "RECEIVED" : "SENT";
|
|
2549
|
+
const counterparty = tx.direction === "in" ? `from ${tx.from}` : `to ${tx.to}`;
|
|
2550
|
+
lines.push(
|
|
2551
|
+
`- **${arrow}** ${tx.amount} ${tx.token} ${counterparty}`,
|
|
2552
|
+
` Block: ${tx.blockNumber} | [View Tx](${result.explorerUrl}/tx/${tx.txHash})`,
|
|
2553
|
+
""
|
|
2554
|
+
);
|
|
2555
|
+
}
|
|
2556
|
+
return lines.join("\n");
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
// src/tools/getHistoricalPrice.ts
|
|
2560
|
+
import { z as z22 } from "zod";
|
|
2561
|
+
var getHistoricalPriceInputSchema = z22.object({
|
|
2562
|
+
token: z22.string().min(1).describe('Token symbol (e.g., "ETH", "USDC", "USDT", "MATIC", "AVAX")'),
|
|
2563
|
+
days: z22.number().int().min(1).max(365).optional().describe("Number of days of history to retrieve (default: 7, max: 365)")
|
|
2564
|
+
});
|
|
2565
|
+
var COINGECKO_MARKET_CHART = "https://api.coingecko.com/api/v3/coins";
|
|
2566
|
+
var TOKEN_TO_COINGECKO_ID2 = {
|
|
2567
|
+
ETH: "ethereum",
|
|
2568
|
+
MATIC: "matic-network",
|
|
2569
|
+
AVAX: "avalanche-2",
|
|
2570
|
+
BERA: "berachain-bera",
|
|
2571
|
+
USDC: "usd-coin",
|
|
2572
|
+
USDT: "tether",
|
|
2573
|
+
USDT0: "tether",
|
|
2574
|
+
BTC: "bitcoin",
|
|
2575
|
+
SOL: "solana",
|
|
2576
|
+
TON: "the-open-network",
|
|
2577
|
+
TRX: "tron"
|
|
2578
|
+
};
|
|
2579
|
+
async function executeGetHistoricalPrice(input, options = {}) {
|
|
2580
|
+
const { token, days = 7 } = input;
|
|
2581
|
+
const tokenUpper = token.toUpperCase();
|
|
2582
|
+
const coinId = TOKEN_TO_COINGECKO_ID2[tokenUpper] ?? token.toLowerCase();
|
|
2583
|
+
const currency = "usd";
|
|
2584
|
+
if (options.demoMode) {
|
|
2585
|
+
return generateDemoData(tokenUpper, coinId, days);
|
|
2586
|
+
}
|
|
2587
|
+
const url = `${COINGECKO_MARKET_CHART}/${coinId}/market_chart?vs_currency=${currency}&days=${days}`;
|
|
2588
|
+
const response = await fetch(url);
|
|
2589
|
+
if (!response.ok) {
|
|
2590
|
+
throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
|
|
2591
|
+
}
|
|
2592
|
+
const data = await response.json();
|
|
2593
|
+
const prices = data.prices.map(([timestamp, price]) => ({
|
|
2594
|
+
timestamp,
|
|
2595
|
+
date: new Date(timestamp).toISOString(),
|
|
2596
|
+
price
|
|
2597
|
+
}));
|
|
2598
|
+
const priceValues = prices.map((p) => p.price);
|
|
2599
|
+
const firstPrice = priceValues[0] ?? 0;
|
|
2600
|
+
const lastPrice = priceValues[priceValues.length - 1] ?? 0;
|
|
2601
|
+
const high = Math.max(...priceValues);
|
|
2602
|
+
const low = Math.min(...priceValues);
|
|
2603
|
+
const absolute = lastPrice - firstPrice;
|
|
2604
|
+
const percentage = firstPrice > 0 ? absolute / firstPrice * 100 : 0;
|
|
2605
|
+
return {
|
|
2606
|
+
token: tokenUpper,
|
|
2607
|
+
coinId,
|
|
2608
|
+
currency,
|
|
2609
|
+
days,
|
|
2610
|
+
prices,
|
|
2611
|
+
priceChange: {
|
|
2612
|
+
absolute: Math.round(absolute * 100) / 100,
|
|
2613
|
+
percentage: Math.round(percentage * 100) / 100,
|
|
2614
|
+
high: Math.round(high * 100) / 100,
|
|
2615
|
+
low: Math.round(low * 100) / 100
|
|
2616
|
+
}
|
|
2617
|
+
};
|
|
2618
|
+
}
|
|
2619
|
+
function generateDemoData(token, coinId, days) {
|
|
2620
|
+
const basePrices = {
|
|
2621
|
+
ETH: 3250,
|
|
2622
|
+
MATIC: 0.58,
|
|
2623
|
+
AVAX: 24.15,
|
|
2624
|
+
BERA: 3.82,
|
|
2625
|
+
USDC: 1,
|
|
2626
|
+
USDT: 1,
|
|
2627
|
+
USDT0: 1,
|
|
2628
|
+
BTC: 62e3,
|
|
2629
|
+
SOL: 145,
|
|
2630
|
+
TON: 5.2,
|
|
2631
|
+
TRX: 0.12
|
|
2632
|
+
};
|
|
2633
|
+
const basePrice = basePrices[token] ?? 1;
|
|
2634
|
+
const now = Date.now();
|
|
2635
|
+
const interval = days * 24 * 60 * 60 * 1e3 / Math.min(days * 24, 168);
|
|
2636
|
+
const numPoints = Math.min(days * 24, 168);
|
|
2637
|
+
const prices = [];
|
|
2638
|
+
for (let i = 0; i < numPoints; i++) {
|
|
2639
|
+
const timestamp = now - (numPoints - i) * interval;
|
|
2640
|
+
const fluctuation = 1 + (Math.sin(i * 0.5) * 0.03 + Math.cos(i * 0.3) * 0.02);
|
|
2641
|
+
const price = Math.round(basePrice * fluctuation * 100) / 100;
|
|
2642
|
+
prices.push({
|
|
2643
|
+
timestamp,
|
|
2644
|
+
date: new Date(timestamp).toISOString(),
|
|
2645
|
+
price
|
|
2646
|
+
});
|
|
2647
|
+
}
|
|
2648
|
+
const priceValues = prices.map((p) => p.price);
|
|
2649
|
+
const firstPrice = priceValues[0] ?? 0;
|
|
2650
|
+
const lastPrice = priceValues[priceValues.length - 1] ?? 0;
|
|
2651
|
+
return {
|
|
2652
|
+
token,
|
|
2653
|
+
coinId,
|
|
2654
|
+
currency: "usd",
|
|
2655
|
+
days,
|
|
2656
|
+
prices,
|
|
2657
|
+
priceChange: {
|
|
2658
|
+
absolute: Math.round((lastPrice - firstPrice) * 100) / 100,
|
|
2659
|
+
percentage: firstPrice > 0 ? Math.round((lastPrice - firstPrice) / firstPrice * 1e4) / 100 : 0,
|
|
2660
|
+
high: Math.round(Math.max(...priceValues) * 100) / 100,
|
|
2661
|
+
low: Math.round(Math.min(...priceValues) * 100) / 100
|
|
2662
|
+
}
|
|
2663
|
+
};
|
|
2664
|
+
}
|
|
2665
|
+
function formatHistoricalPriceResult(result) {
|
|
2666
|
+
const lines = [
|
|
2667
|
+
`## ${result.token} Price History (${result.days} day${result.days > 1 ? "s" : ""})`,
|
|
2668
|
+
"",
|
|
2669
|
+
`- **Current:** $${result.prices[result.prices.length - 1]?.price.toLocaleString() ?? "N/A"}`,
|
|
2670
|
+
`- **High:** $${result.priceChange.high.toLocaleString()}`,
|
|
2671
|
+
`- **Low:** $${result.priceChange.low.toLocaleString()}`,
|
|
2672
|
+
`- **Change:** ${result.priceChange.absolute >= 0 ? "+" : ""}$${result.priceChange.absolute.toLocaleString()} (${result.priceChange.percentage >= 0 ? "+" : ""}${result.priceChange.percentage}%)`,
|
|
2673
|
+
"",
|
|
2674
|
+
`_${result.prices.length} data points from CoinGecko_`
|
|
2675
|
+
];
|
|
2676
|
+
return lines.join("\n");
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2280
2679
|
// src/tools/quoteStore.ts
|
|
2281
2680
|
import { randomUUID } from "crypto";
|
|
2282
2681
|
var DEFAULT_TTL_MS = 5 * 60 * 1e3;
|
|
@@ -2326,13 +2725,13 @@ function clearQuoteStore() {
|
|
|
2326
2725
|
}
|
|
2327
2726
|
|
|
2328
2727
|
// src/tools/wdkQuoteSwap.ts
|
|
2329
|
-
import { z as
|
|
2728
|
+
import { z as z23 } from "zod";
|
|
2330
2729
|
import { parseUnits as parseUnits5 } from "viem";
|
|
2331
|
-
var wdkQuoteSwapInputSchema =
|
|
2332
|
-
fromToken:
|
|
2333
|
-
toToken:
|
|
2334
|
-
amount:
|
|
2335
|
-
chain:
|
|
2730
|
+
var wdkQuoteSwapInputSchema = z23.object({
|
|
2731
|
+
fromToken: z23.string().describe('Token to swap from (e.g., "ETH", "USDC")'),
|
|
2732
|
+
toToken: z23.string().describe('Token to swap to (e.g., "USDT0", "USDC")'),
|
|
2733
|
+
amount: z23.string().regex(/^\d+(\.\d+)?$/).describe("Amount to swap (e.g., '1.0')"),
|
|
2734
|
+
chain: z23.string().describe('Chain to execute swap on (e.g., "ethereum", "arbitrum")')
|
|
2336
2735
|
});
|
|
2337
2736
|
async function executeWdkQuoteSwap(input, wdk) {
|
|
2338
2737
|
const decimals = ["USDC", "USDT", "USDT0"].includes(input.fromToken.toUpperCase()) ? 6 : 18;
|
|
@@ -2410,11 +2809,11 @@ function formatSwapQuoteResult(result) {
|
|
|
2410
2809
|
}
|
|
2411
2810
|
|
|
2412
2811
|
// src/tools/wdkExecuteSwap.ts
|
|
2413
|
-
import { z as
|
|
2812
|
+
import { z as z24 } from "zod";
|
|
2414
2813
|
import { parseUnits as parseUnits6 } from "viem";
|
|
2415
|
-
var wdkExecuteSwapInputSchema =
|
|
2416
|
-
quoteId:
|
|
2417
|
-
confirmed:
|
|
2814
|
+
var wdkExecuteSwapInputSchema = z24.object({
|
|
2815
|
+
quoteId: z24.string().uuid().describe("Quote ID from wdk/quoteSwap"),
|
|
2816
|
+
confirmed: z24.boolean().optional().describe("Set to true to confirm and execute this swap")
|
|
2418
2817
|
});
|
|
2419
2818
|
async function executeWdkExecuteSwap(input, wdk) {
|
|
2420
2819
|
const quote = getQuote(input.quoteId);
|
|
@@ -2487,12 +2886,12 @@ function formatExecuteSwapResult(result) {
|
|
|
2487
2886
|
}
|
|
2488
2887
|
|
|
2489
2888
|
// src/tools/quoteBridge.ts
|
|
2490
|
-
import { z as
|
|
2491
|
-
var quoteBridgeInputSchema =
|
|
2492
|
-
fromChain:
|
|
2493
|
-
toChain:
|
|
2494
|
-
amount:
|
|
2495
|
-
recipient:
|
|
2889
|
+
import { z as z25 } from "zod";
|
|
2890
|
+
var quoteBridgeInputSchema = z25.object({
|
|
2891
|
+
fromChain: z25.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Source chain to bridge from"),
|
|
2892
|
+
toChain: z25.enum(["ethereum", "arbitrum", "ink", "berachain", "unichain"]).describe("Destination chain to bridge to"),
|
|
2893
|
+
amount: z25.string().regex(/^\d+(\.\d+)?$/).describe("Amount of USDT0 to bridge (e.g., '100' for 100 USDT0)"),
|
|
2894
|
+
recipient: z25.string().regex(/^0x[a-fA-F0-9]{40}$/).describe("Recipient address on destination chain")
|
|
2496
2895
|
});
|
|
2497
2896
|
async function executeQuoteBridge(input, rpcUrls) {
|
|
2498
2897
|
const feeResult = await executeGetBridgeFee(input, rpcUrls);
|
|
@@ -2560,10 +2959,10 @@ function formatBridgeQuoteResult(result) {
|
|
|
2560
2959
|
}
|
|
2561
2960
|
|
|
2562
2961
|
// src/tools/executeBridgeFromQuote.ts
|
|
2563
|
-
import { z as
|
|
2564
|
-
var executeBridgeFromQuoteInputSchema =
|
|
2565
|
-
quoteId:
|
|
2566
|
-
confirmed:
|
|
2962
|
+
import { z as z26 } from "zod";
|
|
2963
|
+
var executeBridgeFromQuoteInputSchema = z26.object({
|
|
2964
|
+
quoteId: z26.string().uuid().describe("Quote ID from t402/quoteBridge"),
|
|
2965
|
+
confirmed: z26.boolean().optional().describe("Set to true to confirm and execute this bridge")
|
|
2567
2966
|
});
|
|
2568
2967
|
async function executeExecuteBridgeFromQuote(input, options) {
|
|
2569
2968
|
const quote = getQuote(input.quoteId);
|
|
@@ -2622,22 +3021,22 @@ function executeExecuteBridgeFromQuoteDemo(input) {
|
|
|
2622
3021
|
}
|
|
2623
3022
|
|
|
2624
3023
|
// src/tools/unified.ts
|
|
2625
|
-
import { z as
|
|
2626
|
-
var smartPayInputSchema =
|
|
2627
|
-
url:
|
|
2628
|
-
maxBridgeFee:
|
|
2629
|
-
preferredNetwork:
|
|
2630
|
-
confirmed:
|
|
3024
|
+
import { z as z27 } from "zod";
|
|
3025
|
+
var smartPayInputSchema = z27.object({
|
|
3026
|
+
url: z27.string().url().describe("URL of the 402-protected resource"),
|
|
3027
|
+
maxBridgeFee: z27.string().regex(/^\d+(\.\d+)?$/).optional().describe("Maximum acceptable bridge fee in native token (optional)"),
|
|
3028
|
+
preferredNetwork: z27.string().optional().describe("Preferred network for payment (optional)"),
|
|
3029
|
+
confirmed: z27.boolean().optional().describe("Set to true to confirm and execute this payment")
|
|
2631
3030
|
});
|
|
2632
|
-
var paymentPlanInputSchema =
|
|
2633
|
-
paymentRequired:
|
|
2634
|
-
scheme:
|
|
2635
|
-
network:
|
|
2636
|
-
maxAmountRequired:
|
|
2637
|
-
resource:
|
|
2638
|
-
description:
|
|
2639
|
-
payTo:
|
|
2640
|
-
maxDeadline:
|
|
3031
|
+
var paymentPlanInputSchema = z27.object({
|
|
3032
|
+
paymentRequired: z27.object({
|
|
3033
|
+
scheme: z27.string().optional(),
|
|
3034
|
+
network: z27.string().optional(),
|
|
3035
|
+
maxAmountRequired: z27.string().optional(),
|
|
3036
|
+
resource: z27.string().optional(),
|
|
3037
|
+
description: z27.string().optional(),
|
|
3038
|
+
payTo: z27.string().optional(),
|
|
3039
|
+
maxDeadline: z27.number().optional()
|
|
2641
3040
|
}).passthrough().describe("The 402 PaymentRequired response")
|
|
2642
3041
|
});
|
|
2643
3042
|
var UNIFIED_TOOL_DEFINITIONS = {
|
|
@@ -2692,14 +3091,14 @@ async function executeSmartPay(input, wdk) {
|
|
|
2692
3091
|
};
|
|
2693
3092
|
}
|
|
2694
3093
|
const steps = [];
|
|
2695
|
-
const
|
|
3094
|
+
const chains10 = input.preferredNetwork ? [input.preferredNetwork] : ["ethereum", "arbitrum", "base"];
|
|
2696
3095
|
steps.push({
|
|
2697
3096
|
action: "check_balance",
|
|
2698
3097
|
status: "success",
|
|
2699
|
-
detail: `Checking balances on ${
|
|
3098
|
+
detail: `Checking balances on ${chains10.join(", ")}`
|
|
2700
3099
|
});
|
|
2701
3100
|
const { T402Protocol } = await import("@t402/wdk-protocol");
|
|
2702
|
-
const protocol = await T402Protocol.create(wdk, { chains:
|
|
3101
|
+
const protocol = await T402Protocol.create(wdk, { chains: chains10 });
|
|
2703
3102
|
steps.push({
|
|
2704
3103
|
action: "fetch",
|
|
2705
3104
|
status: "success",
|
|
@@ -3260,6 +3659,131 @@ var TOOL_DEFINITIONS = {
|
|
|
3260
3659
|
},
|
|
3261
3660
|
required: ["quoteId"]
|
|
3262
3661
|
}
|
|
3662
|
+
},
|
|
3663
|
+
"t402/signMessage": {
|
|
3664
|
+
name: "t402/signMessage",
|
|
3665
|
+
description: "Sign a message using the configured wallet. Returns an EIP-191 personal signature. Requires a configured private key.",
|
|
3666
|
+
inputSchema: {
|
|
3667
|
+
type: "object",
|
|
3668
|
+
properties: {
|
|
3669
|
+
chain: {
|
|
3670
|
+
type: "string",
|
|
3671
|
+
enum: [
|
|
3672
|
+
"ethereum",
|
|
3673
|
+
"base",
|
|
3674
|
+
"arbitrum",
|
|
3675
|
+
"optimism",
|
|
3676
|
+
"polygon",
|
|
3677
|
+
"avalanche",
|
|
3678
|
+
"ink",
|
|
3679
|
+
"berachain",
|
|
3680
|
+
"unichain"
|
|
3681
|
+
],
|
|
3682
|
+
description: "Blockchain network context for signing"
|
|
3683
|
+
},
|
|
3684
|
+
message: {
|
|
3685
|
+
type: "string",
|
|
3686
|
+
description: "Message to sign"
|
|
3687
|
+
}
|
|
3688
|
+
},
|
|
3689
|
+
required: ["chain", "message"]
|
|
3690
|
+
}
|
|
3691
|
+
},
|
|
3692
|
+
"t402/verifySignature": {
|
|
3693
|
+
name: "t402/verifySignature",
|
|
3694
|
+
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.",
|
|
3695
|
+
inputSchema: {
|
|
3696
|
+
type: "object",
|
|
3697
|
+
properties: {
|
|
3698
|
+
chain: {
|
|
3699
|
+
type: "string",
|
|
3700
|
+
enum: [
|
|
3701
|
+
"ethereum",
|
|
3702
|
+
"base",
|
|
3703
|
+
"arbitrum",
|
|
3704
|
+
"optimism",
|
|
3705
|
+
"polygon",
|
|
3706
|
+
"avalanche",
|
|
3707
|
+
"ink",
|
|
3708
|
+
"berachain",
|
|
3709
|
+
"unichain"
|
|
3710
|
+
],
|
|
3711
|
+
description: "Blockchain network context for verification"
|
|
3712
|
+
},
|
|
3713
|
+
message: {
|
|
3714
|
+
type: "string",
|
|
3715
|
+
description: "The original message that was signed"
|
|
3716
|
+
},
|
|
3717
|
+
signature: {
|
|
3718
|
+
type: "string",
|
|
3719
|
+
pattern: "^0x[a-fA-F0-9]+$",
|
|
3720
|
+
description: "The signature to verify (hex string)"
|
|
3721
|
+
},
|
|
3722
|
+
address: {
|
|
3723
|
+
type: "string",
|
|
3724
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
3725
|
+
description: "The expected signer address"
|
|
3726
|
+
}
|
|
3727
|
+
},
|
|
3728
|
+
required: ["chain", "message", "signature", "address"]
|
|
3729
|
+
}
|
|
3730
|
+
},
|
|
3731
|
+
"t402/getTransferHistory": {
|
|
3732
|
+
name: "t402/getTransferHistory",
|
|
3733
|
+
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.",
|
|
3734
|
+
inputSchema: {
|
|
3735
|
+
type: "object",
|
|
3736
|
+
properties: {
|
|
3737
|
+
network: {
|
|
3738
|
+
type: "string",
|
|
3739
|
+
enum: [
|
|
3740
|
+
"ethereum",
|
|
3741
|
+
"base",
|
|
3742
|
+
"arbitrum",
|
|
3743
|
+
"optimism",
|
|
3744
|
+
"polygon",
|
|
3745
|
+
"avalanche",
|
|
3746
|
+
"ink",
|
|
3747
|
+
"berachain",
|
|
3748
|
+
"unichain"
|
|
3749
|
+
],
|
|
3750
|
+
description: "Blockchain network to query"
|
|
3751
|
+
},
|
|
3752
|
+
address: {
|
|
3753
|
+
type: "string",
|
|
3754
|
+
pattern: "^0x[a-fA-F0-9]{40}$",
|
|
3755
|
+
description: "Wallet address to get transfer history for"
|
|
3756
|
+
},
|
|
3757
|
+
token: {
|
|
3758
|
+
type: "string",
|
|
3759
|
+
enum: ["USDC", "USDT", "USDT0"],
|
|
3760
|
+
description: "Filter by specific token. If not provided, queries all supported stablecoins."
|
|
3761
|
+
},
|
|
3762
|
+
limit: {
|
|
3763
|
+
type: "number",
|
|
3764
|
+
description: "Maximum number of transfers to return (default: 10, max: 100)"
|
|
3765
|
+
}
|
|
3766
|
+
},
|
|
3767
|
+
required: ["network", "address"]
|
|
3768
|
+
}
|
|
3769
|
+
},
|
|
3770
|
+
"t402/getHistoricalPrice": {
|
|
3771
|
+
name: "t402/getHistoricalPrice",
|
|
3772
|
+
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.",
|
|
3773
|
+
inputSchema: {
|
|
3774
|
+
type: "object",
|
|
3775
|
+
properties: {
|
|
3776
|
+
token: {
|
|
3777
|
+
type: "string",
|
|
3778
|
+
description: 'Token symbol (e.g., "ETH", "USDC", "USDT", "MATIC", "AVAX", "BTC", "SOL")'
|
|
3779
|
+
},
|
|
3780
|
+
days: {
|
|
3781
|
+
type: "number",
|
|
3782
|
+
description: "Number of days of history to retrieve (default: 7, max: 365)"
|
|
3783
|
+
}
|
|
3784
|
+
},
|
|
3785
|
+
required: ["token"]
|
|
3786
|
+
}
|
|
3263
3787
|
}
|
|
3264
3788
|
};
|
|
3265
3789
|
var WDK_TOOL_DEFINITIONS = {
|
|
@@ -3581,6 +4105,18 @@ export {
|
|
|
3581
4105
|
compareNetworkFeesInputSchema,
|
|
3582
4106
|
executeCompareNetworkFees,
|
|
3583
4107
|
formatNetworkFeeComparison,
|
|
4108
|
+
signMessageInputSchema,
|
|
4109
|
+
executeSignMessage,
|
|
4110
|
+
formatSignMessageResult,
|
|
4111
|
+
verifySignatureInputSchema,
|
|
4112
|
+
executeVerifySignature,
|
|
4113
|
+
formatVerifySignatureResult,
|
|
4114
|
+
getTransferHistoryInputSchema,
|
|
4115
|
+
executeGetTransferHistory,
|
|
4116
|
+
formatTransferHistoryResult,
|
|
4117
|
+
getHistoricalPriceInputSchema,
|
|
4118
|
+
executeGetHistoricalPrice,
|
|
4119
|
+
formatHistoricalPriceResult,
|
|
3584
4120
|
createQuote,
|
|
3585
4121
|
getQuote,
|
|
3586
4122
|
deleteQuote,
|
|
@@ -3613,4 +4149,4 @@ export {
|
|
|
3613
4149
|
WDK_TOOL_DEFINITIONS,
|
|
3614
4150
|
ERC8004_TOOL_DEFINITIONS
|
|
3615
4151
|
};
|
|
3616
|
-
//# sourceMappingURL=chunk-
|
|
4152
|
+
//# sourceMappingURL=chunk-OSPCSAZF.mjs.map
|