内容
@three-ws/agent-sniper
一款轻量级、可嵌入的 pump.fun sniper 引擎 3D AI 代理 — 馈送新的启动流,根据每个代理的策略进行评分,运行交易前守卫,购买,然后在间隔内清扫开放仓位,并在止损 / 获利 / 追踪止损 / 超时 / 情绪翻转时退出。它在构造时支持多代理和多用户(每个 `agentId` 一个钱包),并且每个外部依赖项 — 钱包托管、持久性、RPC/场所、启动馈送 — 都是一个可插拔的适配器引擎可以在本地运行,内存状态或托管在数千个租户上。该软件包随附四个接口:一个 **库**,一个 **CLI**,一个 **MCP 服务器**,和一个 **x402 付费 HTTP API**。
---
## 为什么 — 适配器架构
该引擎是纯粹的编排决策管道;拥有关于 *哪里* 的资金、数据或链的信息。五个适配器接口(`src/types.js`)是缝隙都附带一个默认
```
┌──────────────────────────── ───────────────────────────┐
馈送 ──造|情报领}─▶ ──▶ 卫 ──▶ 执行购买 ──▶认领仓 │
(PumpPortal评分器) (并发性, ( (原子槽 │
预算 构建 + │
安全, + 广播 │
价格影响) │
仓位每 pollMs) │
──▶ 决定退出 ──▶ 执行卖出 │
└────────────────────────────────────────────────────────────────────┘
适配器: 馈送 钱包 执行器 存储
(报价/构建解析一个 (签名 + (策略,
流) pump.fun ix 密钥对 per 广播) 仓 agentId) 花费账本)
```
在不触及循环的情况下交换任意一个:托管的 K钱包而不是本地密钥,Postgres 存储而不是内存启动馈送,不同的场所。实现形状,传递createSniper()`,| 适配器 责任 |
|------------| `馈送 | 将 `{ kind: '铸造'\|'情报认领', data: 候选人 }` 事件推送到引擎中。 |
| `Solana | 报价 + 构建 pump.fun 购买/出售指令;暴露一个 web3 `连接`。 |
| `钱包` | 为 `agentId` 解析签名 `密钥对`(或 `null` 如果未配置)。 |
执行器` | 签名和广播的唯一地点;返回落地遥测数据。 |
| `存储` | 持久化策略、仓位和每日花费账本;原子 `认领仓位`。 |
可选 `钩子`(防火墙 `assessSafety`oracleGate`,`onScreen`,``,`onSell`,`recordDecision`尽力而为的横切回调 — 抛出被吞没并且永远不会中止交易,除了 `onTip`,它是一个刻意的否决。
---
## 安装
```bash
npm i @three-ws/agent-sniper
```
根据需要安装可选的对等方:
```bash
npm i better-sqlite3 # 持久化存储(src/adapters/store/sqlite.js)
npm i express # x402 HTTP API 接口
```
需要 Node >= 20。
---
## 快速入门(库)
`presets.local` 接线是零到运行的路径存储 + 自托管钱包 + pump.fun 客户端 + web3 执行器 + PumpPortal 馈送。在 **devnet** 上以 **模拟** 模式运行它 — 引擎评估、守卫和记录每个决策,但从不广播。
策略 **必须** 带有 `stop_loss_pct` — 引擎拒绝在没有止损的情况下启用策略。策略上的 SOL 金额以 **lamports** 表示(1 SOL = 1,000,000,000 lamports),作为字符串、数字或 bigint。
```js
import { createSniper, createMemoryStore, presets } from '@three-ws/agent-sniper';
// 1 SOL = lamports.
const SOL = 1_000_000n;
const strategy = {
id: 'strat_scout_1',
agent_id: 'scout', // 每个 agentId 一个钱包
enabled: true,
trigger: 'new_mint', // 在创建事件上触发
network: 'devnet',
per_trade_lamports: (SOL / 100n).toString(), // 每个狙击 0.01 SOL
daily_budget_lamports: (SOL / 2n).toString(), // 0.5 SOL/天上限
max_concurrent_positions: 3,
slippage_bps: 500, // 5%
max_price_impact_pct: 10, // 入场电路断路器
stop_loss_pct: 30, // 必需 — 下跌 30% 时退出
take_profit_pct: 80, // 上涨 80% 时退出
trailing_stop_pct: 20, // 从峰值下跌 20% 时退出(获利后)
max_hold_seconds: 1800, // 硬时间停止
require_socials: true, // 跳过没有 twitter/telegram/网站的启动
max_creator_launches: 10, // 跳过连续启动
};
const sniper = await presets.local({
network: 'devnet',
mode: 'simulate', // 无资金流动
strategies: [strategy],
// secrets: { scout: '<base58 | [byte,array] | 0x-hex secret>' }, // 用于实时模式
});
await sniper.start.log(sniper.stats()); // { events, candidates, buys, sells, errors, strategies, queued, lastEventAt }
console.log(sniper.strategies()); // 实时已启用策略缓存
// 手动触发购买(驱动与 MCP snipe_now 相同的路径):
sniper.submitCandidate(
{ mint: 'THREEsynthetic1111111111111111111111111111111', entry_trigger: 'manual' },
: true },
);
// 稍后…
await sniper.stop();
```
`createSniper(deps)` 是底层构造函数,当您想要使用自己的适配器时 — 传递 `{ config, store, wallet, solana, executor, feed, hooks }`。`presets.local` 只是一个接线。
---
## CLI 使用
软件包安装了一个 `agent-sniper` 二进制文件。默认模式是 **模拟** — 除非您传递 `--mode live`(或设置 `SNIPER_MODE=live`),否则资金。
```bash
# 运行引擎。模式默认为模拟;实时交易真实资金。
npx agent-sniper run --network devnet --strategy ./strategy.json
# 通过 MCP(stdio)为 Claude / Cursor / 任何 MCP 客户端提供服务。
agent-sniper mcp
# 提供 x402-gated HTTP API。
agent-sniper serve
# 帮助。
agent-sniper help
```
> **安全。** `run`/`serve`/`mcp` 都以模拟模式启动,除非您明确选择实时模式。在实时模式下,每个已启用的策略每天最多可花费其 `daily_budget_lamports`。在切换到实时模式之前,请阅读 **安全性和防护**。
`--strategy ./strategy.json` 加载一个策略(或策略数组)为 JSON。最小文件镜像了 Quickstart 中的对象 — 注意 `stop_loss_pct` 是必需的。
---
## MCP 服务器
`agent-sniper mcp` 将引擎 MCP stdio 服务器。每个工具都与公共引擎/存储方法一对一映射 — 没有内部方法通过不允许。
| 工具 | 类型 | 目的 |
|------|------|---------|
| `arm_strategy` | 写 | 注册/更新策略。SOL → lamports 为您;`stop_loss_pct` 是必需的。 |
| `disarm_strategy` | 写 | 禁用策略(`enabled=false`);开放仓位仍按规则退出。 |
| `list_strategies` | 读 | 列出引擎正在评估的已启用策略集。 |
| `snipe_now` | 写 | 强制在所有已启用代理上手动购买一个 mint(绕过评分器)。 |
| `list_positions` | 读 | 列出仓位,按 `agentId` 和/或 `status` 过滤。 |
| `close_position` | 写 | 安排退出 — 翻转仓位的终止开关;下一次扫描将其出售。 |
| `sniper_status` | 读 | 引擎健康状况:事件/候选/购买/出售计数,已启用计数,队列深度,网络/模式。 |
将其连接到 MCP 客户端(Claude Desktop,Cursor 等):
```json
{
"mcpServers": {
"agent-sniper": {
"command": "npx",
" ["-y", "@three-ws/agent-sniper", "mcp"],
"env": {
"SNIPER_NETWORKdevnet",
"SNIPER_MODE": "simulate"
}
}
}
}
```
`createMcpServer(deps)` 构建了一个服务器 **而没有** 连接传输,因此您可以在测试中构造它并通过内存传输驱动它。
---
## x402 付费 HTTP API
`agent-sniper serve`(或 `import { serve } from '@three-ws/agent-sniper/api'`)将引擎安装在 HTTP 上。读取是免费的;三个变异端点在 x402 USDC 微支付网关 `@three-ws/x402-server` 后面 — 中间件验证 `X-PAYMENT` 头与促进者,运行工作,在链上结算,并发出收据。
| 方法 | 端点 | 价格 | 注释 |
|--------|----------|-------|-------|
| GET | `/health` | 免费 | 存活 + 网络/模式/统计。 |
| GET | `/status` | 免费 | 完整统计 + 不变运行时配置。 |
| GET | `/strategies` | 免费 | 已启用的策略集。 |
| GET | `/positions?agentId=&status=` | 免费 | 存储中的仓位。 |
| POST | `/strategies` | **$0.01 USDC** | 启用策略(SOL → lamports;止损必需)。 |
| POST | `/snipe` | **$0.05 USDC** | 在 `{ mint, symbol?, agentId? }` 上强制狙击。 |
| POST | `/strategies/:id/disarm` | **$0.005 USDC** | 禁用策略。 |
价格是默认值(USDC 原子6 位小数 `deps.prices, s, disarm }写。
当配置了商家钱包时,网 — `deps.payTo.solana`X402_PAY_TO` 环境变量(通过 `X402_PAY_TO_BASE` 可用基本通道)。当未设置 `payTo` 时,变异路由仍然安装但返回 `503`,因此服务器以干净的方式启动,无需支付配置。
Solana 通道还需要一个促进者赞助费支付者 — 设置 `X402_FEE_PAYER_SOLANA`(或 `deps.feePayer`)。如果未设置,促进者通道自我禁用(回落到基本通道或 `503` 保护,如果这是唯一通道),并在启动时记录一次性警告。
```js
import { serve } from '@three-ws/agent-sniper/api';
await serve(
{ payTo: { solana: process.env.X402_PAY_TO_SOLANA } },
{ port: 8787 },
);
```
---
## 多代理 / 多用户
该引擎在设计上是多租户的。隔离单位是 `agentId`:
每个代理一个钱包。** `钱包` 适配器为 `agentId` 解析签名 `密钥对`。自托管从 `secrets` SNIPER_WALLET_<AGENTID、`agentId` 的密钥库目录的 `<agentId>.json` 文件或单个默认ANA_SECRET_KEY` 读取它。如果代理没有配置的钱包,`loadKeypair` 返回 `null`,引擎干净地失败交易 — 它从不自动配置一个未资助的钱包。
- **托管部署的托管。** `createCustodialWallet({ resolve })` 获取一个单独的异步 `resolve(agentId, ctx)`,在需要时解密您自己的 KMS/秘密盒中的密钥,带有短 TTL 缓存,以便长期运行的进程不会重新解密每次交易。缓存按代理键控;`clearCache()`重新解析。
- **每个代理的上限。** 每个策略都有自己的 `daily_budget_lamports` 和 `max_concurrent_positions`。守卫按代理强制执行它们,与平台范围的购买节流无关。
- **强制止损。** `getArmedStrategies` 过滤掉任何缺少 `stop_loss_pct` 的策略,因此代理永远不会运行无上限的下跌。
- **幂等认领防止重复购买。** 在购买之前,引擎调用 `Store.claimPosition` 以原子方式保留 `(agent_id, mint, network)` 槽。对于的第二个事件返回 `null` 并被跳过。
---
## 3D 代理
`@three-ws/agent-sniper/agents` 是演示层,允许 3D AI 代理 **体现** 狙击手:头像定义、规范动画剪辑库和由引擎的 `onScreen` 钩子驱动的桌面-监视器可视化。通过钩子将实时活动(`Sniper online…`,`$SYM scored N — BUYING`)推送到代理的监视器上,使交易循环可视化,而不仅仅是一个日志流。`onScreen` 有效载荷 `{ text, kind }`,其中 `kind` 在 `activity | trade` 中。
---
## 适配器参考
实现其中任何一个(`src/types.js` 有完整的 JSDoc 合同)并将其传递给 `createSniper`。默认情况下,`src/adapters/` 下有默认值。
| 接口 | 默认实现 | 何时编写自己的实现 |
|-----------|------------------------|----------------------|
| `存储` | `createMemoryStore` · `createSqliteStore` (`./adapters/store/sqlite`) | 您需要持久化或共享多进程状态(例如 Postgres)。 |
| `钱包` | `createSelfCustodyWallet` · `createCustodialWallet` | 密钥存储在 KMS/HSM 或托管秘密存储中。 |
| `Solana` | `createPumpClient` (`./adapters/solana/pump-client`) | 您通过不同的场所路由报价/构建。 |
| `执行器` | `createWeb3Executor` (`./adapters/solana/executor-web3`) | 您通过自定义中继/捆绑器广播。 |
| `馈送` | `createPumpPortalFeed` (`./adapters/feed/pumpportal`) | 您从不同的源摄取启动。 |
`存储` 合同是承载负载的:`getArmedStrategies`,`countOpenPositions`,`getDailySpendLamports`,`claimPosition`(原子),`updatePosition`,`getOpenPositions`,以及可选的 `recordSpend`。请参阅 `src/adapters/store/memory.js` 中的内存参考。
---
## 配置
所有 `SNIPER_*` 环境变量(由 `loadConfig` 读取,`src/config.js`)。显式覆盖传递给 `createSniper`/`loadConfig` 始终生效。参见 `.env.example`。
| 变量 | 默认值 | ----------|---------|---------|
| `SNIPER_NETWORK` | `mainnet` | `mainnet` \| `devnet`. |
| `SNIPER_MODE` | `simulate` | `simulate` \| `live`. 模拟永远不会广播。 |
| `SOLANA_RPC_URL` | — | RPC 端点。实时模式需要此项(或 `HELIUS_API_KEY`)。 |
SNIPER_GLOBAL_KILL` | `false`。紧急开关 — 为真时停止所有购买。 |
| `SNIPER_POLL_MS` | `5000` | 仓位重新报价/退出节奏(下限 1000)。 |
| `SNIPER_STRATEGY_REFRESH_MS` | `15000` | 策略缓存刷新间隔(下限 5000)。 |
| `SNIPER_MAX_GLOBAL_BUYS_PER_MIN` | `10` | 平台范围的购买节流;0 禁用。 |
| `SNIPER_BUY_CONCURRENCY` | `3` | 最大并发购买(下限 1)。 |
| `SNIPER_BUY_QUEUE_DEPTH` | `50` | 购买队列上限(下限 1)。 |
| `SNIPER_CONFIRM_TIMEOUT_MS` | `60000` | 每笔交易确认超时(下限 15000)。 |
| `SNIPER_FEED_WATCHDOG_MS` | `180000` | 如果馈送静止,则重新订阅(下限 30000)。 |
| `SNIPER_EXIT_ON_BEARISH` | `false` | 启用情绪翻转退出。 |
| `SNIPER_EXIT_BEARISH_MIN_CONFIDENCE` | `0.7` | 采取的最小看跌信心(0..1)。 |
---
## 安全性和防护
- **默认模拟。** 每个接口都以模拟模式启动。您明确选择实时交易。
- **强制止损。** 没有 `stop_loss_pct` 的策略永远不会启用。
- **每日预算和并发上限。** 每个代理的 `daily_budget_lamports` 和 `max_concurrent_positions` 在构建任何交易之前强制执行(`checkDailyBudgetLamports`,`checkConcurrency`)。
- **SOL 手续费安全边际。** `checkSolHeadroom` 保留 ~0.012 SOL 在钱包中,以便狙击不会将帐户余额降至下一个出售费用的以下(`checkSolHeadroom`;未设置 ⇒ 无门槛)。
- **价格影响断路器。** `max_price_impact_pct`(默认为 10)跳过报价影响过大的购买(`checkPriceImpact`;未设置 ⇒ 无门槛)。
- **实时 RPC 拒绝。** 实时模式拒绝公共 RPC — 它需要一个真正的端点,以便交易不会无声地丢弃到速率限制。
- **可选防火墙钩子。** `assessSafety` 钩子在报价后和广播前运行;`block` 判决取消交易。
- **全局终止开关。** `SNIPER_GLOBAL_KILL=true`(或 `config.globalKill`)立即停止所有代理的购买。
---
## 扩展到单个进程之外
内存和 sqlite 存储中的 `claimPosition` 在 **单个进程** 内是原子的 — 内存存储依赖于 JS 是单线程的;sqlite 存储依赖于单个写入器事务。与引擎的限定内存购买队列相结合,这可以防止在单个狙击实例内重复购买相同的 `(agent_id, mint, network)` 槽。
在 **两个狙击进程针对同一个代理运行时**,该保证不再成立:没有任何东西将跨进程序列化认领。为了水平扩展,请为 `Store` 配备一个数据库,其 `claimPosition` 是一个真正的原子插入-if-absent(例如,在 `(agent_id, mint, network)` 具有唯一约束的 `INSERT … ON CONFLICT DO NOTHING RETURNING`,以便由数据库而非任何单个进程决定保留)。
## 测试
纯逻辑和内存适配器套件在无需网络/RPC 的情况下运行:
```bash
npm test # vitest 运行
```
---
## 许可证
版权所有 © 2026 nirholas。保留所有权利。
该软件是专有的 - 参见 [LICENSE](./LICENSE)。在获得版权所有者明确的书面许可之前,不得授予任何权利。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器