torch-liquidation-agent 1.0.0

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.
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /**
3
+ * wallet-profiler.ts — assesses wallet risk using SAID reputation + trade history.
4
+ *
5
+ * checks each borrower's trust tier and analyzes their trade messages
6
+ * to determine if they tend to lose money (higher liquidation risk).
7
+ *
8
+ * profiles are cached in-memory with a cooldown to avoid hammering RPC.
9
+ *
10
+ * uses the torch agent kit for trade messages and calls the SAID API
11
+ * directly for wallet reputation verification.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.WalletProfiler = void 0;
15
+ const solana_agent_kit_torch_market_1 = require("solana-agent-kit-torch-market");
16
+ const utils_1 = require("./utils");
17
+ const PROFILE_COOLDOWN_MS = 5 * 60 * 1000; // refresh profiles every 5 min
18
+ const MAX_CACHE_AGE_MS = 30 * 60 * 1000; // evict entries older than 30 min
19
+ const MAX_CACHE_SIZE = 1000; // hard cap on cache entries
20
+ const SAID_API_URL = 'https://api.saidprotocol.com/api';
21
+ async function verifySaid(address) {
22
+ try {
23
+ const res = await fetch(`${SAID_API_URL}/verify/${address}`);
24
+ if (!res.ok)
25
+ return { verified: false, trustTier: null };
26
+ const data = (await res.json());
27
+ return {
28
+ verified: data.verified ?? false,
29
+ trustTier: data.trust_tier ?? null,
30
+ };
31
+ }
32
+ catch {
33
+ return { verified: false, trustTier: null };
34
+ }
35
+ }
36
+ class WalletProfiler {
37
+ constructor(log) {
38
+ this.cache = new Map();
39
+ this.log = log;
40
+ }
41
+ async profile(agent, address, mint) {
42
+ this.evictStale();
43
+ const cached = this.cache.get(address);
44
+ if (cached && Date.now() - cached.lastUpdated < PROFILE_COOLDOWN_MS) {
45
+ return cached;
46
+ }
47
+ this.log.debug(`profiling wallet ${address.slice(0, 8)}...`);
48
+ // SAID reputation
49
+ const said = await verifySaid(address);
50
+ // trade history from messages
51
+ const tradeStats = await this.analyzeTradeHistory(agent, mint, address);
52
+ // compute wallet risk score (0-100)
53
+ const riskScore = this.computeWalletRisk(said.trustTier, tradeStats);
54
+ const profile = {
55
+ address,
56
+ saidVerified: said.verified,
57
+ trustTier: said.trustTier,
58
+ tradeStats,
59
+ riskScore,
60
+ lastUpdated: Date.now(),
61
+ };
62
+ this.cache.set(address, profile);
63
+ return profile;
64
+ }
65
+ async analyzeTradeHistory(agent, mint, address) {
66
+ try {
67
+ const messages = await (0, solana_agent_kit_torch_market_1.torchGetMessages)(agent, mint, 50);
68
+ // filter messages from this wallet and analyze buy/sell patterns
69
+ const walletMsgs = messages.filter((m) => m.sender === address);
70
+ let wins = 0;
71
+ let losses = 0;
72
+ let netPnlSol = 0;
73
+ for (const msg of walletMsgs) {
74
+ const m = msg;
75
+ if (m.pnl_sol !== undefined) {
76
+ if (m.pnl_sol > 0)
77
+ wins++;
78
+ else
79
+ losses++;
80
+ netPnlSol += m.pnl_sol;
81
+ }
82
+ }
83
+ const totalTrades = wins + losses;
84
+ return {
85
+ totalTrades,
86
+ wins,
87
+ losses,
88
+ winRate: totalTrades > 0 ? wins / totalTrades : 0.5,
89
+ netPnlSol,
90
+ };
91
+ }
92
+ catch {
93
+ // if we can't get trade history, assume neutral
94
+ return { totalTrades: 0, wins: 0, losses: 0, winRate: 0.5, netPnlSol: 0 };
95
+ }
96
+ }
97
+ computeWalletRisk(trustTier, stats) {
98
+ // base risk from trust tier
99
+ const tierRisk = {
100
+ high: 10,
101
+ medium: 40,
102
+ low: 70,
103
+ };
104
+ let risk = tierRisk[trustTier ?? ''] ?? 50; // unverified = 50
105
+ // modifier from trade history: bad traders are riskier
106
+ if (stats.totalTrades > 0) {
107
+ // low win rate increases risk, high win rate decreases it
108
+ const winRateModifier = (0.5 - stats.winRate) * 40; // -20 to +20
109
+ risk += winRateModifier;
110
+ // net losses increase risk
111
+ if (stats.netPnlSol < 0) {
112
+ risk += Math.min(Math.abs(stats.netPnlSol) * 5, 20); // up to +20
113
+ }
114
+ }
115
+ return (0, utils_1.clamp)(Math.round(risk), 0, 100);
116
+ }
117
+ evictStale() {
118
+ const now = Date.now();
119
+ for (const [key, profile] of this.cache) {
120
+ if (now - profile.lastUpdated > MAX_CACHE_AGE_MS) {
121
+ this.cache.delete(key);
122
+ }
123
+ }
124
+ // hard cap: if still too large, evict oldest entries
125
+ if (this.cache.size > MAX_CACHE_SIZE) {
126
+ const sorted = [...this.cache.entries()].sort((a, b) => a[1].lastUpdated - b[1].lastUpdated);
127
+ const toEvict = sorted.slice(0, this.cache.size - MAX_CACHE_SIZE);
128
+ for (const [key] of toEvict) {
129
+ this.cache.delete(key);
130
+ }
131
+ }
132
+ }
133
+ }
134
+ exports.WalletProfiler = WalletProfiler;
135
+ //# sourceMappingURL=wallet-profiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet-profiler.js","sourceRoot":"","sources":["../src/wallet-profiler.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "torch-liquidation-agent",
3
+ "version": "1.0.0",
4
+ "description": "lending position monitor and auto-liquidation skill using the torch-agent-kit",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "torch-liquidation-agent": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "clean": "rm -rf dist",
16
+ "test": "npx tsx tests/test_lending.ts",
17
+ "test:bot": "npx tsx tests/test_bot.ts",
18
+ "format": "prettier --write src/ tests/"
19
+ },
20
+ "dependencies": {
21
+ "@coral-xyz/anchor": "^0.32.1",
22
+ "@solana/spl-token": "^0.4.14",
23
+ "@solana/web3.js": "^1.98.4",
24
+ "bs58": "^6.0.0",
25
+ "solana-agent-kit": "^2.0.0",
26
+ "solana-agent-kit-torch-market": "^3.0.6"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^20",
30
+ "prettier": "^3.5.3",
31
+ "torchsdk": "^1.0.5",
32
+ "typescript": "^5"
33
+ },
34
+ "peerDependencies": {
35
+ "@solana/web3.js": "^1.98.0"
36
+ },
37
+ "license": "MIT",
38
+ "packageManager": "pnpm@9.10.0+sha512.73a29afa36a0d092ece5271de5177ecbf8318d454ecd701343131b8ebc0c1a91c487da46ab77c8e596d6acf1461e3594ced4becedf8921b074fbd8653ed7051c"
39
+ }
package/readme.md ADDED
@@ -0,0 +1,152 @@
1
+ # torch-liquidation-agent
2
+
3
+ Multi-token liquidation bot for [Torch Market](https://torch.market) lending on Solana, built on [solana-agent-kit](https://github.com/sendaifun/solana-agent-kit) + [solana-agent-kit-torch-market](https://www.npmjs.com/package/solana-agent-kit-torch-market).
4
+
5
+ Same functionality as [`torch-liquidation-bot`](../bot/) but uses the Torch Agent Kit plugin instead of raw torchsdk — making it compatible with AI agent frameworks (LangChain, Vercel AI, OpenAI tools).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install torch-liquidation-agent
11
+ ```
12
+
13
+ ## How It Works
14
+
15
+ Every migrated token on Torch has a built-in lending market. Holders borrow SOL against their tokens. When a borrower's loan-to-value ratio exceeds 65%, anyone can liquidate the position and collect a 10% bonus on the collateral.
16
+
17
+ This bot finds those opportunities before other bots do by **predicting** which positions will go underwater:
18
+
19
+ 1. **Scan** -- discovers all tokens with active lending markets
20
+ 2. **Profile** -- checks each borrower's SAID reputation and trade history
21
+ 3. **Score** -- rates every loan on a 4-factor risk model (0-100)
22
+ 4. **Liquidate** -- executes when a position crosses the threshold and the profit exceeds your minimum
23
+
24
+ ## Quick Start
25
+
26
+ ```bash
27
+ MODE=bot WALLET=<base58-private-key> RPC_URL=<rpc-endpoint> npx torch-liquidation-agent
28
+ ```
29
+
30
+ ## Modes
31
+
32
+ ### `bot` (default) -- full liquidation bot
33
+
34
+ Runs two concurrent loops:
35
+ - **Scan loop** (every 60s) -- finds tokens with active lending, snapshots prices
36
+ - **Score loop** (every 15s) -- profiles borrowers, scores loans, executes liquidations
37
+
38
+ ```bash
39
+ MODE=bot WALLET=<key> RPC_URL=<rpc> npx torch-liquidation-agent
40
+ ```
41
+
42
+ ### `info` -- display lending parameters
43
+
44
+ ```bash
45
+ # all migrated tokens with lending
46
+ MODE=info RPC_URL=<rpc> npx torch-liquidation-agent
47
+
48
+ # specific token
49
+ MODE=info MINT=<mint> RPC_URL=<rpc> npx torch-liquidation-agent
50
+ ```
51
+
52
+ ### `watch` -- monitor your own loan health
53
+
54
+ ```bash
55
+ MODE=watch MINT=<mint> WALLET=<key> RPC_URL=<rpc> npx torch-liquidation-agent
56
+
57
+ # with auto-repay if your position becomes liquidatable
58
+ MODE=watch MINT=<mint> WALLET=<key> AUTO_REPAY=true RPC_URL=<rpc> npx torch-liquidation-agent
59
+ ```
60
+
61
+ ## Risk Scoring
62
+
63
+ Every loan gets a composite score from four weighted factors:
64
+
65
+ | Factor | Weight | What It Measures |
66
+ |--------|--------|------------------|
67
+ | LTV proximity | 40% | How close to the 65% liquidation threshold |
68
+ | Price momentum | 30% | Collateral price trend (linear regression on recent snapshots) |
69
+ | Wallet risk | 20% | SAID trust tier + trade win/loss ratio |
70
+ | Interest burden | 10% | Accrued interest relative to collateral value |
71
+
72
+ Positions above the risk threshold (default: 60) are flagged and watched closely. Liquidatable positions with profit above your minimum are executed immediately, highest profit first.
73
+
74
+ ## Configuration
75
+
76
+ | Variable | Required | Default | Description |
77
+ |----------|----------|---------|-------------|
78
+ | `RPC_URL` | yes | -- | Solana RPC endpoint |
79
+ | `WALLET` | bot/watch | -- | Base58 private key |
80
+ | `MODE` | no | `bot` | `bot`, `info`, or `watch` |
81
+ | `MINT` | info/watch | -- | Token mint address |
82
+ | `SCAN_INTERVAL_MS` | no | `60000` | Token discovery interval |
83
+ | `SCORE_INTERVAL_MS` | no | `15000` | Position scoring interval |
84
+ | `MIN_PROFIT_SOL` | no | `0.01` | Minimum profit to execute liquidation |
85
+ | `RISK_THRESHOLD` | no | `60` | Risk score cutoff for close monitoring |
86
+ | `PRICE_HISTORY` | no | `20` | Price snapshots to keep for momentum |
87
+ | `LOG_LEVEL` | no | `info` | `debug`, `info`, `warn`, `error` |
88
+
89
+ ## Architecture
90
+
91
+ ```
92
+ src/
93
+ ├── types.ts — interfaces and contracts
94
+ ├── config.ts — env vars → SolanaAgentKit + typed config
95
+ ├── logger.ts — structured logging
96
+ ├── utils.ts — shared helpers
97
+ ├── scanner.ts — discovers tokens with active lending
98
+ ├── wallet-profiler.ts — SAID reputation + trade history
99
+ ├── risk-scorer.ts — 4-factor risk model
100
+ ├── liquidator.ts — executes liquidation txs via agent kit
101
+ ├── monitor.ts — scan + score orchestration
102
+ └── index.ts — entry point
103
+ ```
104
+
105
+ ### Differences from `torch-liquidation-bot`
106
+
107
+ | | `bot` (torchsdk) | `agent` (agent kit) |
108
+ |---|---|---|
109
+ | SDK | `torchsdk` direct | `solana-agent-kit-torch-market` plugin |
110
+ | Transaction signing | Manual (`sendAndConfirmTransaction`) | Handled by `SolanaAgentKit` |
111
+ | Holder discovery | `torchsdk.getHolders()` | Solana RPC `getTokenLargestAccounts` |
112
+ | SAID verification | `torchsdk.verifySaid()` | Direct SAID API call |
113
+ | AI agent compatible | No | Yes (LangChain, Vercel AI, OpenAI tools) |
114
+
115
+ ## Lending Parameters
116
+
117
+ | Parameter | Value |
118
+ |-----------|-------|
119
+ | Max LTV | 50% |
120
+ | Liquidation threshold | 65% LTV |
121
+ | Interest rate | 2% per epoch (~7 days) |
122
+ | Liquidation bonus | 10% of collateral |
123
+ | Min borrow | 0.1 SOL |
124
+
125
+ ## Testing
126
+
127
+ Requires [Surfpool](https://github.com/nicholasgasior/surfpool) running a mainnet fork:
128
+
129
+ ```bash
130
+ surfpool start --network mainnet --no-tui
131
+ pnpm test # lending lifecycle test
132
+ pnpm test:bot # bot module test (scanner, profiler, scorer, liquidator)
133
+ ```
134
+
135
+ ## Security
136
+
137
+ - Private keys loaded from env, never logged or transmitted
138
+ - All transactions signed by `SolanaAgentKit` via `KeypairWallet` -- keys never leave your environment
139
+ - Minimum profit threshold prevents unprofitable executions
140
+ - Graceful shutdown on SIGINT
141
+
142
+ ## Links
143
+
144
+ - [solana-agent-kit](https://github.com/sendaifun/solana-agent-kit) -- the agent framework
145
+ - [solana-agent-kit-torch-market](https://www.npmjs.com/package/solana-agent-kit-torch-market) -- Torch Market plugin
146
+ - [torch-liquidation-bot](../bot/) -- the torchsdk-based version
147
+ - [Torch Market](https://torch.market) -- the protocol
148
+ - [SAID Protocol](https://saidprotocol.com) -- wallet reputation layer
149
+
150
+ ## License
151
+
152
+ MIT