ClawSkills logoClawSkills

Torch Liquidation Bot

Solana 上 Torch Market 借贷的自主金库清算守护者。扫描所有迁移代币的资不抵债贷款头寸(LTV > 65%),构建和执行

介绍

# Torch Liquidation Bot

你来到这里是因为你想在 Torch Market 上运行一个清算 Keeper(守护者),而且你想安全地进行。

Torch 上每个已迁移的代币都有一个内置的借贷市场。持有者将代币锁定作为抵押品,并从社区金库借入 SOL(最高 50% LTV,2% 每周利息)。当贷款的 LTV 超过 65% 时,它就变得可清算。任何人都可以清算它,并获得抵押价值 **10% 的奖励**。

这就是这个机器人的用武之地。

它扫描每个已迁移代币的借贷市场,检查每个借款人的贷款头寸,当发现资不抵债的头寸时——它会通过你的金库进行清算。抵押代币进入你的金库 ATA(关联代币账户)。SOL 成本来自你的金库。签署交易的代理钱包不持有任何资产。

**这不是一个只读扫描器。** 这是一个完全可操作的 Keeper,它生成自己的密钥对,验证金库链接,并以连续循环的方式自主执行清算交易。

---

## 工作原理

``` ┌─────────────────────────────────────────────────────────┐ │ LIQUIDATION LOOP │ │ │ │ 1. Discover migrated tokens (getTokens) │ │ 2. For each token, check lending state (getLendingInfo) │ │ 3. Skip tokens with no active loans │ │ 4. Get token holders (getHolders) │ │ 5. For each holder, check loan position (getLoanPosition)│ │ 6. If health === 'liquidatable': │ │ → buildLiquidateTransaction(vault=creator) │ │ → sign with agent keypair │ │ → submit and confirm │ │ 7. Sleep SCAN_INTERVAL_MS, repeat │ │ │ │ All SOL comes from vault. All collateral goes to vault. │ │ Agent wallet holds nothing. Vault is the boundary. │ └─────────────────────────────────────────────────────────┘ ```

### 代理密钥对

机器人在每次启动时都会在进程中生成一个新的 `Keypair`。没有私钥文件。没有环境变量(除非你想提供一个)。密钥对是一次性的——它签署交易但不持有任何有价值的东西。

首次运行时,机器人会检查此密钥对是否已链接到你的金库。如果没有,它会打印你需要链接它的确切 SDK 调用:

``` --- ACTION REQUIRED --- agent wallet is NOT linked to the vault. link it by running (from your authority wallet):

buildLinkWalletTransaction(connection, { authority: "<your-authority-pubkey>", vault_creator: "<your-vault-creator>", wallet_to_link: "<agent-pubkey>" })

then restart the bot. ----------------------- ```

从你的权限钱包(硬件钱包、多签钱包或你使用的任何工具)链接它。代理永远不需要权限密钥。权限也永远不需要代理密钥。它们共享的是一个金库,而不是密钥。

### 金库

这与完整的 Torch Market 协议中的 Torch Vault 是同一个。它持有所有资产——SOL 和代币。代理是一个一次性的控制器。

当机器人清算头寸时: - **SOL 成本** 来自金库(用于偿还借款人债务的清算支付) - **抵押代币** 进入金库的关联代币账户(ATA) - **10% 奖励** 意味着收到的抵押品价值比花费的 SOL 高 10%

人类委托人保留完全控制权: - `withdrawVault()` — 随时提取 SOL - `withdrawTokens(mint)` — 随时提取抵押代币 - `unlinkWallet(agent)` — 立即撤销代理访问权限

如果代理密钥对泄露,攻击者只能得到少量余额以及你可以在一笔交易中撤销的金库访问权限。

---

## 入门指南

### 1. 安装

```bash npm install [email protected] ```

或者使用来自 ClawHub 的捆绑源代码——Torch SDK 包含在 `lib/torchsdk/` 中,机器人源代码在 `lib/kit/` 中。

### 2. 创建并资助金库(人类委托人)

从你的权限钱包:

