torch-liquidation-bot 1.0.4 → 2.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,6 @@
1
+ /**
2
+ * config.ts — loads environment variables into a typed BotConfig.
3
+ */
4
+ import type { BotConfig } from './types';
5
+ export declare function loadConfig(): BotConfig;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,SAAS,CAAA;AAIlD,wBAAgB,UAAU,IAAI,SAAS,CAuCtC"}
package/dist/config.js ADDED
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * config.ts — loads environment variables into a typed BotConfig.
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.loadConfig = loadConfig;
10
+ const web3_js_1 = require("@solana/web3.js");
11
+ const bs58_1 = __importDefault(require("bs58"));
12
+ const torchsdk_1 = require("torchsdk");
13
+ const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
14
+ function loadConfig() {
15
+ const rpcUrl = process.env.RPC_URL;
16
+ if (!rpcUrl)
17
+ throw new Error('RPC_URL env var is required');
18
+ const walletKey = process.env.WALLET;
19
+ if (!walletKey)
20
+ throw new Error('WALLET env var is required (base58 private key)');
21
+ const logLevel = (process.env.LOG_LEVEL ?? 'info');
22
+ if (!LOG_LEVELS.includes(logLevel)) {
23
+ throw new Error(`LOG_LEVEL must be one of: ${LOG_LEVELS.join(', ')}`);
24
+ }
25
+ const minProfitSol = Number(process.env.MIN_PROFIT_SOL ?? '0.01');
26
+ const scanIntervalMs = Number(process.env.SCAN_INTERVAL_MS ?? '60000');
27
+ const scoreIntervalMs = Number(process.env.SCORE_INTERVAL_MS ?? '15000');
28
+ const riskThreshold = Number(process.env.RISK_THRESHOLD ?? '60');
29
+ const priceHistoryDepth = Number(process.env.PRICE_HISTORY ?? '20');
30
+ if (isNaN(scanIntervalMs) || scanIntervalMs < 1000)
31
+ throw new Error('SCAN_INTERVAL_MS must be >= 1000');
32
+ if (isNaN(scoreIntervalMs) || scoreIntervalMs < 1000)
33
+ throw new Error('SCORE_INTERVAL_MS must be >= 1000');
34
+ if (isNaN(riskThreshold) || riskThreshold < 0 || riskThreshold > 100)
35
+ throw new Error('RISK_THRESHOLD must be 0-100');
36
+ if (isNaN(priceHistoryDepth) || priceHistoryDepth < 2)
37
+ throw new Error('PRICE_HISTORY must be >= 2');
38
+ if (isNaN(minProfitSol) || minProfitSol < 0)
39
+ throw new Error('MIN_PROFIT_SOL must be >= 0');
40
+ return {
41
+ rpcUrl,
42
+ walletKeypair: web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(walletKey)),
43
+ scanIntervalMs,
44
+ scoreIntervalMs,
45
+ minProfitLamports: Math.floor(minProfitSol * torchsdk_1.LAMPORTS_PER_SOL),
46
+ riskThreshold,
47
+ priceHistoryDepth,
48
+ logLevel,
49
+ };
50
+ }
51
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;AASH,gCAuCC;AA9CD,6CAAyC;AACzC,gDAAuB;AACvB,uCAA2C;AAG3C,MAAM,UAAU,GAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AAEjE,SAAgB,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAA;IAClC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAE3D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAA;IACpC,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IAElF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAa,CAAA;IAC9D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACvE,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,MAAM,CAAC,CAAA;IACjE,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,CAAA;IACtE,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,CAAA;IACxE,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,CAAA;IAChE,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,CAAA;IAEnE,IAAI,KAAK,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,IAAI;QAChD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACrD,IAAI,KAAK,CAAC,eAAe,CAAC,IAAI,eAAe,GAAG,IAAI;QAClD,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IACtD,IAAI,KAAK,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,CAAC,IAAI,aAAa,GAAG,GAAG;QAClE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,IAAI,KAAK,CAAC,iBAAiB,CAAC,IAAI,iBAAiB,GAAG,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;IAC/C,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAEhD,OAAO;QACL,MAAM;QACN,aAAa,EAAE,iBAAO,CAAC,aAAa,CAAC,cAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC5D,cAAc;QACd,eAAe;QACf,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,2BAAgB,CAAC;QAC9D,aAAa;QACb,iBAAiB;QACjB,QAAQ;KACT,CAAA;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,23 +1,28 @@
1
+ #!/usr/bin/env node
1
2
  /**
2
3
  * torch-lending-monitor
3
4
  *
4
- * Monitors lending positions on migrated Torch tokens and can:
5
- * 1. Display lending parameters (rates, LTV limits, available SOL).
6
- * 2. Watch a wallet's loan health in real-time.
7
- * 3. Auto-liquidate underwater positions for the liquidation bonus.
5
+ * multi-token liquidation bot that discovers lending markets, profiles
6
+ * borrower wallets, predicts which loans will fail, and executes
7
+ * profitable liquidations.
8
8
  *
9
- * Torch lending lets token holders borrow SOL against their tokens
10
- * using community treasury liquidity. This bot watches those positions.
9
+ * modes:
10
+ * info — display lending parameters for a token (or all tokens) (default)
11
+ * watch — monitor your own loan health in real-time
12
+ * bot — run the full liquidation bot
11
13
  *
12
- * Usage:
13
- * # Monitor a token's lending stats
14
- * MODE=info MINT=<token-mint> npx tsx src/index.ts
14
+ * usage:
15
+ * # show all migrated tokens with lending
16
+ * RPC_URL=<rpc> npx tsx src/index.ts
15
17
  *
16
- * # Watch your own loan health
17
- * MODE=watch MINT=<token-mint> WALLET=<base58-key> npx tsx src/index.ts
18
+ * # show lending info for one token
19
+ * MODE=info MINT=<mint> RPC_URL=<rpc> npx tsx src/index.ts
18
20
  *
19
- * # Run as a liquidation bot (scans for liquidatable positions)
20
- * MODE=liquidate MINT=<token-mint> WALLET=<base58-key> npx tsx src/index.ts
21
+ * # watch your loan health
22
+ * MODE=watch MINT=<mint> WALLET=<key> RPC_URL=<rpc> npx tsx src/index.ts
23
+ *
24
+ * # run the liquidation bot
25
+ * MODE=bot WALLET=<key> RPC_URL=<rpc> npx tsx src/index.ts
21
26
  */
