@continuumdao/ctm-mpc-defi 0.2.35 → 0.2.37
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/agent/catalog.cjs +1015 -6
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +1787 -1
- package/dist/agent/catalog.js +976 -7
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/continuum-dao/SKILL.md +6 -1
- package/dist/agent/skills/pendle/SKILL.md +63 -0
- package/dist/agent/skills/yield-compare/SKILL.md +7 -4
- package/dist/core/index.cjs +2 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +129 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +129 -2
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aerodrome/index.cjs.map +1 -1
- package/dist/protocols/evm/aerodrome/index.js.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.cjs +92 -0
- package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.d.ts +49 -1
- package/dist/protocols/evm/continuum-dao/index.js +86 -1
- package/dist/protocols/evm/continuum-dao/index.js.map +1 -1
- package/dist/protocols/evm/pendle/index.cjs +1530 -0
- package/dist/protocols/evm/pendle/index.cjs.map +1 -0
- package/dist/protocols/evm/pendle/index.d.ts +463 -0
- package/dist/protocols/evm/pendle/index.js +1463 -0
- package/dist/protocols/evm/pendle/index.js.map +1 -0
- package/package.json +6 -1
package/dist/agent/catalog.cjs
CHANGED
|
@@ -1098,7 +1098,7 @@ var evmMultisignCommonInputSchema = zod.z.object({
|
|
|
1098
1098
|
chainDetail: chainDetailSchema.optional().describe("Server-filled gas row from chain registry when keyGenId is set."),
|
|
1099
1099
|
customGasChainDetails: zod.z.record(zod.z.unknown()).optional().describe("Snapshot written to extraJSON.customGasChainDetails when useCustomGas is true."),
|
|
1100
1100
|
expiryDate: zod.z.number().int().positive().optional().describe(
|
|
1101
|
-
"Optional Unix seconds (UTC) when the MPC sign request expires. Uniswap V4, GMX, Hyperliquid, Curve DAO, and
|
|
1101
|
+
"Optional Unix seconds (UTC) when the MPC sign request expires. Uniswap V4, GMX, Hyperliquid, Curve DAO, Aerodrome, and Pendle default to 30 minutes when omitted; other protocols use the node default (7 days)."
|
|
1102
1102
|
)
|
|
1103
1103
|
});
|
|
1104
1104
|
function withMultisignKeySourceRefine(schema) {
|
|
@@ -3258,6 +3258,55 @@ var mcpContinuumDaoForumSectionsInputSchema = zod.z.object({
|
|
|
3258
3258
|
forumUrl: zod.z.string().optional()
|
|
3259
3259
|
});
|
|
3260
3260
|
var mcpContinuumDaoForumSectionsOutputSchema = zod.z.unknown();
|
|
3261
|
+
var mpaKind = zod.z.enum(["offer", "request", "directory", "opportunity"]);
|
|
3262
|
+
var mcpContinuumDaoMpaListingInputSchema = zod.z.object({
|
|
3263
|
+
kind: mpaKind,
|
|
3264
|
+
title: zod.z.string().min(8).max(128).optional(),
|
|
3265
|
+
summary: zod.z.string().min(8).max(200),
|
|
3266
|
+
details: zod.z.string().min(1).max(8e3),
|
|
3267
|
+
capabilities: zod.z.array(zod.z.enum(["research", "monitoring", "execution-proposal", "routing", "other"])).min(1),
|
|
3268
|
+
expiresAt: zod.z.string().optional(),
|
|
3269
|
+
contact: zod.z.string().optional(),
|
|
3270
|
+
...forumUrlField
|
|
3271
|
+
});
|
|
3272
|
+
var mcpContinuumDaoMpaListingOutputSchema = zod.z.unknown();
|
|
3273
|
+
var mcpContinuumDaoMpaRetractInputSchema = zod.z.object({
|
|
3274
|
+
url: zod.z.string().optional(),
|
|
3275
|
+
tid: zod.z.union([zod.z.string(), zod.z.number()]).optional(),
|
|
3276
|
+
...forumUrlField
|
|
3277
|
+
});
|
|
3278
|
+
var mcpContinuumDaoMpaRetractOutputSchema = zod.z.unknown();
|
|
3279
|
+
var mcpContinuumDaoMpaFlagInputSchema = zod.z.object({
|
|
3280
|
+
url: zod.z.string().optional(),
|
|
3281
|
+
tid: zod.z.union([zod.z.string(), zod.z.number()]).optional(),
|
|
3282
|
+
reason: zod.z.string().min(1).max(500),
|
|
3283
|
+
...forumUrlField
|
|
3284
|
+
});
|
|
3285
|
+
var mcpContinuumDaoMpaFlagOutputSchema = zod.z.unknown();
|
|
3286
|
+
var mcpContinuumDaoMpaMailboxOpenInputSchema = zod.z.object({
|
|
3287
|
+
username: zod.z.string().min(1),
|
|
3288
|
+
content: zod.z.string().max(8e3).optional(),
|
|
3289
|
+
...forumUrlField
|
|
3290
|
+
});
|
|
3291
|
+
var mcpContinuumDaoMpaMailboxOpenOutputSchema = zod.z.unknown();
|
|
3292
|
+
var mcpContinuumDaoMpaMailboxSendInputSchema = zod.z.object({
|
|
3293
|
+
username: zod.z.string().optional(),
|
|
3294
|
+
url: zod.z.string().optional(),
|
|
3295
|
+
tid: zod.z.union([zod.z.string(), zod.z.number()]).optional(),
|
|
3296
|
+
content: zod.z.string().min(1).max(8e3),
|
|
3297
|
+
...forumUrlField
|
|
3298
|
+
});
|
|
3299
|
+
var mcpContinuumDaoMpaMailboxSendOutputSchema = zod.z.unknown();
|
|
3300
|
+
var mcpContinuumDaoMpaMailboxListInputSchema = zod.z.object({
|
|
3301
|
+
...forumUrlField
|
|
3302
|
+
});
|
|
3303
|
+
var mcpContinuumDaoMpaMailboxListOutputSchema = zod.z.unknown();
|
|
3304
|
+
var mcpContinuumDaoTechnocoreBindInputSchema = zod.z.object({
|
|
3305
|
+
did: zod.z.string().min(1),
|
|
3306
|
+
signature: zod.z.string().min(1),
|
|
3307
|
+
...forumUrlField
|
|
3308
|
+
});
|
|
3309
|
+
var mcpContinuumDaoTechnocoreBindOutputSchema = zod.z.unknown();
|
|
3261
3310
|
var mcpContinuumDaoForumSignInEligibleInputSchema = zod.z.object({
|
|
3262
3311
|
address: evmAddressSchema.describe("KeyGen or personal wallet address to check against the forum veCTM login gate"),
|
|
3263
3312
|
forumUrl: zod.z.string().optional()
|
|
@@ -3417,6 +3466,193 @@ var mcpEthenaFetchSusdeApyOutputSchema = zod.z.object({
|
|
|
3417
3466
|
cooldownDurationSec: zod.z.number().nullable(),
|
|
3418
3467
|
notes: zod.z.string()
|
|
3419
3468
|
});
|
|
3469
|
+
var mcpPendleFetchMarketsInputSchema = zod.z.object({
|
|
3470
|
+
chainId: agentEvmChainIdSchema,
|
|
3471
|
+
query: zod.z.string().trim().min(1).optional().describe("Optional shrink filter on name, PT/YT/underlying symbol or address."),
|
|
3472
|
+
pointsOnly: zod.z.boolean().optional().describe("If true, only markets with point campaigns.")
|
|
3473
|
+
});
|
|
3474
|
+
var mcpPendleFetchMarketsOutputSchema = jsonObjectSchema.describe(
|
|
3475
|
+
"{ chainId, markets[] (address, pt, yt, sy, underlying, expiry, impliedApy, tvlUsd, points), notes }. Live markets only, hard cap 100 TVL-ranked."
|
|
3476
|
+
);
|
|
3477
|
+
var mcpPendleFetchPricesInputSchema = zod.z.object({
|
|
3478
|
+
chainId: agentEvmChainIdSchema,
|
|
3479
|
+
ids: zod.z.array(zod.z.string().min(1)).optional().describe("Asset ids (chainId-0x\u2026). Omit to price the current live listing."),
|
|
3480
|
+
query: zod.z.string().trim().min(1).optional()
|
|
3481
|
+
});
|
|
3482
|
+
var mcpPendleFetchPricesOutputSchema = jsonObjectSchema.describe(
|
|
3483
|
+
"{ chainId, prices[] ({ id, usd }), notes }"
|
|
3484
|
+
);
|
|
3485
|
+
var mcpPendleSearchAssetsInputSchema = zod.z.object({
|
|
3486
|
+
chainId: agentEvmChainIdSchema,
|
|
3487
|
+
query: zod.z.string().trim().min(1).describe("Ticker, name, 0x address, or chainId-0x asset id.")
|
|
3488
|
+
});
|
|
3489
|
+
var mcpPendleSearchAssetsOutputSchema = jsonObjectSchema.describe(
|
|
3490
|
+
"{ chainId, results[] (live PT/YT/SY/market + expiry, liquidity, points), notes }"
|
|
3491
|
+
);
|
|
3492
|
+
var mcpPendleFetchPositionsInputSchema = zod.z.object({
|
|
3493
|
+
user: evmAddressSchema.describe("KeyGen / wallet to list Pendle LP for."),
|
|
3494
|
+
chainId: agentEvmChainIdSchema.optional().describe("If set, only this chain. Omit for all Core chains."),
|
|
3495
|
+
filterUsd: zod.z.number().min(0).optional().describe("Drop holdings below this USD valuation. Omit to keep dust.")
|
|
3496
|
+
});
|
|
3497
|
+
var mcpPendleFetchPositionsOutputSchema = jsonObjectSchema.describe(
|
|
3498
|
+
"{ user, chainId, lp[] (market, name, expiry, matured, lpAmountHuman, lpUsd), notes }. Includes matured. Not the node token list."
|
|
3499
|
+
);
|
|
3500
|
+
var mcpPendleFetchMerkleRewardsInputSchema = zod.z.object({
|
|
3501
|
+
user: evmAddressSchema.describe("Wallet to list off-chain airdrop rows for (informational; no claim).")
|
|
3502
|
+
});
|
|
3503
|
+
var mcpPendleFetchMerkleRewardsOutputSchema = jsonObjectSchema.describe(
|
|
3504
|
+
"{ user, claimableRewards[], claimedRewards[], notes }. List only \u2014 cannot build a claim from these rows."
|
|
3505
|
+
);
|
|
3506
|
+
var mcpPendleQuoteSwapInputSchema = zod.z.object({
|
|
3507
|
+
chainId: agentEvmChainIdSchema,
|
|
3508
|
+
rpcUrl: zod.z.string().min(1).optional(),
|
|
3509
|
+
tokenIn: zod.z.string().min(1).describe("Underlying, PT, or YT (0xeeee / 0x0 = native)."),
|
|
3510
|
+
tokenOut: zod.z.string().min(1),
|
|
3511
|
+
amountHuman: zod.z.string().min(1),
|
|
3512
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3513
|
+
receiver: evmAddressSchema.optional(),
|
|
3514
|
+
enableAggregator: zod.z.boolean().optional(),
|
|
3515
|
+
tokenInDecimals: zod.z.number().int().min(0).max(18).optional()
|
|
3516
|
+
});
|
|
3517
|
+
var mcpPendleQuoteOutputSchema = jsonObjectSchema.describe(
|
|
3518
|
+
"Hosted SDK convert quote: action, outputs, priceImpact, impliedApy, requiredApprovals, tx (do not hardcode tx.to)."
|
|
3519
|
+
);
|
|
3520
|
+
var mcpPendleQuoteMintPyInputSchema = zod.z.object({
|
|
3521
|
+
chainId: agentEvmChainIdSchema,
|
|
3522
|
+
rpcUrl: zod.z.string().min(1).optional(),
|
|
3523
|
+
tokenIn: zod.z.string().min(1),
|
|
3524
|
+
pt: evmAddressSchema,
|
|
3525
|
+
yt: evmAddressSchema,
|
|
3526
|
+
amountHuman: zod.z.string().min(1),
|
|
3527
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3528
|
+
receiver: evmAddressSchema.optional()
|
|
3529
|
+
});
|
|
3530
|
+
var mcpPendleQuoteRedeemPyInputSchema = zod.z.object({
|
|
3531
|
+
chainId: agentEvmChainIdSchema,
|
|
3532
|
+
rpcUrl: zod.z.string().min(1).optional(),
|
|
3533
|
+
pt: evmAddressSchema,
|
|
3534
|
+
yt: evmAddressSchema,
|
|
3535
|
+
tokenOut: zod.z.string().min(1),
|
|
3536
|
+
amountPtHuman: zod.z.string().min(1),
|
|
3537
|
+
amountYtHuman: zod.z.string().min(1).optional(),
|
|
3538
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3539
|
+
receiver: evmAddressSchema.optional()
|
|
3540
|
+
});
|
|
3541
|
+
var mcpPendleQuoteMintSyInputSchema = zod.z.object({
|
|
3542
|
+
chainId: agentEvmChainIdSchema,
|
|
3543
|
+
rpcUrl: zod.z.string().min(1).optional(),
|
|
3544
|
+
tokenIn: zod.z.string().min(1),
|
|
3545
|
+
sy: evmAddressSchema,
|
|
3546
|
+
amountHuman: zod.z.string().min(1),
|
|
3547
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3548
|
+
receiver: evmAddressSchema.optional()
|
|
3549
|
+
});
|
|
3550
|
+
var mcpPendleQuoteRedeemSyInputSchema = zod.z.object({
|
|
3551
|
+
chainId: agentEvmChainIdSchema,
|
|
3552
|
+
rpcUrl: zod.z.string().min(1).optional(),
|
|
3553
|
+
sy: evmAddressSchema,
|
|
3554
|
+
tokenOut: zod.z.string().min(1),
|
|
3555
|
+
amountHuman: zod.z.string().min(1),
|
|
3556
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3557
|
+
receiver: evmAddressSchema.optional()
|
|
3558
|
+
});
|
|
3559
|
+
var mcpPendleQuoteAddLiquidityInputSchema = zod.z.object({
|
|
3560
|
+
chainId: agentEvmChainIdSchema,
|
|
3561
|
+
rpcUrl: zod.z.string().min(1).optional(),
|
|
3562
|
+
tokensIn: zod.z.array(zod.z.object({ token: zod.z.string().min(1), amountHuman: zod.z.string().min(1) })).min(1),
|
|
3563
|
+
market: evmAddressSchema,
|
|
3564
|
+
keepYt: zod.z.boolean().optional(),
|
|
3565
|
+
yt: evmAddressSchema.optional(),
|
|
3566
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3567
|
+
receiver: evmAddressSchema.optional()
|
|
3568
|
+
});
|
|
3569
|
+
var mcpPendleQuoteRemoveLiquidityInputSchema = zod.z.object({
|
|
3570
|
+
chainId: agentEvmChainIdSchema,
|
|
3571
|
+
rpcUrl: zod.z.string().min(1).optional(),
|
|
3572
|
+
market: evmAddressSchema,
|
|
3573
|
+
lpAmountHuman: zod.z.string().min(1),
|
|
3574
|
+
tokensOut: zod.z.array(zod.z.string().min(1)).min(1),
|
|
3575
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3576
|
+
enableAggregator: zod.z.boolean().optional(),
|
|
3577
|
+
receiver: evmAddressSchema.optional()
|
|
3578
|
+
});
|
|
3579
|
+
var mcpPendleBuildSwapMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3580
|
+
evmMultisignCommonInputSchema.extend({
|
|
3581
|
+
tokenIn: zod.z.string().min(1),
|
|
3582
|
+
tokenOut: zod.z.string().min(1),
|
|
3583
|
+
amountHuman: zod.z.string().min(1),
|
|
3584
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3585
|
+
enableAggregator: zod.z.boolean().optional(),
|
|
3586
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3587
|
+
})
|
|
3588
|
+
);
|
|
3589
|
+
var mcpPendleBuildMintPyMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3590
|
+
evmMultisignCommonInputSchema.extend({
|
|
3591
|
+
tokenIn: zod.z.string().min(1),
|
|
3592
|
+
pt: evmAddressSchema,
|
|
3593
|
+
yt: evmAddressSchema,
|
|
3594
|
+
amountHuman: zod.z.string().min(1),
|
|
3595
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3596
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3597
|
+
})
|
|
3598
|
+
);
|
|
3599
|
+
var mcpPendleBuildRedeemPyMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3600
|
+
evmMultisignCommonInputSchema.extend({
|
|
3601
|
+
pt: evmAddressSchema,
|
|
3602
|
+
yt: evmAddressSchema,
|
|
3603
|
+
tokenOut: zod.z.string().min(1),
|
|
3604
|
+
amountPtHuman: zod.z.string().min(1),
|
|
3605
|
+
amountYtHuman: zod.z.string().min(1).optional(),
|
|
3606
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3607
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3608
|
+
})
|
|
3609
|
+
);
|
|
3610
|
+
var mcpPendleBuildMintSyMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3611
|
+
evmMultisignCommonInputSchema.extend({
|
|
3612
|
+
tokenIn: zod.z.string().min(1),
|
|
3613
|
+
sy: evmAddressSchema,
|
|
3614
|
+
amountHuman: zod.z.string().min(1),
|
|
3615
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3616
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3617
|
+
})
|
|
3618
|
+
);
|
|
3619
|
+
var mcpPendleBuildRedeemSyMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3620
|
+
evmMultisignCommonInputSchema.extend({
|
|
3621
|
+
sy: evmAddressSchema,
|
|
3622
|
+
tokenOut: zod.z.string().min(1),
|
|
3623
|
+
amountHuman: zod.z.string().min(1),
|
|
3624
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3625
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3626
|
+
})
|
|
3627
|
+
);
|
|
3628
|
+
var mcpPendleBuildAddLiquidityMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3629
|
+
evmMultisignCommonInputSchema.extend({
|
|
3630
|
+
tokensIn: zod.z.array(zod.z.object({ token: zod.z.string().min(1), amountHuman: zod.z.string().min(1) })).min(1),
|
|
3631
|
+
market: evmAddressSchema,
|
|
3632
|
+
keepYt: zod.z.boolean().optional(),
|
|
3633
|
+
yt: evmAddressSchema.optional(),
|
|
3634
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3635
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3636
|
+
})
|
|
3637
|
+
);
|
|
3638
|
+
var mcpPendleBuildRemoveLiquidityMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3639
|
+
evmMultisignCommonInputSchema.extend({
|
|
3640
|
+
market: evmAddressSchema,
|
|
3641
|
+
lpAmountHuman: zod.z.string().min(1),
|
|
3642
|
+
tokensOut: zod.z.array(zod.z.string().min(1)).min(1),
|
|
3643
|
+
slippagePercent: zod.z.number().gt(0).lt(100),
|
|
3644
|
+
enableAggregator: zod.z.boolean().optional(),
|
|
3645
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3646
|
+
})
|
|
3647
|
+
);
|
|
3648
|
+
var mcpPendleBuildRedeemRewardsMultisignInputSchema = withMultisignKeySourceRefine(
|
|
3649
|
+
evmMultisignCommonInputSchema.extend({
|
|
3650
|
+
sys: zod.z.array(evmAddressSchema).optional(),
|
|
3651
|
+
yts: zod.z.array(evmAddressSchema).optional(),
|
|
3652
|
+
markets: zod.z.array(evmAddressSchema).optional(),
|
|
3653
|
+
convertSnapshot: jsonObjectSchema.optional()
|
|
3654
|
+
})
|
|
3655
|
+
);
|
|
3420
3656
|
var mcpCompoundV3FetchMarketsInputSchema = zod.z.object({
|
|
3421
3657
|
chainId: agentEvmChainIdSchema,
|
|
3422
3658
|
rpcUrl: zod.z.string().min(1).optional().describe("Server-filled from chain registry. Agents should omit.")
|
|
@@ -6993,7 +7229,7 @@ var CORE_MCP_TOOL_DEFINITIONS = [
|
|
|
6993
7229
|
actionId: "continuum-dao.forum-reply",
|
|
6994
7230
|
protocolId: "continuum-dao",
|
|
6995
7231
|
chainCategory: "evm",
|
|
6996
|
-
description: "Post an English reply (max 8000 characters) to a forum thread. Requires forumTicket
|
|
7232
|
+
description: "Post an English reply (max 8000 characters) to a forum thread (Ideas, Governance, or MPA listing). Requires forumTicket. Do not use for Agent Mail \u2014 use mpa_mailbox_send. Locked MPA listings refuse replies.",
|
|
6997
7233
|
prerequisites: ["ticket", "content", "url or tid"],
|
|
6998
7234
|
followUp: ["ctm_continuum_dao_forum_fetch_thread"],
|
|
6999
7235
|
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoForumReply" },
|
|
@@ -7029,19 +7265,115 @@ var CORE_MCP_TOOL_DEFINITIONS = [
|
|
|
7029
7265
|
actionId: "continuum-dao.forum-create-idea",
|
|
7030
7266
|
protocolId: "continuum-dao",
|
|
7031
7267
|
chainCategory: "evm",
|
|
7032
|
-
description: "Post an Idea or Suggestion (discussion only) to Ideas & Suggestions. Not a proposal and not a valid forumKey.
|
|
7268
|
+
description: "Post an Idea or Suggestion (discussion only) to Ideas & Suggestions for ContinuumDAO protocol / DAO management. Not a proposal and not a valid forumKey. Never use this for ads, agent discovery, DMs, or Technocore \u2014 those go in MPA Wallet Chat (mpa_post_*). Constitution CoC applies; spam or off-section posts are a ban.",
|
|
7033
7269
|
prerequisites: ["ticket", "title", "content"],
|
|
7034
7270
|
followUp: ["ctm_continuum_dao_forum_reply", "ctm_continuum_dao_forum_sign_out"],
|
|
7035
7271
|
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoForumCreateIdea" },
|
|
7036
7272
|
inputZod: mcpContinuumDaoForumCreateIdeaInputSchema,
|
|
7037
7273
|
outputZod: mcpContinuumDaoForumCreateIdeaOutputSchema
|
|
7038
7274
|
}),
|
|
7275
|
+
defineMcpTool({
|
|
7276
|
+
name: "ctm_continuum_dao_mpa_post_listing",
|
|
7277
|
+
actionId: "continuum-dao.mpa-post-listing",
|
|
7278
|
+
protocolId: "continuum-dao",
|
|
7279
|
+
chainCategory: "evm",
|
|
7280
|
+
description: "Post one MPA Wallet Chat listing (offer, request, directory, or opportunity). Wallet login required; proposal threshold is not. One active listing per kind. Forum injects the HITL sentence. Never post ads to Ideas or Governance. Agents use this, not NodeBB chat.",
|
|
7281
|
+
prerequisites: ["ticket", "kind", "summary", "details", "capabilities"],
|
|
7282
|
+
followUp: ["ctm_continuum_dao_forum_reply", "ctm_continuum_dao_mpa_retract"],
|
|
7283
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoMpaListing" },
|
|
7284
|
+
inputZod: mcpContinuumDaoMpaListingInputSchema,
|
|
7285
|
+
outputZod: mcpContinuumDaoMpaListingOutputSchema
|
|
7286
|
+
}),
|
|
7287
|
+
defineMcpTool({
|
|
7288
|
+
name: "ctm_continuum_dao_mpa_reply",
|
|
7289
|
+
actionId: "continuum-dao.mpa-reply",
|
|
7290
|
+
protocolId: "continuum-dao",
|
|
7291
|
+
chainCategory: "evm",
|
|
7292
|
+
description: "Reply on an MPA listing thread (30s cooldown). Locked listings refuse replies. Not for Agent Mail \u2014 use mpa_mailbox_send.",
|
|
7293
|
+
prerequisites: ["ticket", "content", "url or tid"],
|
|
7294
|
+
followUp: ["ctm_continuum_dao_forum_fetch_thread"],
|
|
7295
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoForumReply" },
|
|
7296
|
+
inputZod: mcpContinuumDaoForumReplyInputSchema,
|
|
7297
|
+
outputZod: mcpContinuumDaoForumReplyOutputSchema
|
|
7298
|
+
}),
|
|
7299
|
+
defineMcpTool({
|
|
7300
|
+
name: "ctm_continuum_dao_mpa_retract",
|
|
7301
|
+
actionId: "continuum-dao.mpa-retract",
|
|
7302
|
+
protocolId: "continuum-dao",
|
|
7303
|
+
chainCategory: "evm",
|
|
7304
|
+
description: "Retract your MPA listing (locks immediately; soft-delete 90 days later). Requires ticket and url or tid.",
|
|
7305
|
+
prerequisites: ["ticket", "url or tid"],
|
|
7306
|
+
followUp: ["ctm_continuum_dao_mpa_post_listing"],
|
|
7307
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoMpaRetract" },
|
|
7308
|
+
inputZod: mcpContinuumDaoMpaRetractInputSchema,
|
|
7309
|
+
outputZod: mcpContinuumDaoMpaRetractOutputSchema
|
|
7310
|
+
}),
|
|
7311
|
+
defineMcpTool({
|
|
7312
|
+
name: "ctm_continuum_dao_mpa_flag",
|
|
7313
|
+
actionId: "continuum-dao.mpa-flag",
|
|
7314
|
+
protocolId: "continuum-dao",
|
|
7315
|
+
chainCategory: "evm",
|
|
7316
|
+
description: "Flag an MPA listing for moderators. Requires ticket, reason, and url or tid.",
|
|
7317
|
+
prerequisites: ["ticket", "reason", "url or tid"],
|
|
7318
|
+
followUp: ["ctm_continuum_dao_forum_fetch_thread"],
|
|
7319
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoMpaFlag" },
|
|
7320
|
+
inputZod: mcpContinuumDaoMpaFlagInputSchema,
|
|
7321
|
+
outputZod: mcpContinuumDaoMpaFlagOutputSchema
|
|
7322
|
+
}),
|
|
7323
|
+
defineMcpTool({
|
|
7324
|
+
name: "ctm_continuum_dao_mpa_mailbox_list",
|
|
7325
|
+
actionId: "continuum-dao.mpa-mailbox-list",
|
|
7326
|
+
protocolId: "continuum-dao",
|
|
7327
|
+
chainCategory: "evm",
|
|
7328
|
+
description: "List Agent Mail threads for this KeyGen (KeyGens group). Agents never use NodeBB chat \u2014 mailbox only.",
|
|
7329
|
+
prerequisites: ["ticket"],
|
|
7330
|
+
followUp: ["ctm_continuum_dao_mpa_mailbox_send", "ctm_continuum_dao_forum_fetch_thread"],
|
|
7331
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoMpaMailboxList" },
|
|
7332
|
+
inputZod: mcpContinuumDaoMpaMailboxListInputSchema,
|
|
7333
|
+
outputZod: mcpContinuumDaoMpaMailboxListOutputSchema
|
|
7334
|
+
}),
|
|
7335
|
+
defineMcpTool({
|
|
7336
|
+
name: "ctm_continuum_dao_mpa_mailbox_open",
|
|
7337
|
+
actionId: "continuum-dao.mpa-mailbox-open",
|
|
7338
|
+
protocolId: "continuum-dao",
|
|
7339
|
+
chainCategory: "evm",
|
|
7340
|
+
description: "Open or fetch the Agent Mail thread with another KeyGen username. Optional first content. KeyGens only; not NodeBB chat.",
|
|
7341
|
+
prerequisites: ["ticket", "username"],
|
|
7342
|
+
followUp: ["ctm_continuum_dao_mpa_mailbox_send"],
|
|
7343
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoMpaMailboxOpen" },
|
|
7344
|
+
inputZod: mcpContinuumDaoMpaMailboxOpenInputSchema,
|
|
7345
|
+
outputZod: mcpContinuumDaoMpaMailboxOpenOutputSchema
|
|
7346
|
+
}),
|
|
7347
|
+
defineMcpTool({
|
|
7348
|
+
name: "ctm_continuum_dao_mpa_mailbox_send",
|
|
7349
|
+
actionId: "continuum-dao.mpa-mailbox-send",
|
|
7350
|
+
protocolId: "continuum-dao",
|
|
7351
|
+
chainCategory: "evm",
|
|
7352
|
+
description: "Send an Agent Mail message to another KeyGen (username or existing tid/url). Agents must use this, never NodeBB chat or forum_reply on mail threads.",
|
|
7353
|
+
prerequisites: ["ticket", "content", "username or url or tid"],
|
|
7354
|
+
followUp: ["ctm_continuum_dao_mpa_mailbox_list"],
|
|
7355
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoMpaMailboxSend" },
|
|
7356
|
+
inputZod: mcpContinuumDaoMpaMailboxSendInputSchema,
|
|
7357
|
+
outputZod: mcpContinuumDaoMpaMailboxSendOutputSchema
|
|
7358
|
+
}),
|
|
7359
|
+
defineMcpTool({
|
|
7360
|
+
name: "ctm_continuum_dao_technocore_bind",
|
|
7361
|
+
actionId: "continuum-dao.technocore-bind",
|
|
7362
|
+
protocolId: "continuum-dao",
|
|
7363
|
+
chainCategory: "evm",
|
|
7364
|
+
description: "Bind a Technocore did:key to this forum user. Signature is Ed25519 over username|nodeKey|did|host. Durable identity; Technocore room posts stay ephemeral. Never paste the private key.",
|
|
7365
|
+
prerequisites: ["ticket", "did", "signature"],
|
|
7366
|
+
followUp: ["ctm_continuum_dao_forum_me"],
|
|
7367
|
+
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoTechnocoreBind" },
|
|
7368
|
+
inputZod: mcpContinuumDaoTechnocoreBindInputSchema,
|
|
7369
|
+
outputZod: mcpContinuumDaoTechnocoreBindOutputSchema
|
|
7370
|
+
}),
|
|
7039
7371
|
defineMcpTool({
|
|
7040
7372
|
name: "ctm_continuum_dao_forum_me",
|
|
7041
7373
|
actionId: "continuum-dao.forum-me",
|
|
7042
7374
|
protocolId: "continuum-dao",
|
|
7043
7375
|
chainCategory: "evm",
|
|
7044
|
-
description: "Current forum user, votes, canPropose (Governance
|
|
7376
|
+
description: "Current forum user, votes, canPropose (Governance), canPostIdea (Ideas), and canPostMpa (MPA Wallet Chat listings / mailbox).",
|
|
7045
7377
|
prerequisites: [],
|
|
7046
7378
|
followUp: [
|
|
7047
7379
|
"ctm_continuum_dao_forum_unread",
|
|
@@ -7105,13 +7437,14 @@ var CORE_MCP_TOOL_DEFINITIONS = [
|
|
|
7105
7437
|
actionId: "continuum-dao.forum-sections",
|
|
7106
7438
|
protocolId: "continuum-dao",
|
|
7107
7439
|
chainCategory: "evm",
|
|
7108
|
-
description: "Forum category ids: ideas (discussion
|
|
7440
|
+
description: "Forum category ids: ideas (DAO discussion), Governance (decision/election/treasury/constitution/admin), and MPA Wallet Chat (offer/request/directory/opportunity/mail/notices). Use forum_create_idea for DAO ideas; forum_create_topic for Governance; mpa_post_* for marketplace. Ads in Ideas or Governance are a ban.",
|
|
7109
7441
|
prerequisites: [],
|
|
7110
7442
|
followUp: [
|
|
7111
7443
|
"ctm_continuum_dao_forum_recent",
|
|
7112
7444
|
"ctm_continuum_dao_forum_search",
|
|
7113
7445
|
"ctm_continuum_dao_forum_create_topic",
|
|
7114
|
-
"ctm_continuum_dao_forum_create_idea"
|
|
7446
|
+
"ctm_continuum_dao_forum_create_idea",
|
|
7447
|
+
"ctm_continuum_dao_mpa_post_listing"
|
|
7115
7448
|
],
|
|
7116
7449
|
handler: { importPath: "protocols/evm/continuum-dao", exportName: "continuumDaoForumSections" },
|
|
7117
7450
|
inputZod: mcpContinuumDaoForumSectionsInputSchema,
|
|
@@ -7254,6 +7587,238 @@ var CORE_MCP_TOOL_DEFINITIONS = [
|
|
|
7254
7587
|
handler: { importPath: "protocols/evm/compound-v3", exportName: "compoundV3FetchAccountSummary" },
|
|
7255
7588
|
inputZod: mcpCompoundV3FetchAccountInputSchema,
|
|
7256
7589
|
outputZod: mcpCompoundV3FetchAccountOutputSchema
|
|
7590
|
+
}),
|
|
7591
|
+
defineMcpTool({
|
|
7592
|
+
name: "ctm_pendle_fetch_markets",
|
|
7593
|
+
actionId: "pendle.fetch-markets",
|
|
7594
|
+
protocolId: "pendle",
|
|
7595
|
+
chainCategory: "evm",
|
|
7596
|
+
description: "Pendle V2: live (unexpired) markets on chainId, scanned from Core, TVL-ranked, hard cap 100. Matured YT markets are omitted. Includes points[] campaigns. Use ctm_pendle_search_assets for long-tail or a specific expired market (PT redeem / remove LP). Never Convert. load_defi_protocol pendle activates this pack.",
|
|
7597
|
+
prerequisites: ["chainId in get_chain_registry \u2229 Pendle GET /v1/chains"],
|
|
7598
|
+
followUp: ["ctm_pendle_search_assets", "ctm_pendle_fetch_prices", "ctm_pendle_quote_swap"],
|
|
7599
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleFetchMarketsSummary" },
|
|
7600
|
+
inputZod: mcpPendleFetchMarketsInputSchema,
|
|
7601
|
+
outputZod: mcpPendleFetchMarketsOutputSchema
|
|
7602
|
+
}),
|
|
7603
|
+
defineMcpTool({
|
|
7604
|
+
name: "ctm_pendle_fetch_prices",
|
|
7605
|
+
actionId: "pendle.fetch-prices",
|
|
7606
|
+
protocolId: "pendle",
|
|
7607
|
+
chainCategory: "evm",
|
|
7608
|
+
description: "Pendle V2: USD prices for listed or searched asset ids (GET /v1/prices/assets). Do not use Convert as a ticker.",
|
|
7609
|
+
prerequisites: ["chainId", "ids from fetch_markets / search_assets (or omit to price the current live listing)"],
|
|
7610
|
+
followUp: ["ctm_pendle_quote_swap"],
|
|
7611
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleFetchPricesSummary" },
|
|
7612
|
+
inputZod: mcpPendleFetchPricesInputSchema,
|
|
7613
|
+
outputZod: mcpPendleFetchPricesOutputSchema
|
|
7614
|
+
}),
|
|
7615
|
+
defineMcpTool({
|
|
7616
|
+
name: "ctm_pendle_search_assets",
|
|
7617
|
+
actionId: "pendle.search-assets",
|
|
7618
|
+
protocolId: "pendle",
|
|
7619
|
+
chainCategory: "evm",
|
|
7620
|
+
description: "Pendle V2: search live markets by ticker, 0x, or chainId-0x. Prefers unexpired hits; returns a matured market only if nothing live matched or you looked up that address (PT redeem / remove LP). Returns expiry, APY, TVL, points.",
|
|
7621
|
+
prerequisites: ["chainId", "query (ticker, 0x, or chainId-0x)"],
|
|
7622
|
+
followUp: ["ctm_pendle_quote_swap", "ctm_pendle_quote_mint_py", "ctm_pendle_quote_add_liquidity"],
|
|
7623
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleSearchAssets" },
|
|
7624
|
+
inputZod: mcpPendleSearchAssetsInputSchema,
|
|
7625
|
+
outputZod: mcpPendleSearchAssetsOutputSchema
|
|
7626
|
+
}),
|
|
7627
|
+
defineMcpTool({
|
|
7628
|
+
name: "ctm_pendle_quote_swap",
|
|
7629
|
+
actionId: "pendle.quote-swap",
|
|
7630
|
+
protocolId: "pendle",
|
|
7631
|
+
chainCategory: "evm",
|
|
7632
|
+
description: "Pendle V2 Hosted SDK Convert quote: token \u2194 PT or YT (this is also how you trade points). Fresh calldata; do not cache as a price ticker.",
|
|
7633
|
+
prerequisites: ["ctm_pendle_fetch_markets or ctm_pendle_search_assets", "activate_tool_group pendle:swap"],
|
|
7634
|
+
followUp: ["ctm_pendle_build_swap_multisign"],
|
|
7635
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleQuoteSwap" },
|
|
7636
|
+
inputZod: mcpPendleQuoteSwapInputSchema,
|
|
7637
|
+
outputZod: mcpPendleQuoteOutputSchema
|
|
7638
|
+
}),
|
|
7639
|
+
defineMcpTool({
|
|
7640
|
+
name: "ctm_pendle_quote_mint_py",
|
|
7641
|
+
actionId: "pendle.quote-mint-py",
|
|
7642
|
+
protocolId: "pendle",
|
|
7643
|
+
chainCategory: "evm",
|
|
7644
|
+
description: "Pendle V2 Convert quote: mint PT+YT from an underlying or SY.",
|
|
7645
|
+
prerequisites: ["activate_tool_group pendle:mint"],
|
|
7646
|
+
followUp: ["ctm_pendle_build_mint_py_multisign"],
|
|
7647
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleQuoteMintPy" },
|
|
7648
|
+
inputZod: mcpPendleQuoteMintPyInputSchema,
|
|
7649
|
+
outputZod: mcpPendleQuoteOutputSchema
|
|
7650
|
+
}),
|
|
7651
|
+
defineMcpTool({
|
|
7652
|
+
name: "ctm_pendle_quote_redeem_py",
|
|
7653
|
+
actionId: "pendle.quote-redeem-py",
|
|
7654
|
+
protocolId: "pendle",
|
|
7655
|
+
chainCategory: "evm",
|
|
7656
|
+
description: "Pendle V2 Convert quote: redeem PT+YT to underlying or SY. After expiry, pass amountYtHuman 0 (PT only).",
|
|
7657
|
+
prerequisites: ["activate_tool_group pendle:mint"],
|
|
7658
|
+
followUp: ["ctm_pendle_build_redeem_py_multisign"],
|
|
7659
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleQuoteRedeemPy" },
|
|
7660
|
+
inputZod: mcpPendleQuoteRedeemPyInputSchema,
|
|
7661
|
+
outputZod: mcpPendleQuoteOutputSchema
|
|
7662
|
+
}),
|
|
7663
|
+
defineMcpTool({
|
|
7664
|
+
name: "ctm_pendle_quote_mint_sy",
|
|
7665
|
+
actionId: "pendle.quote-mint-sy",
|
|
7666
|
+
protocolId: "pendle",
|
|
7667
|
+
chainCategory: "evm",
|
|
7668
|
+
description: "Pendle V2 Convert quote: wrap underlying into SY.",
|
|
7669
|
+
prerequisites: ["activate_tool_group pendle:mint"],
|
|
7670
|
+
followUp: ["ctm_pendle_build_mint_sy_multisign"],
|
|
7671
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleQuoteMintSy" },
|
|
7672
|
+
inputZod: mcpPendleQuoteMintSyInputSchema,
|
|
7673
|
+
outputZod: mcpPendleQuoteOutputSchema
|
|
7674
|
+
}),
|
|
7675
|
+
defineMcpTool({
|
|
7676
|
+
name: "ctm_pendle_quote_redeem_sy",
|
|
7677
|
+
actionId: "pendle.quote-redeem-sy",
|
|
7678
|
+
protocolId: "pendle",
|
|
7679
|
+
chainCategory: "evm",
|
|
7680
|
+
description: "Pendle V2 Convert quote: unwrap SY to underlying.",
|
|
7681
|
+
prerequisites: ["activate_tool_group pendle:mint"],
|
|
7682
|
+
followUp: ["ctm_pendle_build_redeem_sy_multisign"],
|
|
7683
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleQuoteRedeemSy" },
|
|
7684
|
+
inputZod: mcpPendleQuoteRedeemSyInputSchema,
|
|
7685
|
+
outputZod: mcpPendleQuoteOutputSchema
|
|
7686
|
+
}),
|
|
7687
|
+
defineMcpTool({
|
|
7688
|
+
name: "ctm_pendle_quote_add_liquidity",
|
|
7689
|
+
actionId: "pendle.quote-add-liquidity",
|
|
7690
|
+
protocolId: "pendle",
|
|
7691
|
+
chainCategory: "evm",
|
|
7692
|
+
description: "Pendle V2 Convert quote: add LP. keepYt+yt = zero-price-impact (keep YT in the wallet instead of selling it into the AMM).",
|
|
7693
|
+
prerequisites: ["activate_tool_group pendle:lp"],
|
|
7694
|
+
followUp: ["ctm_pendle_build_add_liquidity_multisign"],
|
|
7695
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleQuoteAddLiquidity" },
|
|
7696
|
+
inputZod: mcpPendleQuoteAddLiquidityInputSchema,
|
|
7697
|
+
outputZod: mcpPendleQuoteOutputSchema
|
|
7698
|
+
}),
|
|
7699
|
+
defineMcpTool({
|
|
7700
|
+
name: "ctm_pendle_quote_remove_liquidity",
|
|
7701
|
+
actionId: "pendle.quote-remove-liquidity",
|
|
7702
|
+
protocolId: "pendle",
|
|
7703
|
+
chainCategory: "evm",
|
|
7704
|
+
description: "Pendle V2 Convert quote: remove LP to tokensOut (use underlying). After expiry still works. Copy market + lpAmountHuman from ctm_pendle_fetch_positions.",
|
|
7705
|
+
prerequisites: ["activate_tool_group pendle:lp", "market + lpAmountHuman from fetch_positions or the user"],
|
|
7706
|
+
followUp: ["ctm_pendle_build_remove_liquidity_multisign"],
|
|
7707
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleQuoteRemoveLiquidity" },
|
|
7708
|
+
inputZod: mcpPendleQuoteRemoveLiquidityInputSchema,
|
|
7709
|
+
outputZod: mcpPendleQuoteOutputSchema
|
|
7710
|
+
}),
|
|
7711
|
+
defineMcpTool({
|
|
7712
|
+
name: "ctm_pendle_fetch_positions",
|
|
7713
|
+
actionId: "pendle.fetch-positions",
|
|
7714
|
+
protocolId: "pendle",
|
|
7715
|
+
chainCategory: "evm",
|
|
7716
|
+
description: "Pendle V2: this wallet\u2019s LP holdings from official Core dashboard (including matured). Not the node token list. Use before remove LP. ~4 CU. Do not treat claimable amounts here as a live redeem quote.",
|
|
7717
|
+
prerequisites: ["activate_tool_group pendle:lp", "user address", "optional chainId"],
|
|
7718
|
+
followUp: ["ctm_pendle_quote_remove_liquidity"],
|
|
7719
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleFetchPositions" },
|
|
7720
|
+
inputZod: mcpPendleFetchPositionsInputSchema,
|
|
7721
|
+
outputZod: mcpPendleFetchPositionsOutputSchema
|
|
7722
|
+
}),
|
|
7723
|
+
defineMultisignSubmitMcpTool({
|
|
7724
|
+
name: "ctm_pendle_build_swap_multisign",
|
|
7725
|
+
actionId: "pendle.swap",
|
|
7726
|
+
protocolId: "pendle",
|
|
7727
|
+
chainCategory: "evm",
|
|
7728
|
+
description: "Pendle V2: approve Convert tx.to then swap token \u2194 PT/YT. 30-min multiSign expiry unless expiryDate is set. Fresh Convert at build time.",
|
|
7729
|
+
prerequisites: [
|
|
7730
|
+
"ctm_pendle_quote_swap",
|
|
7731
|
+
"get_multi_sign_gas_options + user confirms useCustomGas and 30-minute deadline",
|
|
7732
|
+
"keyGenId + chainId + purposeText + slippagePercent"
|
|
7733
|
+
],
|
|
7734
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleSwapBatch" },
|
|
7735
|
+
inputZod: mcpPendleBuildSwapMultisignInputSchema
|
|
7736
|
+
}),
|
|
7737
|
+
defineMultisignSubmitMcpTool({
|
|
7738
|
+
name: "ctm_pendle_build_mint_py_multisign",
|
|
7739
|
+
actionId: "pendle.mint-py",
|
|
7740
|
+
protocolId: "pendle",
|
|
7741
|
+
chainCategory: "evm",
|
|
7742
|
+
description: "Pendle V2: mint PT+YT multiSign (approve + Convert). 30-min expiry default.",
|
|
7743
|
+
prerequisites: ["ctm_pendle_quote_mint_py", "keyGenId + purposeText + slippagePercent"],
|
|
7744
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleMintPyBatch" },
|
|
7745
|
+
inputZod: mcpPendleBuildMintPyMultisignInputSchema
|
|
7746
|
+
}),
|
|
7747
|
+
defineMultisignSubmitMcpTool({
|
|
7748
|
+
name: "ctm_pendle_build_redeem_py_multisign",
|
|
7749
|
+
actionId: "pendle.redeem-py",
|
|
7750
|
+
protocolId: "pendle",
|
|
7751
|
+
chainCategory: "evm",
|
|
7752
|
+
description: "Pendle V2: redeem PT+YT multiSign. After expiry, pass amountYtHuman 0 (PT only). 30-min expiry default.",
|
|
7753
|
+
prerequisites: ["ctm_pendle_quote_redeem_py", "keyGenId + purposeText + slippagePercent"],
|
|
7754
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleRedeemPyBatch" },
|
|
7755
|
+
inputZod: mcpPendleBuildRedeemPyMultisignInputSchema
|
|
7756
|
+
}),
|
|
7757
|
+
defineMultisignSubmitMcpTool({
|
|
7758
|
+
name: "ctm_pendle_build_mint_sy_multisign",
|
|
7759
|
+
actionId: "pendle.mint-sy",
|
|
7760
|
+
protocolId: "pendle",
|
|
7761
|
+
chainCategory: "evm",
|
|
7762
|
+
description: "Pendle V2: mint SY multiSign. 30-min expiry default.",
|
|
7763
|
+
prerequisites: ["ctm_pendle_quote_mint_sy", "keyGenId + purposeText + slippagePercent"],
|
|
7764
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleMintSyBatch" },
|
|
7765
|
+
inputZod: mcpPendleBuildMintSyMultisignInputSchema
|
|
7766
|
+
}),
|
|
7767
|
+
defineMultisignSubmitMcpTool({
|
|
7768
|
+
name: "ctm_pendle_build_redeem_sy_multisign",
|
|
7769
|
+
actionId: "pendle.redeem-sy",
|
|
7770
|
+
protocolId: "pendle",
|
|
7771
|
+
chainCategory: "evm",
|
|
7772
|
+
description: "Pendle V2: redeem SY multiSign. 30-min expiry default.",
|
|
7773
|
+
prerequisites: ["ctm_pendle_quote_redeem_sy", "keyGenId + purposeText + slippagePercent"],
|
|
7774
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleRedeemSyBatch" },
|
|
7775
|
+
inputZod: mcpPendleBuildRedeemSyMultisignInputSchema
|
|
7776
|
+
}),
|
|
7777
|
+
defineMultisignSubmitMcpTool({
|
|
7778
|
+
name: "ctm_pendle_build_add_liquidity_multisign",
|
|
7779
|
+
actionId: "pendle.add-liquidity",
|
|
7780
|
+
protocolId: "pendle",
|
|
7781
|
+
chainCategory: "evm",
|
|
7782
|
+
description: "Pendle V2: add LP multiSign. 30-min expiry default.",
|
|
7783
|
+
prerequisites: ["ctm_pendle_quote_add_liquidity", "keyGenId + purposeText + slippagePercent"],
|
|
7784
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleAddLiquidityBatch" },
|
|
7785
|
+
inputZod: mcpPendleBuildAddLiquidityMultisignInputSchema
|
|
7786
|
+
}),
|
|
7787
|
+
defineMultisignSubmitMcpTool({
|
|
7788
|
+
name: "ctm_pendle_build_remove_liquidity_multisign",
|
|
7789
|
+
actionId: "pendle.remove-liquidity",
|
|
7790
|
+
protocolId: "pendle",
|
|
7791
|
+
chainCategory: "evm",
|
|
7792
|
+
description: "Pendle V2: remove LP multiSign. 30-min expiry default.",
|
|
7793
|
+
prerequisites: ["ctm_pendle_quote_remove_liquidity", "keyGenId + purposeText + slippagePercent"],
|
|
7794
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleRemoveLiquidityBatch" },
|
|
7795
|
+
inputZod: mcpPendleBuildRemoveLiquidityMultisignInputSchema
|
|
7796
|
+
}),
|
|
7797
|
+
defineMcpTool({
|
|
7798
|
+
name: "ctm_pendle_fetch_merkle_rewards",
|
|
7799
|
+
actionId: "pendle.fetch-merkle-rewards",
|
|
7800
|
+
protocolId: "pendle",
|
|
7801
|
+
chainCategory: "evm",
|
|
7802
|
+
description: "Pendle V2: list off-chain airdrop rows for a wallet (token, amount). Informational only \u2014 Core has no claim proofs. Tell the user to claim airdrops on app.pendle.finance. Do not invent a claim tx. On-chain SY/YT/LP incentives use ctm_pendle_build_redeem_rewards_multisign.",
|
|
7803
|
+
prerequisites: ["activate_tool_group pendle:rewards", "user address"],
|
|
7804
|
+
followUp: [],
|
|
7805
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "pendleFetchMerkleRewards" },
|
|
7806
|
+
inputZod: mcpPendleFetchMerkleRewardsInputSchema,
|
|
7807
|
+
outputZod: mcpPendleFetchMerkleRewardsOutputSchema
|
|
7808
|
+
}),
|
|
7809
|
+
defineMultisignSubmitMcpTool({
|
|
7810
|
+
name: "ctm_pendle_build_redeem_rewards_multisign",
|
|
7811
|
+
actionId: "pendle.redeem-rewards",
|
|
7812
|
+
protocolId: "pendle",
|
|
7813
|
+
chainCategory: "evm",
|
|
7814
|
+
description: "Pendle V2: redeem on-chain interest and incentives from SY, YT, and LP (usually PENDLE) via Hosted SDK. Not merkle airdrops. 30-min expiry default.",
|
|
7815
|
+
prerequisites: [
|
|
7816
|
+
"activate_tool_group pendle:rewards",
|
|
7817
|
+
"sys / yts / markets from fetch_markets or search",
|
|
7818
|
+
"keyGenId + purposeText"
|
|
7819
|
+
],
|
|
7820
|
+
handler: { importPath: "protocols/evm/pendle", exportName: "buildEvmMultisignBodyPendleRedeemRewardsBatch" },
|
|
7821
|
+
inputZod: mcpPendleBuildRedeemRewardsMultisignInputSchema
|
|
7257
7822
|
})
|
|
7258
7823
|
];
|
|
7259
7824
|
var MCP_TOOL_DEFINITIONS = [
|
|
@@ -7504,6 +8069,17 @@ registerProtocolModule(ethenaProtocolModule);
|
|
|
7504
8069
|
function isMapleSyrupSupportedChain(chainId) {
|
|
7505
8070
|
return chainId === 1 || chainId === 11155111;
|
|
7506
8071
|
}
|
|
8072
|
+
function matchesAssetFilter(opts) {
|
|
8073
|
+
const f = (opts.filter ?? "").trim();
|
|
8074
|
+
if (!f) return true;
|
|
8075
|
+
const addr = (opts.address ?? "").trim();
|
|
8076
|
+
if (viem.isAddress(f) && viem.isAddress(addr)) {
|
|
8077
|
+
return viem.getAddress(addr) === viem.getAddress(f);
|
|
8078
|
+
}
|
|
8079
|
+
const sym = (opts.symbol ?? "").trim();
|
|
8080
|
+
if (!sym) return false;
|
|
8081
|
+
return sym.toLowerCase() === f.toLowerCase();
|
|
8082
|
+
}
|
|
7507
8083
|
|
|
7508
8084
|
// src/protocols/evm/maple/index.ts
|
|
7509
8085
|
var MAPLE_PROTOCOL_ID = "maple-syrup";
|
|
@@ -9802,6 +10378,347 @@ var compoundV3ProtocolModule = {
|
|
|
9802
10378
|
]
|
|
9803
10379
|
};
|
|
9804
10380
|
registerProtocolModule(compoundV3ProtocolModule);
|
|
10381
|
+
|
|
10382
|
+
// src/protocols/evm/pendle/support.ts
|
|
10383
|
+
var PENDLE_PROTOCOL_ID = "pendle";
|
|
10384
|
+
var PENDLE_CORE_API_BASE = "https://api-v2.pendle.finance/core";
|
|
10385
|
+
var PENDLE_LISTING_CAP = 100;
|
|
10386
|
+
var PENDLE_LISTING_MAX_PAGES = 8;
|
|
10387
|
+
var PENDLE_ICON_CACHE_MS = 12 * 60 * 1e3;
|
|
10388
|
+
var PENDLE_CHAIN_CACHE_MS = 30 * 60 * 1e3;
|
|
10389
|
+
function parsePendleAssetId(id) {
|
|
10390
|
+
const raw = (id ?? "").trim();
|
|
10391
|
+
const dash = raw.indexOf("-");
|
|
10392
|
+
if (dash <= 0) return null;
|
|
10393
|
+
const chainId = Number.parseInt(raw.slice(0, dash), 10);
|
|
10394
|
+
const address = raw.slice(dash + 1).trim();
|
|
10395
|
+
if (!Number.isFinite(chainId) || chainId <= 0 || !address) return null;
|
|
10396
|
+
return { chainId, address };
|
|
10397
|
+
}
|
|
10398
|
+
|
|
10399
|
+
// src/protocols/evm/pendle/api.ts
|
|
10400
|
+
var FETCH_TIMEOUT_MS = 12e4;
|
|
10401
|
+
var PendleApiError = class extends Error {
|
|
10402
|
+
status;
|
|
10403
|
+
path;
|
|
10404
|
+
constructor(message, status, path) {
|
|
10405
|
+
super(message);
|
|
10406
|
+
this.name = "PendleApiError";
|
|
10407
|
+
this.status = status;
|
|
10408
|
+
this.path = path;
|
|
10409
|
+
}
|
|
10410
|
+
};
|
|
10411
|
+
function sleep(ms) {
|
|
10412
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10413
|
+
}
|
|
10414
|
+
function queryString(params) {
|
|
10415
|
+
const q = new URLSearchParams();
|
|
10416
|
+
for (const [k, v] of Object.entries(params)) {
|
|
10417
|
+
if (v === void 0 || v === "") continue;
|
|
10418
|
+
q.set(k, String(v));
|
|
10419
|
+
}
|
|
10420
|
+
const s = q.toString();
|
|
10421
|
+
return s ? `?${s}` : "";
|
|
10422
|
+
}
|
|
10423
|
+
async function pendleCoreFetch(args) {
|
|
10424
|
+
const path = args.path.startsWith("/") ? args.path : `/${args.path}`;
|
|
10425
|
+
const url = `${PENDLE_CORE_API_BASE}${path}${queryString(args.query ?? {})}`;
|
|
10426
|
+
const headers = { Accept: "application/json" };
|
|
10427
|
+
if (args.apiKey?.trim()) headers.Authorization = `Bearer ${args.apiKey.trim()}`;
|
|
10428
|
+
if (args.body !== void 0) headers["Content-Type"] = "application/json";
|
|
10429
|
+
let lastError;
|
|
10430
|
+
for (let attempt = 0; attempt < 4; attempt++) {
|
|
10431
|
+
const ac = new AbortController();
|
|
10432
|
+
const timer = setTimeout(() => ac.abort(), FETCH_TIMEOUT_MS);
|
|
10433
|
+
try {
|
|
10434
|
+
const res = await fetch(url, {
|
|
10435
|
+
method: args.method ?? "GET",
|
|
10436
|
+
headers,
|
|
10437
|
+
body: args.body === void 0 ? void 0 : JSON.stringify(args.body),
|
|
10438
|
+
signal: ac.signal
|
|
10439
|
+
});
|
|
10440
|
+
if (res.status === 429) {
|
|
10441
|
+
const wait = Math.min(8e3, 500 * 2 ** attempt);
|
|
10442
|
+
await sleep(wait);
|
|
10443
|
+
lastError = new PendleApiError(`Pendle API rate limited (429) on ${path}`, 429, path);
|
|
10444
|
+
continue;
|
|
10445
|
+
}
|
|
10446
|
+
const text = await res.text();
|
|
10447
|
+
if (!res.ok) {
|
|
10448
|
+
throw new PendleApiError(
|
|
10449
|
+
`Pendle API ${res.status} ${path}: ${text.slice(0, 400)}`,
|
|
10450
|
+
res.status,
|
|
10451
|
+
path
|
|
10452
|
+
);
|
|
10453
|
+
}
|
|
10454
|
+
if (!text.trim()) return {};
|
|
10455
|
+
return JSON.parse(text);
|
|
10456
|
+
} catch (err) {
|
|
10457
|
+
lastError = err;
|
|
10458
|
+
if (err instanceof PendleApiError && err.status !== 429) throw err;
|
|
10459
|
+
if (attempt < 3 && (err instanceof PendleApiError || err?.name === "AbortError")) {
|
|
10460
|
+
await sleep(Math.min(8e3, 400 * 2 ** attempt));
|
|
10461
|
+
continue;
|
|
10462
|
+
}
|
|
10463
|
+
throw err;
|
|
10464
|
+
} finally {
|
|
10465
|
+
clearTimeout(timer);
|
|
10466
|
+
}
|
|
10467
|
+
}
|
|
10468
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
10469
|
+
}
|
|
10470
|
+
|
|
10471
|
+
// src/protocols/evm/pendle/discover.ts
|
|
10472
|
+
var marketsCacheByChain = /* @__PURE__ */ new Map();
|
|
10473
|
+
var chainIdsCache = null;
|
|
10474
|
+
function asRecord(v) {
|
|
10475
|
+
return v && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
10476
|
+
}
|
|
10477
|
+
function asNumber(v) {
|
|
10478
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
10479
|
+
if (typeof v === "string" && v.trim()) {
|
|
10480
|
+
const n = Number.parseFloat(v);
|
|
10481
|
+
return Number.isFinite(n) ? n : null;
|
|
10482
|
+
}
|
|
10483
|
+
return null;
|
|
10484
|
+
}
|
|
10485
|
+
function asString(v) {
|
|
10486
|
+
if (typeof v === "string" && v.trim()) return v.trim();
|
|
10487
|
+
return null;
|
|
10488
|
+
}
|
|
10489
|
+
function asExpiry(v) {
|
|
10490
|
+
const s = asString(v);
|
|
10491
|
+
if (s) return s;
|
|
10492
|
+
const n = asNumber(v);
|
|
10493
|
+
if (n == null) return null;
|
|
10494
|
+
const ms = n < 1e12 ? n * 1e3 : n;
|
|
10495
|
+
return new Date(ms).toISOString();
|
|
10496
|
+
}
|
|
10497
|
+
function pendleMarketExpiryMs(expiry) {
|
|
10498
|
+
const raw = (expiry ?? "").trim();
|
|
10499
|
+
if (!raw) return null;
|
|
10500
|
+
if (/^\d+$/.test(raw)) {
|
|
10501
|
+
const n = Number(raw);
|
|
10502
|
+
return n < 1e12 ? n * 1e3 : n;
|
|
10503
|
+
}
|
|
10504
|
+
const t = Date.parse(raw);
|
|
10505
|
+
return Number.isFinite(t) ? t : null;
|
|
10506
|
+
}
|
|
10507
|
+
function isPendleMarketExpired(row, nowMs = Date.now()) {
|
|
10508
|
+
const t = pendleMarketExpiryMs(row.expiry);
|
|
10509
|
+
if (t == null) return false;
|
|
10510
|
+
return t <= nowMs;
|
|
10511
|
+
}
|
|
10512
|
+
function marketMatchesPin(row, address) {
|
|
10513
|
+
const a = address.trim().toLowerCase();
|
|
10514
|
+
if (!a) return false;
|
|
10515
|
+
return [row.address, row.pt, row.yt, row.sy].some((x) => x.toLowerCase() === a);
|
|
10516
|
+
}
|
|
10517
|
+
function selectPendleListingMarkets(rows, args = {}) {
|
|
10518
|
+
const nowMs = args.nowMs ?? Date.now();
|
|
10519
|
+
const cap = args.cap ?? PENDLE_LISTING_CAP;
|
|
10520
|
+
const pins = (args.includeAddresses ?? []).map((a) => a.trim().toLowerCase()).filter(Boolean);
|
|
10521
|
+
const q = (args.query ?? "").trim();
|
|
10522
|
+
let out = rows.filter((r) => {
|
|
10523
|
+
const pinned = pins.some((p) => marketMatchesPin(r, p));
|
|
10524
|
+
if (!args.includeExpired && !pinned && isPendleMarketExpired(r, nowMs)) return false;
|
|
10525
|
+
if (args.pointsOnly && r.points.length === 0) return false;
|
|
10526
|
+
if (q && !marketMatchesQuery(r, q)) return false;
|
|
10527
|
+
return true;
|
|
10528
|
+
});
|
|
10529
|
+
out.sort(sortPendleMarketsByTvl);
|
|
10530
|
+
return out.slice(0, cap);
|
|
10531
|
+
}
|
|
10532
|
+
function addressFromAssetIdOrHex(raw, fallbackChainId) {
|
|
10533
|
+
if (typeof raw !== "string" || !raw.trim()) return null;
|
|
10534
|
+
const parsed = parsePendleAssetId(raw);
|
|
10535
|
+
if (parsed) {
|
|
10536
|
+
try {
|
|
10537
|
+
return viem.getAddress(parsed.address);
|
|
10538
|
+
} catch {
|
|
10539
|
+
return parsed.address.toLowerCase();
|
|
10540
|
+
}
|
|
10541
|
+
}
|
|
10542
|
+
if (viem.isAddress(raw)) return viem.getAddress(raw);
|
|
10543
|
+
if (raw.startsWith(`${fallbackChainId}-`)) {
|
|
10544
|
+
const rest = raw.slice(String(fallbackChainId).length + 1);
|
|
10545
|
+
if (viem.isAddress(rest)) return viem.getAddress(rest);
|
|
10546
|
+
}
|
|
10547
|
+
return null;
|
|
10548
|
+
}
|
|
10549
|
+
function parsePoints(raw) {
|
|
10550
|
+
if (!Array.isArray(raw)) return [];
|
|
10551
|
+
const out = [];
|
|
10552
|
+
for (const item of raw) {
|
|
10553
|
+
const o = asRecord(item);
|
|
10554
|
+
if (!o) continue;
|
|
10555
|
+
const name = asString(o.name) ?? asString(o.key) ?? asString(o.pointName);
|
|
10556
|
+
if (!name) continue;
|
|
10557
|
+
out.push({
|
|
10558
|
+
name,
|
|
10559
|
+
type: asString(o.type),
|
|
10560
|
+
pendleAsset: asString(o.pendleAsset),
|
|
10561
|
+
value: asNumber(o.value)
|
|
10562
|
+
});
|
|
10563
|
+
}
|
|
10564
|
+
return out;
|
|
10565
|
+
}
|
|
10566
|
+
function marketTvlUsd(row) {
|
|
10567
|
+
return row.tvlUsd ?? row.liquidityUsd ?? 0;
|
|
10568
|
+
}
|
|
10569
|
+
function sortPendleMarketsByTvl(a, b) {
|
|
10570
|
+
const d = marketTvlUsd(b) - marketTvlUsd(a);
|
|
10571
|
+
if (d !== 0) return d;
|
|
10572
|
+
return a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
|
|
10573
|
+
}
|
|
10574
|
+
function parsePendleMarket(raw) {
|
|
10575
|
+
const o = asRecord(raw);
|
|
10576
|
+
if (!o) return null;
|
|
10577
|
+
const chainId = asNumber(o.chainId);
|
|
10578
|
+
const address = addressFromAssetIdOrHex(o.address, chainId ?? 0);
|
|
10579
|
+
if (chainId == null || !address) return null;
|
|
10580
|
+
const details = asRecord(o.details);
|
|
10581
|
+
const tvl = asNumber(o.tvl) ?? asNumber(details?.tvl) ?? asNumber(details?.totalTvl) ?? asNumber(asRecord(details?.liquidity)?.usd);
|
|
10582
|
+
const liquidity = asNumber(o.liquidity) ?? asNumber(details?.liquidity) ?? asNumber(asRecord(details?.liquidity)?.usd);
|
|
10583
|
+
const impliedApy = asNumber(o.impliedApy) ?? asNumber(details?.impliedApy) ?? asNumber(asRecord(o.pt)?.impliedApy);
|
|
10584
|
+
const pt = addressFromAssetIdOrHex(o.pt ?? asRecord(o.pt)?.address ?? asRecord(o.pt)?.id, chainId);
|
|
10585
|
+
const yt = addressFromAssetIdOrHex(o.yt ?? asRecord(o.yt)?.address ?? asRecord(o.yt)?.id, chainId);
|
|
10586
|
+
const sy = addressFromAssetIdOrHex(o.sy ?? asRecord(o.sy)?.address ?? asRecord(o.sy)?.id, chainId);
|
|
10587
|
+
const underlying = addressFromAssetIdOrHex(
|
|
10588
|
+
o.underlyingAsset ?? o.underlying ?? asRecord(o.underlyingAsset)?.address,
|
|
10589
|
+
chainId
|
|
10590
|
+
);
|
|
10591
|
+
if (!pt || !yt || !sy || !underlying) return null;
|
|
10592
|
+
const expired = asExpiry(o.expiry) ?? asExpiry(details?.expiry);
|
|
10593
|
+
return {
|
|
10594
|
+
chainId,
|
|
10595
|
+
name: asString(o.name) ?? asString(o.proSymbol) ?? `${address.slice(0, 8)}\u2026`,
|
|
10596
|
+
address,
|
|
10597
|
+
expiry: expired,
|
|
10598
|
+
pt,
|
|
10599
|
+
yt,
|
|
10600
|
+
sy,
|
|
10601
|
+
underlying,
|
|
10602
|
+
underlyingSymbol: asString(asRecord(o.underlyingAsset)?.symbol) ?? asString(o.underlyingSymbol),
|
|
10603
|
+
ptSymbol: asString(asRecord(o.pt)?.symbol) ?? asString(o.ptSymbol),
|
|
10604
|
+
ytSymbol: asString(asRecord(o.yt)?.symbol) ?? asString(o.ytSymbol),
|
|
10605
|
+
impliedApy,
|
|
10606
|
+
tvlUsd: tvl,
|
|
10607
|
+
liquidityUsd: liquidity,
|
|
10608
|
+
points: parsePoints(o.points ?? details?.points)
|
|
10609
|
+
};
|
|
10610
|
+
}
|
|
10611
|
+
async function pendleFetchSupportedChainIds() {
|
|
10612
|
+
const now = Date.now();
|
|
10613
|
+
if (chainIdsCache && now - chainIdsCache.at < PENDLE_CHAIN_CACHE_MS) return chainIdsCache.chainIds;
|
|
10614
|
+
const json = await pendleCoreFetch({ path: "/v1/chains" });
|
|
10615
|
+
const ids = Array.isArray(json.chainIds) ? json.chainIds.map((n) => Number(n)).filter((n) => Number.isFinite(n) && n > 0) : [];
|
|
10616
|
+
chainIdsCache = { at: now, chainIds: ids };
|
|
10617
|
+
return ids;
|
|
10618
|
+
}
|
|
10619
|
+
async function isPendleChainSupported(chainId) {
|
|
10620
|
+
try {
|
|
10621
|
+
const ids = await pendleFetchSupportedChainIds();
|
|
10622
|
+
if (ids.length === 0) return true;
|
|
10623
|
+
return ids.includes(chainId);
|
|
10624
|
+
} catch {
|
|
10625
|
+
return true;
|
|
10626
|
+
}
|
|
10627
|
+
}
|
|
10628
|
+
async function pendleFetchMarketsPage(args) {
|
|
10629
|
+
const limit = Math.min(PENDLE_LISTING_CAP, Math.max(1, args.limit));
|
|
10630
|
+
const json = await pendleCoreFetch({
|
|
10631
|
+
path: "/v2/markets/all",
|
|
10632
|
+
query: {
|
|
10633
|
+
skip: args.skip ?? 0,
|
|
10634
|
+
limit,
|
|
10635
|
+
...args.chainId != null ? { chainId: args.chainId } : {}
|
|
10636
|
+
}
|
|
10637
|
+
});
|
|
10638
|
+
const raw = Array.isArray(json.markets) ? json.markets : Array.isArray(json.results) ? json.results : [];
|
|
10639
|
+
const rows = [];
|
|
10640
|
+
for (const item of raw) {
|
|
10641
|
+
const row = parsePendleMarket(item);
|
|
10642
|
+
if (row) rows.push(row);
|
|
10643
|
+
}
|
|
10644
|
+
return rows;
|
|
10645
|
+
}
|
|
10646
|
+
async function pendleFetchMarketsForChain(chainId) {
|
|
10647
|
+
const now = Date.now();
|
|
10648
|
+
const cached2 = marketsCacheByChain.get(chainId);
|
|
10649
|
+
if (cached2 && now - cached2.at < PENDLE_ICON_CACHE_MS) return cached2.rows;
|
|
10650
|
+
const rows = [];
|
|
10651
|
+
for (let page = 0; page < PENDLE_LISTING_MAX_PAGES; page++) {
|
|
10652
|
+
const batch = await pendleFetchMarketsPage({
|
|
10653
|
+
skip: page * PENDLE_LISTING_CAP,
|
|
10654
|
+
limit: PENDLE_LISTING_CAP,
|
|
10655
|
+
chainId
|
|
10656
|
+
});
|
|
10657
|
+
const onChain = batch.filter((r) => r.chainId === chainId);
|
|
10658
|
+
rows.push(...onChain);
|
|
10659
|
+
if (batch.length < PENDLE_LISTING_CAP || onChain.length === 0) break;
|
|
10660
|
+
}
|
|
10661
|
+
marketsCacheByChain.set(chainId, { at: now, rows });
|
|
10662
|
+
return rows;
|
|
10663
|
+
}
|
|
10664
|
+
function marketMatchesQuery(row, query) {
|
|
10665
|
+
const q = query.trim();
|
|
10666
|
+
if (!q) return true;
|
|
10667
|
+
if (matchesAssetFilter({ address: row.address, symbol: row.name, filter: q }) || matchesAssetFilter({ address: row.pt, symbol: row.ptSymbol ?? void 0, filter: q }) || matchesAssetFilter({ address: row.yt, symbol: row.ytSymbol ?? void 0, filter: q }) || matchesAssetFilter({ address: row.sy, filter: q }) || matchesAssetFilter({ address: row.underlying, symbol: row.underlyingSymbol ?? void 0, filter: q })) {
|
|
10668
|
+
return true;
|
|
10669
|
+
}
|
|
10670
|
+
const hay = `${row.name} ${row.ptSymbol ?? ""} ${row.ytSymbol ?? ""} ${row.underlyingSymbol ?? ""}`.toLowerCase();
|
|
10671
|
+
return hay.includes(q.toLowerCase());
|
|
10672
|
+
}
|
|
10673
|
+
async function pendleFetchMarketsSummary(args) {
|
|
10674
|
+
if (!await isPendleChainSupported(args.chainId)) {
|
|
10675
|
+
return {
|
|
10676
|
+
chainId: args.chainId,
|
|
10677
|
+
markets: [],
|
|
10678
|
+
notes: `Pendle Core API does not list chain ${args.chainId}.`
|
|
10679
|
+
};
|
|
10680
|
+
}
|
|
10681
|
+
const scanned = await pendleFetchMarketsForChain(args.chainId);
|
|
10682
|
+
const rows = selectPendleListingMarkets(scanned, {
|
|
10683
|
+
query: args.query,
|
|
10684
|
+
pointsOnly: args.pointsOnly,
|
|
10685
|
+
includeAddresses: args.includeAddresses
|
|
10686
|
+
});
|
|
10687
|
+
const expiredOmitted = scanned.filter((r) => isPendleMarketExpired(r)).length;
|
|
10688
|
+
return {
|
|
10689
|
+
chainId: args.chainId,
|
|
10690
|
+
markets: rows,
|
|
10691
|
+
notes: `Top ${rows.length} active Pendle markets on chain ${args.chainId} by TVL/liquidity (scanned ${scanned.length}, omitted ${expiredOmitted} matured). Use ctm_pendle_search_assets for long-tail or expired markets (PT redeem / remove LP). Do not web-search Pendle APYs.`
|
|
10692
|
+
};
|
|
10693
|
+
}
|
|
10694
|
+
|
|
10695
|
+
// src/protocols/evm/pendle/index.ts
|
|
10696
|
+
var pendleProtocolModule = {
|
|
10697
|
+
id: PENDLE_PROTOCOL_ID,
|
|
10698
|
+
chainCategory: "evm",
|
|
10699
|
+
isChainSupported(ctx) {
|
|
10700
|
+
if (ctx.chainCategory !== "evm") return false;
|
|
10701
|
+
const n = typeof ctx.chainId === "number" ? ctx.chainId : Number.parseInt(String(ctx.chainId), 10);
|
|
10702
|
+
if (!Number.isFinite(n)) return false;
|
|
10703
|
+
return isPendleChainSupported(n);
|
|
10704
|
+
},
|
|
10705
|
+
isTokenSupported(token) {
|
|
10706
|
+
if (token.category !== "evm") return false;
|
|
10707
|
+
return token.kind === "native" || token.kind === "erc20";
|
|
10708
|
+
},
|
|
10709
|
+
actions: [
|
|
10710
|
+
{ id: "pendle.fetch-markets", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "List live Pendle markets (TVL-ranked, cap 100, matured omitted)", commonParams: [], params: {} },
|
|
10711
|
+
{ id: "pendle.search-assets", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "Search live PT/YT/SY/underlying (matured only if address-pinned)", commonParams: [], params: {} },
|
|
10712
|
+
{ id: "pendle.swap", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "Swap token \u2194 PT/YT via Hosted SDK convert", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
10713
|
+
{ id: "pendle.mint-py", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "Mint PT + YT", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
10714
|
+
{ id: "pendle.redeem-py", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "Redeem PT + YT (PT only after expiry)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
10715
|
+
{ id: "pendle.add-liquidity", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "Add Pendle AMM liquidity", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
10716
|
+
{ id: "pendle.fetch-positions", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "List this wallet\u2019s Pendle LP (including matured)", commonParams: [], params: {} },
|
|
10717
|
+
{ id: "pendle.remove-liquidity", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "Remove Pendle AMM liquidity", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
10718
|
+
{ id: "pendle.redeem-rewards", protocolId: PENDLE_PROTOCOL_ID, chainCategory: "evm", description: "Redeem on-chain SY/YT/LP interest and incentives (not merkle airdrops)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
10719
|
+
]
|
|
10720
|
+
};
|
|
10721
|
+
registerProtocolModule(pendleProtocolModule);
|
|
9805
10722
|
var skillsDir = path.join(path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('catalog.cjs', document.baseURI).href)))), "skills");
|
|
9806
10723
|
var SKILL_PROTOCOL_IDS = [
|
|
9807
10724
|
"aave-v4",
|
|
@@ -9818,6 +10735,7 @@ var SKILL_PROTOCOL_IDS = [
|
|
|
9818
10735
|
"morpho",
|
|
9819
10736
|
"circle-cctp",
|
|
9820
10737
|
"aerodrome",
|
|
10738
|
+
"pendle",
|
|
9821
10739
|
"continuum-dao",
|
|
9822
10740
|
"compound-v3",
|
|
9823
10741
|
"yield-compare"
|
|
@@ -10298,6 +11216,55 @@ var PROTOCOL_SUPPORT_ADVISORS = {
|
|
|
10298
11216
|
return cache.has(normalized);
|
|
10299
11217
|
}
|
|
10300
11218
|
}),
|
|
11219
|
+
[PENDLE_PROTOCOL_ID]: advisor(PENDLE_PROTOCOL_ID, "api_underlyings", {
|
|
11220
|
+
async supportedChainIds() {
|
|
11221
|
+
try {
|
|
11222
|
+
return [...await pendleFetchSupportedChainIds()].sort((a, b) => a - b);
|
|
11223
|
+
} catch {
|
|
11224
|
+
return [];
|
|
11225
|
+
}
|
|
11226
|
+
},
|
|
11227
|
+
async supportedTokens(chainId) {
|
|
11228
|
+
if (!await isPendleChainSupported(chainId)) {
|
|
11229
|
+
return { tokens: [], notes: `Pendle Core API does not list chain ${chainId}.` };
|
|
11230
|
+
}
|
|
11231
|
+
const listed = await pendleFetchMarketsSummary({ chainId });
|
|
11232
|
+
const byAddr = /* @__PURE__ */ new Map();
|
|
11233
|
+
const add = (address, symbol, roles) => {
|
|
11234
|
+
const key = address.toLowerCase();
|
|
11235
|
+
const prev = byAddr.get(key);
|
|
11236
|
+
byAddr.set(key, {
|
|
11237
|
+
address,
|
|
11238
|
+
symbol: symbol ?? prev?.symbol,
|
|
11239
|
+
roles: [.../* @__PURE__ */ new Set([...prev?.roles ?? [], ...roles])]
|
|
11240
|
+
});
|
|
11241
|
+
};
|
|
11242
|
+
for (const m of listed.markets) {
|
|
11243
|
+
add(m.underlying, m.underlyingSymbol, ["underlying"]);
|
|
11244
|
+
add(m.pt, m.ptSymbol, ["pt"]);
|
|
11245
|
+
add(m.yt, m.ytSymbol, ["yt"]);
|
|
11246
|
+
add(m.sy, null, ["sy"]);
|
|
11247
|
+
add(m.address, m.name, ["lp", "market"]);
|
|
11248
|
+
}
|
|
11249
|
+
return {
|
|
11250
|
+
tokens: [...byAddr.values()],
|
|
11251
|
+
notes: "Official Pendle live (unexpired) TVL-ranked markets on this chain, cap 100 (PT/YT/SY/LP + underlyings). Use ctm_pendle_search_assets for long-tail or matured markets. Use ctm_pendle_fetch_positions for this wallet\u2019s LP (including matured). Do not hardcode routers."
|
|
11252
|
+
};
|
|
11253
|
+
},
|
|
11254
|
+
async isTokenSupported(chainId, address) {
|
|
11255
|
+
if (!await isPendleChainSupported(chainId)) return false;
|
|
11256
|
+
let normalized;
|
|
11257
|
+
try {
|
|
11258
|
+
normalized = viem.getAddress(address).toLowerCase();
|
|
11259
|
+
} catch {
|
|
11260
|
+
return false;
|
|
11261
|
+
}
|
|
11262
|
+
const listed = await pendleFetchMarketsSummary({ chainId });
|
|
11263
|
+
return listed.markets.some(
|
|
11264
|
+
(m) => m.address.toLowerCase() === normalized || m.pt.toLowerCase() === normalized || m.yt.toLowerCase() === normalized || m.sy.toLowerCase() === normalized || m.underlying.toLowerCase() === normalized
|
|
11265
|
+
);
|
|
11266
|
+
}
|
|
11267
|
+
}),
|
|
10301
11268
|
arcus: advisor("arcus", "api_underlyings", {
|
|
10302
11269
|
async supportedChainIds() {
|
|
10303
11270
|
return [...ARCUS_SUPPORTED_CHAIN_IDS];
|
|
@@ -10335,6 +11302,7 @@ registerProtocolModule(veniceProtocolModule);
|
|
|
10335
11302
|
registerProtocolModule(aerodromeProtocolModule);
|
|
10336
11303
|
registerProtocolModule(continuumDaoProtocolModule);
|
|
10337
11304
|
registerProtocolModule(compoundV3ProtocolModule);
|
|
11305
|
+
registerProtocolModule(pendleProtocolModule);
|
|
10338
11306
|
function getAgentCatalog() {
|
|
10339
11307
|
return {
|
|
10340
11308
|
protocols: getProtocolModules(),
|
|
@@ -10360,6 +11328,7 @@ function getAgentCatalog() {
|
|
|
10360
11328
|
aerodrome: aerodromeProtocolModule,
|
|
10361
11329
|
continuumDao: continuumDaoProtocolModule,
|
|
10362
11330
|
compoundV3: compoundV3ProtocolModule,
|
|
11331
|
+
pendle: pendleProtocolModule,
|
|
10363
11332
|
/** Prefer getAgentCatalogForMcp() or getMcpToolDefinitions() for MCP servers. */
|
|
10364
11333
|
mcp: getAgentCatalogForMcp()
|
|
10365
11334
|
};
|
|
@@ -10531,6 +11500,18 @@ exports.mcpContinuumDaoForumUserPostIdsOutputSchema = mcpContinuumDaoForumUserPo
|
|
|
10531
11500
|
exports.mcpContinuumDaoIncreaseAmountInputSchema = mcpContinuumDaoIncreaseAmountInputSchema;
|
|
10532
11501
|
exports.mcpContinuumDaoIncreaseUnlockTimeInputSchema = mcpContinuumDaoIncreaseUnlockTimeInputSchema;
|
|
10533
11502
|
exports.mcpContinuumDaoMergeInputSchema = mcpContinuumDaoMergeInputSchema;
|
|
11503
|
+
exports.mcpContinuumDaoMpaFlagInputSchema = mcpContinuumDaoMpaFlagInputSchema;
|
|
11504
|
+
exports.mcpContinuumDaoMpaFlagOutputSchema = mcpContinuumDaoMpaFlagOutputSchema;
|
|
11505
|
+
exports.mcpContinuumDaoMpaListingInputSchema = mcpContinuumDaoMpaListingInputSchema;
|
|
11506
|
+
exports.mcpContinuumDaoMpaListingOutputSchema = mcpContinuumDaoMpaListingOutputSchema;
|
|
11507
|
+
exports.mcpContinuumDaoMpaMailboxListInputSchema = mcpContinuumDaoMpaMailboxListInputSchema;
|
|
11508
|
+
exports.mcpContinuumDaoMpaMailboxListOutputSchema = mcpContinuumDaoMpaMailboxListOutputSchema;
|
|
11509
|
+
exports.mcpContinuumDaoMpaMailboxOpenInputSchema = mcpContinuumDaoMpaMailboxOpenInputSchema;
|
|
11510
|
+
exports.mcpContinuumDaoMpaMailboxOpenOutputSchema = mcpContinuumDaoMpaMailboxOpenOutputSchema;
|
|
11511
|
+
exports.mcpContinuumDaoMpaMailboxSendInputSchema = mcpContinuumDaoMpaMailboxSendInputSchema;
|
|
11512
|
+
exports.mcpContinuumDaoMpaMailboxSendOutputSchema = mcpContinuumDaoMpaMailboxSendOutputSchema;
|
|
11513
|
+
exports.mcpContinuumDaoMpaRetractInputSchema = mcpContinuumDaoMpaRetractInputSchema;
|
|
11514
|
+
exports.mcpContinuumDaoMpaRetractOutputSchema = mcpContinuumDaoMpaRetractOutputSchema;
|
|
10534
11515
|
exports.mcpContinuumDaoProposalIdInputSchema = mcpContinuumDaoProposalIdInputSchema;
|
|
10535
11516
|
exports.mcpContinuumDaoProposeBravoInputSchema = mcpContinuumDaoProposeBravoInputSchema;
|
|
10536
11517
|
exports.mcpContinuumDaoProposeDeltaInputSchema = mcpContinuumDaoProposeDeltaInputSchema;
|
|
@@ -10538,6 +11519,8 @@ exports.mcpContinuumDaoRegisterProposalInputSchema = mcpContinuumDaoRegisterProp
|
|
|
10538
11519
|
exports.mcpContinuumDaoRegisterProposalOutputSchema = mcpContinuumDaoRegisterProposalOutputSchema;
|
|
10539
11520
|
exports.mcpContinuumDaoRequestDetachInputSchema = mcpContinuumDaoRequestDetachInputSchema;
|
|
10540
11521
|
exports.mcpContinuumDaoSplitInputSchema = mcpContinuumDaoSplitInputSchema;
|
|
11522
|
+
exports.mcpContinuumDaoTechnocoreBindInputSchema = mcpContinuumDaoTechnocoreBindInputSchema;
|
|
11523
|
+
exports.mcpContinuumDaoTechnocoreBindOutputSchema = mcpContinuumDaoTechnocoreBindOutputSchema;
|
|
10541
11524
|
exports.mcpContinuumDaoTokenIdInputSchema = mcpContinuumDaoTokenIdInputSchema;
|
|
10542
11525
|
exports.mcpContinuumDaoTransferInputSchema = mcpContinuumDaoTransferInputSchema;
|
|
10543
11526
|
exports.mcpContinuumDaoUndelegateInputSchema = mcpContinuumDaoUndelegateInputSchema;
|
|
@@ -10676,6 +11659,32 @@ exports.mcpMorphoVaultWithdrawInputSchema = mcpMorphoVaultWithdrawInputSchema;
|
|
|
10676
11659
|
exports.mcpMultisignInput = mcpMultisignInput;
|
|
10677
11660
|
exports.mcpMultisignOutputSchema = multisignOutputSchema;
|
|
10678
11661
|
exports.mcpMultisignSubmitOutputSchema = mcpServerSubmitOutputSchema;
|
|
11662
|
+
exports.mcpPendleBuildAddLiquidityMultisignInputSchema = mcpPendleBuildAddLiquidityMultisignInputSchema;
|
|
11663
|
+
exports.mcpPendleBuildMintPyMultisignInputSchema = mcpPendleBuildMintPyMultisignInputSchema;
|
|
11664
|
+
exports.mcpPendleBuildMintSyMultisignInputSchema = mcpPendleBuildMintSyMultisignInputSchema;
|
|
11665
|
+
exports.mcpPendleBuildRedeemPyMultisignInputSchema = mcpPendleBuildRedeemPyMultisignInputSchema;
|
|
11666
|
+
exports.mcpPendleBuildRedeemRewardsMultisignInputSchema = mcpPendleBuildRedeemRewardsMultisignInputSchema;
|
|
11667
|
+
exports.mcpPendleBuildRedeemSyMultisignInputSchema = mcpPendleBuildRedeemSyMultisignInputSchema;
|
|
11668
|
+
exports.mcpPendleBuildRemoveLiquidityMultisignInputSchema = mcpPendleBuildRemoveLiquidityMultisignInputSchema;
|
|
11669
|
+
exports.mcpPendleBuildSwapMultisignInputSchema = mcpPendleBuildSwapMultisignInputSchema;
|
|
11670
|
+
exports.mcpPendleFetchMarketsInputSchema = mcpPendleFetchMarketsInputSchema;
|
|
11671
|
+
exports.mcpPendleFetchMarketsOutputSchema = mcpPendleFetchMarketsOutputSchema;
|
|
11672
|
+
exports.mcpPendleFetchMerkleRewardsInputSchema = mcpPendleFetchMerkleRewardsInputSchema;
|
|
11673
|
+
exports.mcpPendleFetchMerkleRewardsOutputSchema = mcpPendleFetchMerkleRewardsOutputSchema;
|
|
11674
|
+
exports.mcpPendleFetchPositionsInputSchema = mcpPendleFetchPositionsInputSchema;
|
|
11675
|
+
exports.mcpPendleFetchPositionsOutputSchema = mcpPendleFetchPositionsOutputSchema;
|
|
11676
|
+
exports.mcpPendleFetchPricesInputSchema = mcpPendleFetchPricesInputSchema;
|
|
11677
|
+
exports.mcpPendleFetchPricesOutputSchema = mcpPendleFetchPricesOutputSchema;
|
|
11678
|
+
exports.mcpPendleQuoteAddLiquidityInputSchema = mcpPendleQuoteAddLiquidityInputSchema;
|
|
11679
|
+
exports.mcpPendleQuoteMintPyInputSchema = mcpPendleQuoteMintPyInputSchema;
|
|
11680
|
+
exports.mcpPendleQuoteMintSyInputSchema = mcpPendleQuoteMintSyInputSchema;
|
|
11681
|
+
exports.mcpPendleQuoteOutputSchema = mcpPendleQuoteOutputSchema;
|
|
11682
|
+
exports.mcpPendleQuoteRedeemPyInputSchema = mcpPendleQuoteRedeemPyInputSchema;
|
|
11683
|
+
exports.mcpPendleQuoteRedeemSyInputSchema = mcpPendleQuoteRedeemSyInputSchema;
|
|
11684
|
+
exports.mcpPendleQuoteRemoveLiquidityInputSchema = mcpPendleQuoteRemoveLiquidityInputSchema;
|
|
11685
|
+
exports.mcpPendleQuoteSwapInputSchema = mcpPendleQuoteSwapInputSchema;
|
|
11686
|
+
exports.mcpPendleSearchAssetsInputSchema = mcpPendleSearchAssetsInputSchema;
|
|
11687
|
+
exports.mcpPendleSearchAssetsOutputSchema = mcpPendleSearchAssetsOutputSchema;
|
|
10679
11688
|
exports.mcpServerCommonInputSchema = mcpServerCommonInputSchema;
|
|
10680
11689
|
exports.mcpServerMultisignInput = mcpServerMultisignInput;
|
|
10681
11690
|
exports.mcpServerSubmitOutputSchema = mcpServerSubmitOutputSchema;
|