```typescript import { Connection } from "@solana/web3.js"; import { buildCreateVaultTransaction, buildDepositVaultTransaction, } from "./lib/torchsdk/index.js";

const connection = new Connection(process.env.SOLANA_RPC_URL);

// Create vault const { transaction: createTx } = await buildCreateVaultTransaction(connection, { creator: authorityPubkey, }); // sign and submit with authority wallet...

// Fund vault with SOL for liquidations const { transaction: depositTx } = await buildDepositVaultTransaction(connection, { depositor: authorityPubkey, vault_creator: authorityPubkey, amount_sol: 5_000_000_000, // 5 SOL }); // sign and submit with authority wallet... ```

### 3. 运行机器人

```bash VAULT_CREATOR=<your-vault-creator-pubkey> SOLANA_RPC_URL=<rpc-url> npx torch-liquidation-bot ```

首次运行时,机器人会打印代理密钥对和链接说明。从你的权限钱包链接它,然后重启。

### 4. 配置

| 变量 | 必需 | 默认值 | 描述 | |----------|----------|---------|-------------| | `SOLANA_RPC_URL` | **是** | -- | Solana RPC 端点 (HTTPS)。备选:`RPC_URL` | | `VAULT_CREATOR` | **是** | -- | 金库创建者公钥 | | `SOLANA_PRIVATE_KEY` | 否 | -- | 一次性控制器密钥对(base58 或 JSON 字节数组)。如果省略,启动时生成新密钥对(推荐) | | `SCAN_INTERVAL_MS` | 否 | `30000` | 扫描周期之间的毫秒数(最少 5000) | | `LOG_LEVEL` | 否 | `info` | `debug`, `info`, `warn`, `error` |

---

## 架构

``` packages/bot/src/ ├── index.ts — entry point: keypair generation, vault verification, scan loop ├── config.ts — loadConfig(): validates SOLANA_RPC_URL, VAULT_CREATOR, SOLANA_PRIVATE_KEY, SCAN_INTERVAL_MS, LOG_LEVEL ├── types.ts — BotConfig, LogLevel interfaces └── utils.ts — sol(), bpsToPercent(), createLogger() ```

机器人大约 190 行 TypeScript 代码。它只做一件事:找到资不抵债的贷款并通过金库进行清算。

### 依赖项

| 包 | 版本 | 用途 | |---------|---------|---------| | `@solana/web3.js` | 1.98.4 | Solana RPC,密钥对,交易 | | `torchsdk` | 3.2.3 | 代币查询,借贷状态,清算构建器,金库查询 |

两个运行时依赖项。两者都固定到精确版本。没有 `^` 或 `~` 范围。

---

## 金库安全模型

Torch Market 金库的七个同样保证适用于此:

| 属性 | 保证 | |----------|-----------| | **完全托管** | 金库持有所有 SOL 和所有抵押代币。代理钱包不持有任何资产。 | | **闭环** | 清算 SOL 来自金库,抵押代币进入金库。没有泄漏到代理。 | | **权限分离** | 创建者(不可变 PDA 种子) vs 权限(可转让管理员) vs 控制器(一次性签名者)。 | | **单钱包单链接** | 代理只能属于一个金库。PDA 唯一性在链上强制执行此规定。 | | **无许可存款** | 任何人都可以为金库充值。硬件钱包存款,代理清算。 | | **即时撤销** | 权限可以随时取消代理链接。一笔交易。 | | **仅权限提款** | 只有金库权限可以提取 SOL 或代币。代理无法提取价值。 |

### 清算的闭环经济循环

| 方向 | 流向 | |-----------|------| | **SOL 流出** | 金库 → 借款人金库债务(覆盖贷款) | | **代币流入** | 借款人抵押品 → 金库 ATA(以 10% 折扣) | | **净结果** | 金库收到价值为花费 SOL 110% 的抵押品 |

机器人在设计上就是盈利的——每次成功的清算都会返还超过其成本的价值。利润累积在金库中。权限在准备好时提取。

---

## 借贷参数