22
27
  export {};
23
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
package/dist/index.js CHANGED
@@ -1,24 +1,29 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  /**
3
4
  * torch-lending-monitor
4
5
  *
5
- * Monitors lending positions on migrated Torch tokens and can:
6
- * 1. Display lending parameters (rates, LTV limits, available SOL).
7
- * 2. Watch a wallet's loan health in real-time.
8
- * 3. Auto-liquidate underwater positions for the liquidation bonus.
6
+ * multi-token liquidation bot that discovers lending markets, profiles
7
+ * borrower wallets, predicts which loans will fail, and executes
8
+ * profitable liquidations.
9
9
  *
10
- * Torch lending lets token holders borrow SOL against their tokens
11
- * using community treasury liquidity. This bot watches those positions.
10
+ * modes:
11
+ * info — display lending parameters for a token (or all tokens) (default)
12
+ * watch — monitor your own loan health in real-time
13
+ * bot — run the full liquidation bot
12
14
  *
13
- * Usage:
14
- * # Monitor a token's lending stats
15
- * MODE=info MINT=<token-mint> npx tsx src/index.ts
15
+ * usage:
16
+ * # show all migrated tokens with lending
17
+ * RPC_URL=<rpc> npx tsx src/index.ts
16
18
  *
17
- * # Watch your own loan health
18
- * MODE=watch MINT=<token-mint> WALLET=<base58-key> npx tsx src/index.ts
19
+ * # show lending info for one token
20
+ * MODE=info MINT=<mint> RPC_URL=<rpc> npx tsx src/index.ts
19
21
  *
20
- * # Run as a liquidation bot (scans for liquidatable positions)
21
- * MODE=liquidate MINT=<token-mint> WALLET=<base58-key> npx tsx src/index.ts
22
+ * # watch your loan health
23
+ * MODE=watch MINT=<mint> WALLET=<key> RPC_URL=<rpc> npx tsx src/index.ts
24
+ *
25
+ * # run the liquidation bot
26
+ * MODE=bot WALLET=<key> RPC_URL=<rpc> npx tsx src/index.ts
22
27
  */
