关于 leverage
Spiral Stake 的 leverage 服务负责组合并提供该应用的只读策略和市场数据,面向应用及 Agent 消费方。它通过带版本的 REST API 保持应用计算行为一致;此阶段尚未实现 MCP 工具或交易构建。
主要功能
- 01提供组合后的杠杆策略
- 02公开市场及 APY 历史数据
- 03提供价格和价格图表
- 04报告 TVL 与头寸总量
- 05按字段组显示数据陈旧时间
- 06提供带版本的 OpenAPI 接口
适用场景
- 01为应用提供策略数据
- 02供 Agent 读取固定的策略契约
- 03获取市场及抵押品 APY 历史
- 04查看支持链上的协议 TVL
MCP 相关
尽管项目名称与 MCP 相关,此阶段尚未实现 MCP 工具层。它通过带版本的 REST API 提供只读 JSON;MCP 工具和交易构建计划在后续阶段实现。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://api.spiralstake.xyz/mcpclaude mcp add --transport http xyz-spiralstake-leverage https://api.spiralstake.xyz/mcp{"mcpServers":{"xyz-spiralstake-leverage":{"type":"http","url":"https://api.spiralstake.xyz/mcp"}}}在 Cursor 中打开{"servers":{"xyz-spiralstake-leverage":{"type":"http","url":"https://api.spiralstake.xyz/mcp"}}}在 VS Code 中打开{"mcpServers":{"xyz-spiralstake-leverage":{"type":"http","url":"https://api.spiralstake.xyz/mcp"}}}{"mcpServers":{"xyz-spiralstake-leverage":{"serverUrl":"https://api.spiralstake.xyz/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
10| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| chainId | integer | 否 | 目标链。支持:1、4663。默认值:1。 |
| category | string | 否 | 按抵押品类别筛选:'stable'、'ETH'、'BTC'、'stable-PT'、'stocks'(权益金库)、'Other'(永续合约)。 |
详细介绍
Spiral Stake — mcp 只读数据骨干(第 1a 步)
Spiral Stake 策略数据的组合权威层 + 读取 API。它将应用的客户端数据组合逻辑迁移到服务端,并以 JSON 形式返回,让三类使用方共用一个核心:
- 应用 — 提供它当前获取的完整读取接口,便于第 2 步进行一对一替换。
- Agent — 冻结的
/strategiescontract。 - 合作伙伴(后续) — 简洁、版本化、自描述的 REST 接口(OpenAPI)。
只读。不写入 contract,不构建交易,不签名,不处理私钥。它只组合数据并提供 JSON。MCP 工具层、执行/build_* 和合作伙伴身份验证属于后续步骤——接口边界已预留(core + http),但尚未构建。
架构
src/
core/ pure composition — no I/O, unit-testable
leverage.ts ← VERBATIM copy of v2-client/src/utils/leverage.ts (byte-diff gated)
apy.ts collateral-APY resolution (Pendle/DeFiLlama/Royco/StableWatch/on-chain)
leverageApy.ts 30/60/90d leveraged-APY windows + lumpy-token smoothing
compose.ts Market assembly from warm raw (port of FlashLeverage.createInstance)
strategy.ts Market → frozen /strategies contract (ladder, freshness, spiralHints)
exitLiquidity.ts exit-liquidity tier (the single verdict) + thresholds
sources/ one adapter per upstream (fetch + parse). native fetch + viem; no axios/wagmi
cache/ two-layer cache — RAW store (last-good) + warming policy (CONTRACT cadences)
warmer/ background scheduler (stale-while-revalidate); reads NEVER fetch
http/ thin hono REST layer (the only thing that knows about requests)
data/ static market config (copied from the app) + readMarkets port
config/ env (validated) + structured logger with correlation ids
数据流:warmer 按照 CONTRACT 规定的频率获取上游数据 → 将原始数据写入缓存(失败时保留最近一次成功数据)→ core 仅基于已预热的原始数据组合策略 → http 提供这些数据。
上游数据过期或获取失败时,会按字段组提供最近一次成功数据,并明确显示其过期时长——绝不丢弃,也绝不强制转换为 0。
运行
cp .env.example .env # fill in RPC + API keys (secrets via env only)
npm install
npm run dev # tsx watch; serves on :$PORT (default 8787)
npm test # golden + parity gates
npm run typecheck # tsc --noEmit
npm run openapi # (re)emit openapi.json
node --import tsx scripts/smoke.ts # live: prime + print one composed strategy
启动后即可访问 /health(存活状态 + 缓存诊断)和 /ready(在 warmer 预热所需数据前返回 503)。
端点 — 应用读取清单 → 端点映射
应用在 v2-client/src/api-services/* 中执行的每项数据读取,都映射到此处的一个端点(持仓仍由仪表盘后端提供,不在此处重新实现):
应用读取(api-services/*) | mcp 端点 |
|---|---|
getTokenApy、getAllMorphoMarketsData、fetchMerklSpotIncentives、价格、链上价值 → 组合后的市场 | GET /v1/strategies、GET /v1/strategies/:id |
FlashLeverage.createInstance → 应用完整的客户端 Market[] 组合 | GET /v1/app/markets(原始领域模型;BigNumber→{"$bn":…},bigint→{"$bigint":…} — 使用前需还原) |
morpho.ts getAllBorrowApyHistories / getBorrowApyHistory | GET /v1/markets/borrow-apy-history、GET /v1/markets/:id/borrow-apy-history |
apy.ts resolveTokenApyHistory(DeFiLlama/Royco/StableWatch 历史数据)、chart.ts getApyChart | GET /v1/collateral/apy-history、GET /v1/collateral/:id/apy-history |
merkl.ts fetchMerklIncentiveData(借款激励 APR 历史数据) | GET /v1/markets/:id/incentive-history |
token.ts getAllLoanTokenPrices / getTokenPrice | GET /v1/prices |
chart.ts getMarketChart(CoinGecko 价格图表) | GET /v1/prices/chart?coinId=&days=¤cy=(按需代理) |
chart.ts getDexOhlcv(对于没有 CoinGecko/TradingView 图表的代币,获取 DEX 价格图表,例如 Robinhood 上的 CASHCAT/PONS) | GET /v1/prices/ohlcv?chainId=&token=&timeframe=&aggregate=&limit=(按需代理 GeckoTerminal,缓存 30 秒,失败时保留最近一次成功数据;COINGECKO_PRO_API_KEY 可提高速率限制) |
dashboard.ts getApySnapshot(StableWatch 稳定 APY) | GET /v1/stable-apy — 直接从 StableWatch 获取,作为已预热的上游数据;现在 mcp 拥有此数据,不再依赖仪表盘 /apy 端点 |
| —(协议级数据,并非应用读取) | GET /v1/tvl — 所有受支持链上的协议 TVL,每 5 分钟根据链上持仓预热:tvlUsd = 用户净权益(抵押品 − 债务,即 DefiLlama TVL),grossTvlUsd = 循环借贷抵押品总额,borrowedUsd = 债务总额,另含 positions/users;在计算完首条链之前返回 503 |
| swap/meta-dex 聚合器、推荐、持仓 | 不在范围内(执行 / 后端领域) |
跨领域能力:/v1 版本控制、将 CORS 限制为 CORS_ORIGINS、统一的错误封装({ error: { code, message, correlationId } })、每个请求都有一个关联 ID(通过 x-correlation-id 回传)、结构化 JSON 日志,以及位于 /openapi.json 的 OpenAPI 3.1 规范(另有已提交的 openapi.json)。
对齐门槛
leverage.ts黄金向量测试——test/golden/leverage.golden.test.ts固定输入 → 精确输出;leverage.parity.test.ts断言该文件与应用的leverage.ts逐字节相同。这会将每个 APY/LTV/阶梯数值锁定为与应用一致。/strategies组合——test/parity/strategies.compose.test.ts使用受控夹具填充原始缓存,并逐字段断言组合后的契约(数据来源、LTV 计算、通过原样使用的leverage.ts计算的阶梯、新鲜度周期、null与字段缺失的区别、spiralHints隔离)。在 CI 中离线运行。- 实时黄金集 + 应用表面一致性——
scripts/capture-parity.ts让预热器连接真实上游数据源,并将固定市场集的组合后/strategies(以及 APY/借款历史)写入test/fixtures/。与应用的对齐差异通过将相同的固定输入传入应用的客户端组合逻辑并进行比较来生成(应用会记录其组合后的市场);PR 提交这些夹具以及空差异。这道门槛让我们能安全地卸载 TVL。
已冻结的决策(对齐关键项)
bignumber.js固定为与应用相同的9.3.1;不更改全局BigNumber.config→toFixed(2)/ 舍入(ROUND_HALF_UP)保持一致。- 使用 viem 替代 wagmi 进行链上读取:
getCollateralValueInLoanToken(multicall3)、stUSDSstr()、spUSDGvsr()(链 4663)。与应用完全一致地保留其对 JSON 数字执行的(有意损失精度的)BigInt(liqLtv),不做“修正”。 maxLeverage = calcLeverage(maxLtv);defaultLeverage = calcLeverage(safeLtv),safeLtv = maxLtv% − 0.75——与应用推导方式完全一致。阶梯为整数步长1x … ⌊maxLeverage⌋(LTV=(1 − 1/lev)·100),然后是精确的max。- 退出滑点由应用的每周刷新脚本写入
collateralTokens.json;该文件的 mtime 即为exitLiquidity.asOf。等级(唯一的判定结果)及其阈值位于spiralHints中;原始slippagePct保留在exitLiquidity下,无路线时保留null。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。