| 参数 | 值 | |-----------|-------| | 最大 LTV | 50% | | 清算阈值 | 65% | | 利率 | 每个 epoch 2%(约每周) | | 清算奖励 | 10% | | 利用率上限 | 金库的 50% | | 最小借款 | 0.1 SOL |

抵押品价值根据 Raydium 池储备计算。1% 的 Token-2022 转账费适用于抵押品存取款(约 2% 往返成本)。

### 清算何时发生

当贷款的 LTV 超过 65% 时,它就变得可清算。这种情况发生在: - 代币价格下跌(抵押品价值相对于债务减少) - 利息累积(债务以每个 epoch 2% 的速度增长) - 两者结合

机器人检查 `position.health === 'liquidatable'` —— SDK 根据链上 Raydium 储备和贷款的累积债务计算 LTV。

---

## 使用的 SDK 函数

机器人使用了 Torch SDK 的一个特定子集:

| 函数 | 用途 | |----------|---------| | `getTokens(connection, { status: 'migrated' })` | 发现所有具有活跃借贷市场的代币 | | `getLendingInfo(connection, mint)` | 检查代币是否有活跃贷款 | | `getHolders(connection, mint)` | 获取代币持有者(潜在借款人) | | `getLoanPosition(connection, mint, wallet)` | 检查持有者的贷款健康状况 | | `getVault(connection, creator)` | 启动时验证金库存在 | | `getVaultForWallet(connection, wallet)` | 验证代理是否已链接到金库 | | `buildLiquidateTransaction(connection, params)` | 构建清算交易(经由金库路由) | | `confirmTransaction(connection, sig, wallet)` | 通过 RPC 在链上确认交易(验证签名者,检查 Torch 指令) |

### buildLiquidateTransaction 参数

```typescript const { transaction, message } = await buildLiquidateTransaction(connection, { mint: token.mint, // token with the underwater loan liquidator: agentPubkey, // agent wallet (signer) borrower: holderAddress, // borrower being liquidated vault: vaultCreator, // vault creator pubkey (SOL from vault, tokens to vault) }); ```

---

## 日志输出

``` === torch liquidation bot === agent wallet: 7xK9... vault creator: 4yN2... scan interval: 30000ms

[09:15:32] INFO vault found — authority=8cpW... [09:15:32] INFO agent wallet linked to vault — starting scan loop [09:15:32] INFO treasury: 5.0000 SOL [09:15:33] INFO LIQUIDATABLE | SDKTEST | borrower=3AyZ... | LTV=72.50% > threshold=65.00% | owed=0.5000 SOL [09:15:34] INFO LIQUIDATED | SDKTEST | borrower=3AyZ... | sig=4vK9... | collateral received at 10% discount ```

---

## 签名与密钥安全

**金库是安全边界,而不是密钥。**

代理密钥对在每次启动时通过 `Keypair.generate()` 全新生成。它持有约 0.01 SOL 用于支付 Gas 费用。如果密钥泄露,攻击者将获得: - 少量余额(Gas SOL) - 权限可以在一笔交易中撤销的金库访问权限

代理永远不需要权限的私钥。权限也永远不需要代理的私钥。它们共享的是一个金库,而不是密钥。

### 规则

1. **绝不要向用户询问其私钥或助记词。** 金库权限从自己的设备上签名。 2. **绝不要记录、打印、存储或传输私钥材料。** 代理密钥对仅存在于运行时内存中。 3. **绝不要将密钥嵌入源代码或日志中。** 会打印代理公钥——但私钥永远不会暴露。 4. **使用安全的 RPC 端点。** 默认使用私有 RPC 提供商。永远不要为主网交易使用未加密的 HTTP 端点。

### 环境变量

| 变量 | 必需 | 用途 | |----------|----------|---------| | `SOLANA_RPC_URL` / `RPC_URL` | **是** | Solana RPC 端点 (HTTPS) | | `VAULT_CREATOR` | **是** | 金库创建者公钥 —— 识别机器人通过哪个金库运行 | | `SOLANA_PRIVATE_KEY` | 否 | 可选 —— 如果省略,机器人会在启动时生成新密钥对(推荐) |