23
28
  var __importDefault = (this && this.__importDefault) || function (mod) {
24
29
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -27,15 +32,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
27
32
  const web3_js_1 = require("@solana/web3.js");
28
33
  const bs58_1 = __importDefault(require("bs58"));
29
34
  const torchsdk_1 = require("torchsdk");
35
+ const monitor_1 = require("./monitor");
36
+ const config_1 = require("./config");
37
+ const utils_1 = require("./utils");
30
38
  // ---------------------------------------------------------------------------
31
- // Config
32
- // ---------------------------------------------------------------------------
33
- const RPC_URL = process.env.RPC_URL ?? 'https://api.mainnet-beta.solana.com';
34
- const MINT = process.env.MINT;
35
- const MODE = process.env.MODE ?? 'info';
36
- const POLL_INTERVAL_MS = Number(process.env.POLL_INTERVAL_MS ?? '15000');
37
- // ---------------------------------------------------------------------------
38
- // Helpers
39
+ // helpers for info/watch modes (don't need full config)
39
40
  // ---------------------------------------------------------------------------
40
41
  function loadWallet() {
41
42
  const key = process.env.WALLET;
@@ -43,36 +44,49 @@ function loadWallet() {
43
44
  throw new Error('Set WALLET env var to a base58-encoded private key');
44
45
  return web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(key));
45
46
  }
46
- function sleep(ms) {
47
- return new Promise((r) => setTimeout(r, ms));
48
- }
49
- function sol(lamports) {
50
- return (lamports / torchsdk_1.LAMPORTS_PER_SOL).toFixed(4);
51
- }
52
- function bpsToPercent(bps) {
53
- return (bps / 100).toFixed(2) + '%';
54
- }
55
47
  // ---------------------------------------------------------------------------
56
- // Mode: info — display lending parameters for a token
48
+ // mode: info
57
49
  // ---------------------------------------------------------------------------
58
50
  async function showLendingInfo(connection, mint) {
59
51
  const token = await (0, torchsdk_1.getToken)(connection, mint);
60
52
  const lending = await (0, torchsdk_1.getLendingInfo)(connection, mint);
61
53
  console.log(`\n=== lending info: ${token.name} (${token.symbol}) ===`);
62
54
  console.log(`status: ${token.status}`);
63
- console.log(`token price: ${sol(token.price_sol)} SOL`);
64
- console.log(`interest rate: ${bpsToPercent(lending.interest_rate_bps)}`);
65
- console.log(`max LTV: ${bpsToPercent(lending.max_ltv_bps)}`);
66
- console.log(`liquidation threshold: ${bpsToPercent(lending.liquidation_threshold_bps)}`);
67
- console.log(`liquidation bonus: ${bpsToPercent(lending.liquidation_bonus_bps)}`);
68
- console.log(`treasury SOL avail: ${sol(lending.treasury_sol_available)} SOL`);
69
- console.log(`total SOL lent: ${sol(lending.total_sol_lent)} SOL`);
55
+ console.log(`token price: ${(0, utils_1.sol)(token.price_sol)} SOL`);
56
+ console.log(`interest rate: ${(0, utils_1.bpsToPercent)(lending.interest_rate_bps)}`);
57
+ console.log(`max LTV: ${(0, utils_1.bpsToPercent)(lending.max_ltv_bps)}`);
58
+ console.log(`liquidation threshold: ${(0, utils_1.bpsToPercent)(lending.liquidation_threshold_bps)}`);
59
+ console.log(`liquidation bonus: ${(0, utils_1.bpsToPercent)(lending.liquidation_bonus_bps)}`);
60
+ console.log(`treasury SOL avail: ${(0, utils_1.sol)(lending.treasury_sol_available)} SOL`);
61
+ console.log(`total SOL lent: ${(0, utils_1.sol)(lending.total_sol_lent)} SOL`);
70
62
  console.log(`active loans: ${lending.active_loans}`);
71
63
  }
64
+ async function showAllLending(connection) {
65
+ console.log('=== torch lending monitor ===\n');
66
+ console.log('no MINT specified — showing all migrated tokens with lending\n');
67
+ const { tokens } = await (0, torchsdk_1.getTokens)(connection, {
68
+ status: 'migrated',
69
+ sort: 'volume',
70
+ limit: 10,
71
+ });
72
+ for (const t of tokens) {
73
+ try {
74
+ const lending = await (0, torchsdk_1.getLendingInfo)(connection, t.mint);
75
+ console.log(`${t.symbol.padEnd(10)} | ` +
76
+ `rate: ${(0, utils_1.bpsToPercent)(lending.interest_rate_bps).padEnd(7)} | ` +
77
+ `loans: ${String(lending.active_loans).padEnd(4)} | ` +
78
+ `avail: ${(0, utils_1.sol)(lending.treasury_sol_available)} SOL`);
79
+ }
80
+ catch {
81
+ // token may not have lending enabled yet
82
+ }
83
+ }
84
+ }
72
85
  // ---------------------------------------------------------------------------
73
- // Mode: watch — monitor your own loan health
86
+ // mode: watch
74
87
  // ---------------------------------------------------------------------------
75
88
  async function watchPosition(connection, mint, wallet) {
89
+ const pollMs = Number(process.env.POLL_INTERVAL_MS ?? '15000');
76
90
  console.log(`\n=== watching loan: ${wallet.publicKey.toBase58()} ===`);
77
91
  console.log(`mint: ${mint}\n`);
78
92
  while (true) {
@@ -84,17 +98,16 @@ async function watchPosition(connection, mint, wallet) {
84
98
  const healthColor = pos.health === 'healthy' ? 'OK' : pos.health === 'at_risk' ? 'WARNING' : 'DANGER';
85
99
  console.log(`[${new Date().toISOString()}] health: ${healthColor} (${pos.health})`);
86
100
  console.log(` collateral: ${pos.collateral_amount} tokens`);
87
- console.log(` collat value: ${sol(pos.collateral_value_sol)} SOL`);
88
- console.log(` borrowed: ${sol(pos.borrowed_amount)} SOL`);
89
- console.log(` interest: ${sol(pos.accrued_interest)} SOL`);
90
- console.log(` total owed: ${sol(pos.total_owed)} SOL`);
91
- console.log(` current LTV: ${bpsToPercent(pos.current_ltv_bps)}`);
101
+ console.log(` collat value: ${(0, utils_1.sol)(pos.collateral_value_sol)} SOL`);
102
+ console.log(` borrowed: ${(0, utils_1.sol)(pos.borrowed_amount)} SOL`);
103
+ console.log(` interest: ${(0, utils_1.sol)(pos.accrued_interest)} SOL`);
104
+ console.log(` total owed: ${(0, utils_1.sol)(pos.total_owed)} SOL`);
105
+ console.log(` current LTV: ${(0, utils_1.bpsToPercent)(pos.current_ltv_bps)}`);
92
106
  if (pos.health === 'at_risk') {
93
107
  console.log(' --> consider adding collateral or repaying to avoid liquidation');
94
108
  }
95
109
  if (pos.health === 'liquidatable') {
96
110
  console.log(' --> your position can be liquidated! repay immediately');
97
- // auto-repay if enabled
98
111
  if (process.env.AUTO_REPAY === 'true') {
99
112
  console.log(' --> auto-repaying...');
100
113
  const { transaction, message } = await (0, torchsdk_1.buildRepayTransaction)(connection, {
@@ -110,98 +123,50 @@ async function watchPosition(connection, mint, wallet) {
110
123
  }
111
124
  }
112
125
  }
113
- await sleep(POLL_INTERVAL_MS);
126
+ await (0, utils_1.sleep)(pollMs);
114
127
  }
115
128
  }
116
129
  // ---------------------------------------------------------------------------
117
- // Mode: liquidate — scan holders for underwater positions
130
+ // main
118
131
  // ---------------------------------------------------------------------------
119
- async function runLiquidator(connection, mint, wallet) {
120
- console.log(`\n=== liquidation bot ===`);
121
- console.log(`mint: ${mint}`);
122
- console.log(`liquidator: ${wallet.publicKey.toBase58()}\n`);
123
- const lending = await (0, torchsdk_1.getLendingInfo)(connection, mint);
124
- console.log(`liquidation threshold: ${bpsToPercent(lending.liquidation_threshold_bps)}`);
125
- console.log(`liquidation bonus: ${bpsToPercent(lending.liquidation_bonus_bps)}`);
126
- console.log(`active loans: ${lending.active_loans}\n`);
127
- while (true) {
128
- console.log(`[${new Date().toISOString()}] scanning holders...`);
129
- const { holders } = await (0, torchsdk_1.getHolders)(connection, mint, 100);
130
- let liquidatable = 0;
131
- for (const holder of holders) {
132
- const pos = await (0, torchsdk_1.getLoanPosition)(connection, mint, holder.address);
133
- if (pos.health === 'liquidatable') {
134
- liquidatable++;
135
- console.log(` LIQUIDATABLE: ${holder.address}`);
136
- console.log(` collateral: ${pos.collateral_amount} tokens (${sol(pos.collateral_value_sol)} SOL)`);
137
- console.log(` owes: ${sol(pos.total_owed)} SOL`);
138
- console.log(` LTV: ${bpsToPercent(pos.current_ltv_bps)}`);
139
- try {
140
- const { transaction, message } = await (0, torchsdk_1.buildLiquidateTransaction)(connection, {
141
- mint,
142
- liquidator: wallet.publicKey.toBase58(),
143
- borrower: holder.address,
144
- });
145
- console.log(` tx: ${message}`);
146
- const sig = await (0, web3_js_1.sendAndConfirmTransaction)(connection, transaction, [wallet]);
147
- console.log(` confirmed: ${sig}`);
148
- const result = await (0, torchsdk_1.confirmTransaction)(connection, sig, wallet.publicKey.toBase58());
149
- console.log(` SAID event: ${result.event_type}`);
150
- }
151
- catch (err) {
152
- console.error(` failed: ${err instanceof Error ? err.message : err}`);
153
- }
154
- }
132
+ async function main() {
133
+ const MODE = process.env.MODE ?? 'info';
134
+ const MINT = process.env.MINT;
135
+ const RPC_URL = process.env.RPC_URL ?? 'https://api.mainnet-beta.solana.com';
136
+ // info mode: no wallet needed
137
+ if (MODE === 'info') {
138
+ const connection = new web3_js_1.Connection(RPC_URL, 'confirmed');
139
+ if (MINT) {
140
+ await showLendingInfo(connection, MINT);
155
141
  }
156
- if (liquidatable === 0) {
157
- console.log(' no liquidatable positions found');
142
+ else {
143
+ await showAllLending(connection);
158
144
  }
159
- await sleep(POLL_INTERVAL_MS);
145
+ return;
160
146
  }
161
- }
162
- // ---------------------------------------------------------------------------
163
- // Main
164
- // ---------------------------------------------------------------------------
165
- async function main() {
166
- if (!MINT) {
167
- // If no mint is specified, show lending info for all migrated tokens
168
- console.log('=== torch lending monitor ===\n');
169
- console.log('no MINT specified — showing all migrated tokens with lending\n');
147
+ // watch mode: single token + wallet
148
+ if (MODE === 'watch') {
149
+ if (!MINT)
150
+ throw new Error('MINT env var required for watch mode');
170
151
  const connection = new web3_js_1.Connection(RPC_URL, 'confirmed');
171
- const { tokens } = await (0, torchsdk_1.getTokens)(connection, {
172
- status: 'migrated',
173
- sort: 'volume',
174
- limit: 10,
175
- });
176
- for (const t of tokens) {
177
- try {
178
- const lending = await (0, torchsdk_1.getLendingInfo)(connection, t.mint);
179
- console.log(`${t.symbol.padEnd(10)} | ` +
180
- `rate: ${bpsToPercent(lending.interest_rate_bps).padEnd(7)} | ` +
181
- `loans: ${String(lending.active_loans).padEnd(4)} | ` +
182
- `avail: ${sol(lending.treasury_sol_available)} SOL`);
183
- }
184
- catch {
185
- // token may not have lending enabled yet
186
- }
187
- }
152
+ await watchPosition(connection, MINT, loadWallet());
188
153
  return;
189
154
  }
190
- const connection = new web3_js_1.Connection(RPC_URL, 'confirmed');
191
- switch (MODE) {
192
- case 'info':
193
- await showLendingInfo(connection, MINT);
194
- break;
195
- case 'watch':
196
- await watchPosition(connection, MINT, loadWallet());
197
- break;
198
- case 'liquidate':
199
- await runLiquidator(connection, MINT, loadWallet());
200
- break;
201
- default:
202
- console.error(`unknown MODE: ${MODE}. use info | watch | liquidate`);
203
- process.exit(1);
155
+ // bot mode: full liquidation bot
156
+ if (MODE === 'bot') {
157
+ const config = (0, config_1.loadConfig)();
158
+ const connection = new web3_js_1.Connection(config.rpcUrl, 'confirmed');
159
+ const monitor = new monitor_1.Monitor(connection, config);
160
+ // graceful shutdown
161
+ process.on('SIGINT', () => {
162
+ monitor.stop();
163
+ process.exit(0);
164
+ });
165
+ await monitor.start();
166
+ return;
204
167
  }
168
+ console.error(`unknown MODE: ${MODE}. use info | watch | bot`);
169
+ process.exit(1);
205
170
  }
206
171
  main();
207
172
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * liquidator.ts — executes liquidation transactions.
3
+ *
4
+ * receives a target, calculates expected profit, builds the tx,
5
+ * signs and sends it, then confirms via SAID for reputation.
6
+ */
7
+ import { type Connection } from '@solana/web3.js';
8
+ import type { ScoredLoan, LiquidationResult, BotConfig } from './types';
9
+ import type { Logger } from './logger';
10
+ export declare class Liquidator {
11
+ private log;
12
+ private wallet;
13
+ private minProfitLamports;
14
+ constructor(config: BotConfig, log: Logger);
15
+ tryLiquidate(connection: Connection, loan: ScoredLoan): Promise<LiquidationResult | null>;
16
+ }
17
+ //# sourceMappingURL=liquidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liquidator.d.ts","sourceRoot":"","sources":["../src/liquidator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,UAAU,EAA2C,MAAM,iBAAiB,CAAA;AAE1F,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAGtC,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAAQ;gBAErB,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM;IAMpC,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CA4DhG"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * liquidator.ts — executes liquidation transactions.
4
+ *
5
+ * receives a target, calculates expected profit, builds the tx,
6
+ * signs and sends it, then confirms via SAID for reputation.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Liquidator = void 0;
10
+ const web3_js_1 = require("@solana/web3.js");
11
+ const torchsdk_1 = require("torchsdk");
12
+ const utils_1 = require("./utils");
13
+ class Liquidator {
14
+ constructor(config, log) {
15
+ this.wallet = config.walletKeypair;
16
+ this.minProfitLamports = config.minProfitLamports;
17
+ this.log = log;
18
+ }
19
+ async tryLiquidate(connection, loan) {
20
+ if (loan.position.health !== 'liquidatable') {
21
+ this.log.debug(`skipping ${loan.borrower.slice(0, 8)}... — not liquidatable yet`);
22
+ return null;
23
+ }
24
+ if (loan.estimatedProfitLamports < this.minProfitLamports) {
25
+ this.log.debug(`skipping ${loan.borrower.slice(0, 8)}... — profit too low`, {
26
+ expected: (0, utils_1.sol)(loan.estimatedProfitLamports),
27
+ minimum: (0, utils_1.sol)(this.minProfitLamports),
28
+ });
29
+ return null;
30
+ }
31
+ this.log.info(`liquidating ${loan.borrower.slice(0, 8)}...`, {
32
+ token: loan.tokenName,
33
+ profit: `${(0, utils_1.sol)(loan.estimatedProfitLamports)} SOL`,
34
+ risk: loan.riskScore,
35
+ });
36
+ try {
37
+ const { transaction, message } = await (0, torchsdk_1.buildLiquidateTransaction)(connection, {
38
+ mint: loan.mint,
39
+ liquidator: this.wallet.publicKey.toBase58(),
40
+ borrower: loan.borrower,
41
+ });
42
+ this.log.debug(`tx built: ${message}`);
43
+ const signature = await (0, web3_js_1.sendAndConfirmTransaction)(connection, transaction, [this.wallet]);
44
+ this.log.info(`liquidation confirmed`, { sig: signature });
45
+ // confirm via SAID for reputation
46
+ let confirmed = false;
47
+ try {
48
+ const result = await (0, torchsdk_1.confirmTransaction)(connection, signature, this.wallet.publicKey.toBase58());
49
+ confirmed = result.confirmed;
50
+ this.log.debug(`SAID confirmation`, { event: result.event_type });
51
+ }
52
+ catch {
53
+ this.log.warn('SAID confirmation failed — tx still went through');
54
+ }
55
+ return {
56
+ mint: loan.mint,
57
+ borrower: loan.borrower,
58
+ signature,
59
+ profitLamports: loan.estimatedProfitLamports,
60
+ timestamp: Date.now(),
61
+ confirmed,
62
+ };
63
+ }
64
+ catch (err) {
65
+ const msg = err instanceof Error ? err.message : String(err);
66
+ this.log.error(`liquidation failed for ${loan.borrower.slice(0, 8)}...`, { error: msg });
67
+ return null;
68
+ }
69
+ }
70
+ }
71
+ exports.Liquidator = Liquidator;
72
+ //# sourceMappingURL=liquidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liquidator.js","sourceRoot":"","sources":["../src/liquidator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * logger.ts — simple structured logging with levels.
3
+ */
4
+ import type { LogLevel } from './types';
5
+ export declare class Logger {
6
+ private module;
7
+ private minLevel;
8
+ constructor(module: string, level: LogLevel);
9
+ debug(msg: string, data?: Record<string, unknown>): void;
10
+ info(msg: string, data?: Record<string, unknown>): void;
11
+ warn(msg: string, data?: Record<string, unknown>): void;
12
+ error(msg: string, data?: Record<string, unknown>): void;
13
+ child(module: string): Logger;
14
+ private levelName;
15
+ private log;
16
+ }
17
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AASvC,qBAAa,MAAM;IAIf,OAAO,CAAC,MAAM;IAHhB,OAAO,CAAC,QAAQ,CAAQ;gBAGd,MAAM,EAAE,MAAM,EACtB,KAAK,EAAE,QAAQ;IAKjB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIjD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIhD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIhD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIjD,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI7B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,GAAG;CAeZ"}
package/dist/logger.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * logger.ts — simple structured logging with levels.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Logger = void 0;
7
+ const LEVEL_PRIORITY = {
8
+ debug: 0,
9
+ info: 1,
10
+ warn: 2,
11
+ error: 3,
12
+ };
13
+ class Logger {
14
+ constructor(module, level) {
15
+ this.module = module;
16
+ this.minLevel = LEVEL_PRIORITY[level];
17
+ }
18
+ debug(msg, data) {
19
+ this.log('debug', msg, data);
20
+ }
21
+ info(msg, data) {
22
+ this.log('info', msg, data);
23
+ }
24
+ warn(msg, data) {
25
+ this.log('warn', msg, data);
26
+ }
27
+ error(msg, data) {
28
+ this.log('error', msg, data);
29
+ }
30
+ child(module) {
31
+ return new Logger(`${this.module}:${module}`, this.levelName());
32
+ }
33
+ levelName() {
34
+ const entry = Object.entries(LEVEL_PRIORITY).find(([, v]) => v === this.minLevel);
35
+ return (entry?.[0] ?? 'info');
36
+ }
37
+ log(level, msg, data) {
38
+ if (LEVEL_PRIORITY[level] < this.minLevel)
39
+ return;
40
+ const ts = new Date().toISOString();
41
+ const prefix = `[${ts}] [${level.toUpperCase().padEnd(5)}] [${this.module}]`;
42
+ if (data) {
43
+ const parts = Object.entries(data)
44
+ .map(([k, v]) => `${k}=${v}`)
45
+ .join(' ');
46
+ console.log(`${prefix} ${msg} | ${parts}`);
47
+ }
48
+ else {
49
+ console.log(`${prefix} ${msg}`);
50
+ }
51
+ }
52
+ }
53
+ exports.Logger = Logger;
54
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAIH,MAAM,cAAc,GAA6B;IAC/C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAA;AAED,MAAa,MAAM;IAGjB,YACU,MAAc,EACtB,KAAe;QADP,WAAM,GAAN,MAAM,CAAQ;QAGtB,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,IAA8B;QAC/C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,IAA8B;QAC9C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,IAA8B;QAC9C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,IAA8B;QAC/C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,MAAc;QAClB,OAAO,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;IACjE,CAAC;IAEO,SAAS;QACf,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAA;QACjF,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAa,CAAA;IAC3C,CAAC;IAEO,GAAG,CAAC,KAAe,EAAE,GAAW,EAAE,IAA8B;QACtE,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ;YAAE,OAAM;QAEjD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACnC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,GAAG,CAAA;QAE5E,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;iBAC/B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;iBAC5B,IAAI,CAAC,GAAG,CAAC,CAAA;YACZ,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,MAAM,KAAK,EAAE,CAAC,CAAA;QAC5C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;CACF;AAlDD,wBAkDC"}