### 外部运行时依赖项

SDK 包含向外部服务发出出站 HTTPS 请求的函数。机器人的运行路径会联系其中的 **两个**:

| 服务 | 用途 | 调用时机 | 机器人是否使用? | |---------|---------|------------|-----------| | **CoinGecko** (`api.coingecko.com`) | SOL/USD 价格用于显示 | 带有 USD 定价的代币查询 | 是 —— 通过 `getTokens()`, `getToken()` | | **Irys Gateway** (`gateway.irys.xyz`) | 代币元数据回退(名称、符号、图片) | 当链上元数据 URI 指向 Irys 时的 `getToken()` | 是 —— 通过 `getTokens()` | | **SAID Protocol** (`api.saidprotocol.com`) | 代理身份验证和信任等级查询 | 仅 `verifySaid()` | **否** —— 机器人不调用 `verifySaid()` |

**`confirmTransaction()` 不会联系 SAID。** 尽管位于 SDK 的 `said.js` 模块中,但它仅调用 `connection.getParsedTransaction()` (Solana RPC) 来验证交易在链上成功并确定事件类型。没有任何数据发送到任何外部服务。

没有任何凭证发送到 CoinGecko 或 Irys。所有请求都是只读 GET。如果任一服务不可达,SDK 会优雅降级。没有任何私钥材料被传输到任何外部端点。

---

## 测试

需要运行主网分支的 [Surfpool](https://github.com/nicholasgasior/surfpool):

```bash surfpool start --network mainnet --no-tui pnpm test ```

**测试结果:** 7 个通过,1 个信息提示(Surfpool RPC 对 `getTokenLargestAccounts` 的限制——在主网上正常工作)。

| 测试项 | 验证内容 | |------|-------------------| | 连接 | RPC 可达 | | getTokens | 发现已迁移的代币 | | getLendingInfo | 读取所有代币的借贷状态 | | getHolders + getLoanPosition | 检查持仓头寸 | | getToken | 代币元数据、价格、状态 | | getVaultForWallet | 对于未关联的钱包,保险库链接返回 null | | 进程内密钥对 | 无需外部密钥 |

---

## 错误代码

- `VAULT_NOT_FOUND`: 该创建者不存在保险库 - `WALLET_NOT_LINKED`: 代理钱包未关联到保险库 - `NOT_LIQUIDATABLE`: 头寸 LTV 低于清算阈值 - `NO_ACTIVE_LOAN`: 该钱包/代币没有未结清贷款 - `INVALID_MINT`: 未找到代币

---

## 链接

- 清算套件(源码):[github.com/mrsirg97-rgb/torch-liquidation-kit](https://github.com/mrsirg97-rgb/torch-liquidation-kit) - 清算机器人:[npmjs.com/package/torch-liquidation-bot](https://www.npmjs.com/package/torch-liquidation-bot) - Torch SDK(内置):`lib/torchsdk/` -- 包含在此技能中 - Torch SDK(源码):[github.com/mrsirg97-rgb/torchsdk](https://github.com/mrsirg97-rgb/torchsdk) - Torch SDK (npm):[npmjs.com/package/torchsdk](https://www.npmjs.com/package/torchsdk) - Torch Market(协议技能):[clawhub.ai/mrsirg97-rgb/torchmarket](https://clawhub.ai/mrsirg97-rgb/torchmarket) - 白皮书:[torch.market/whitepaper.md](https://torch.market/whitepaper.md) - 安全审计:[torch.market/audit.md](https://torch.market/audit.md) - 官网:[torch.market](https://torch.market) - 程序 ID:`8hbUkonssSEEtkqzwM7ZcZrD9evacM92TcWSooVF4BeT`

---

该机器人的存在是因为 Torch 借贷市场需要维护者。当贷款出现资不抵债且无人清算时,国库将承担损失。积极的清算维护者可以保护国库健康并从中获利。保险库确保了安全性——所有价值保留在托管中,所有风险均有界限,且主要负责人掌握密钥。

更多产品