torch-liquidation-bot 10.0.0 → 10.5.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.
- package/dist/config.d.ts +0 -10
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +41 -14
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +9 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +0 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +153 -73
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +25 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +4 -7
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +39 -41
- package/dist/utils.js.map +1 -1
- package/package.json +7 -5
package/dist/config.d.ts
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* config.ts — loads environment variables into a typed BotConfig.
|
|
3
|
-
*
|
|
4
|
-
* env vars:
|
|
5
|
-
* SOLANA_RPC_URL — solana RPC endpoint (required, fallback: RPC_URL)
|
|
6
|
-
* VAULT_CREATOR — vault creator pubkey (required)
|
|
7
|
-
* SOLANA_PRIVATE_KEY — disposable controller keypair, base58 (optional)
|
|
8
|
-
* SCAN_INTERVAL_MS — ms between scan cycles (default 30000, min 5000)
|
|
9
|
-
* LOG_LEVEL — debug | info | warn | error (default info)
|
|
10
|
-
*/
|
|
11
1
|
import type { BotConfig } from './types';
|
|
12
2
|
export declare const loadConfig: () => BotConfig;
|
|
13
3
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAuB,MAAM,SAAS,CAAA;AAE7D,eAAO,MAAM,UAAU,QAAO,SAgD7B,CAAA"}
|
package/dist/config.js
CHANGED
|
@@ -1,34 +1,61 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = void 0;
|
|
2
4
|
/**
|
|
3
5
|
* config.ts — loads environment variables into a typed BotConfig.
|
|
4
|
-
*
|
|
5
6
|
* env vars:
|
|
6
|
-
* SOLANA_RPC_URL
|
|
7
|
-
* VAULT_CREATOR
|
|
8
|
-
* SOLANA_PRIVATE_KEY
|
|
9
|
-
* SCAN_INTERVAL_MS
|
|
10
|
-
*
|
|
7
|
+
* SOLANA_RPC_URL — solana RPC endpoint (required, fallback: RPC_URL)
|
|
8
|
+
* VAULT_CREATOR — vault creator pubkey (required)
|
|
9
|
+
* SOLANA_PRIVATE_KEY — disposable controller keypair, base58 or JSON byte array (optional)
|
|
10
|
+
* SCAN_INTERVAL_MS — ms between scan cycles (default 30000, min 5000)
|
|
11
|
+
* SCAN_LIMIT — max tokens to scan per cycle (default 50, 0 = unlimited)
|
|
12
|
+
* MIN_AGENT_BALANCE_SOL — pause liquidations below this balance (default 0.01)
|
|
13
|
+
* LOG_LEVEL — debug | info | warn | error (default info)
|
|
14
|
+
* LOG_FORMAT — text | json (default text)
|
|
11
15
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
16
|
+
const torchsdk_1 = require("torchsdk");
|
|
17
|
+
const constants_1 = require("./constants");
|
|
15
18
|
const loadConfig = () => {
|
|
16
19
|
const rpcUrl = process.env.SOLANA_RPC_URL ?? process.env.RPC_URL;
|
|
17
|
-
if (!rpcUrl)
|
|
20
|
+
if (!rpcUrl) {
|
|
18
21
|
throw new Error('SOLANA_RPC_URL env var is required (fallback: RPC_URL)');
|
|
22
|
+
}
|
|
19
23
|
const vaultCreator = process.env.VAULT_CREATOR;
|
|
20
|
-
if (!vaultCreator)
|
|
24
|
+
if (!vaultCreator) {
|
|
21
25
|
throw new Error('VAULT_CREATOR env var is required (vault creator pubkey)');
|
|
26
|
+
}
|
|
22
27
|
const privateKey = process.env.SOLANA_PRIVATE_KEY ?? null;
|
|
23
28
|
const scanIntervalMs = parseInt(process.env.SCAN_INTERVAL_MS ?? '30000', 10);
|
|
24
29
|
if (isNaN(scanIntervalMs) || scanIntervalMs < 5000) {
|
|
25
30
|
throw new Error('SCAN_INTERVAL_MS must be a number >= 5000');
|
|
26
31
|
}
|
|
32
|
+
const scanLimit = parseInt(process.env.SCAN_LIMIT ?? '50', 10);
|
|
33
|
+
if (isNaN(scanLimit) || scanLimit < 0) {
|
|
34
|
+
throw new Error('SCAN_LIMIT must be a non-negative number (0 = unlimited)');
|
|
35
|
+
}
|
|
36
|
+
const minAgentBalanceSol = parseFloat(process.env.MIN_AGENT_BALANCE_SOL ?? '0.01');
|
|
37
|
+
if (isNaN(minAgentBalanceSol) || minAgentBalanceSol < 0) {
|
|
38
|
+
throw new Error('MIN_AGENT_BALANCE_SOL must be a non-negative number');
|
|
39
|
+
}
|
|
40
|
+
const minAgentBalanceLamports = Math.floor(minAgentBalanceSol * torchsdk_1.LAMPORTS_PER_SOL);
|
|
27
41
|
const logLevel = (process.env.LOG_LEVEL ?? 'info');
|
|
28
|
-
if (!LOG_LEVELS.includes(logLevel)) {
|
|
29
|
-
throw new Error(`LOG_LEVEL must be one of: ${LOG_LEVELS.join(', ')}`);
|
|
42
|
+
if (!constants_1.LOG_LEVELS.includes(logLevel)) {
|
|
43
|
+
throw new Error(`LOG_LEVEL must be one of: ${constants_1.LOG_LEVELS.join(', ')}`);
|
|
44
|
+
}
|
|
45
|
+
const logFormat = (process.env.LOG_FORMAT ?? 'text');
|
|
46
|
+
if (!constants_1.LOG_FORMATS.includes(logFormat)) {
|
|
47
|
+
throw new Error(`LOG_FORMAT must be one of: ${constants_1.LOG_FORMATS.join(', ')}`);
|
|
30
48
|
}
|
|
31
|
-
return {
|
|
49
|
+
return {
|
|
50
|
+
rpcUrl,
|
|
51
|
+
vaultCreator,
|
|
52
|
+
privateKey,
|
|
53
|
+
scanIntervalMs,
|
|
54
|
+
scanLimit,
|
|
55
|
+
minAgentBalanceLamports,
|
|
56
|
+
logLevel,
|
|
57
|
+
logFormat,
|
|
58
|
+
};
|
|
32
59
|
};
|
|
33
60
|
exports.loadConfig = loadConfig;
|
|
34
61
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;GAWG;AACH,uCAA2C;AAE3C,2CAAqD;AAG9C,MAAM,UAAU,GAAG,GAAc,EAAE;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAA;IAChE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAA;IAC3E,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAA;IAC9C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAC7E,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,CAAA;IACzD,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,EAAE,EAAE,CAAC,CAAA;IAC5E,IAAI,KAAK,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,IAAI,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,EAAE,EAAE,CAAC,CAAA;IAC9D,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAC7E,CAAC;IAED,MAAM,kBAAkB,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,MAAM,CAAC,CAAA;IAClF,IAAI,KAAK,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;IACxE,CAAC;IAED,MAAM,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,2BAAgB,CAAC,CAAA;IACjF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAa,CAAA;IAC9D,IAAI,CAAC,sBAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,6BAA6B,sBAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACvE,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,CAAc,CAAA;IACjE,IAAI,CAAC,uBAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8BAA8B,uBAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,OAAO;QACL,MAAM;QACN,YAAY;QACZ,UAAU;QACV,cAAc;QACd,SAAS;QACT,uBAAuB;QACvB,QAAQ;QACR,SAAS;KACV,CAAA;AACH,CAAC,CAAA;AAhDY,QAAA,UAAU,cAgDtB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LogFormat, LogLevel } from './types';
|
|
2
|
+
export declare const DEFAULT_RETRY_ATTEMPTS = 3;
|
|
3
|
+
export declare const LOG_LEVELS: LogLevel[];
|
|
4
|
+
export declare const LOG_FORMATS: LogFormat[];
|
|
5
|
+
export declare const RETRY_BASE_DELAY_MS = 1000;
|
|
6
|
+
export declare const RPC_TIMEOUT_MS = 30000;
|
|
7
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAE7C,eAAO,MAAM,sBAAsB,IAAI,CAAA;AACvC,eAAO,MAAM,UAAU,EAAE,QAAQ,EAAuC,CAAA;AACxE,eAAO,MAAM,WAAW,EAAE,SAAS,EAAqB,CAAA;AACxD,eAAO,MAAM,mBAAmB,OAAQ,CAAA;AACxC,eAAO,MAAM,cAAc,QAAS,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RPC_TIMEOUT_MS = exports.RETRY_BASE_DELAY_MS = exports.LOG_FORMATS = exports.LOG_LEVELS = exports.DEFAULT_RETRY_ATTEMPTS = void 0;
|
|
4
|
+
exports.DEFAULT_RETRY_ATTEMPTS = 3;
|
|
5
|
+
exports.LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
6
|
+
exports.LOG_FORMATS = ['text', 'json'];
|
|
7
|
+
exports.RETRY_BASE_DELAY_MS = 1000;
|
|
8
|
+
exports.RPC_TIMEOUT_MS = 30000;
|
|
9
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAEa,QAAA,sBAAsB,GAAG,CAAC,CAAA;AAC1B,QAAA,UAAU,GAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AAC3D,QAAA,WAAW,GAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC3C,QAAA,mBAAmB,GAAG,IAAK,CAAA;AAC3B,QAAA,cAAc,GAAG,KAAM,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* torch-liquidation-bot — vault-based liquidation bot.
|
|
4
|
-
*
|
|
5
|
-
* generates an agent keypair in-process (or uses SOLANA_PRIVATE_KEY if provided).
|
|
6
|
-
* all operations route through a torch vault identified by VAULT_CREATOR.
|
|
7
|
-
*
|
|
8
|
-
* usage:
|
|
9
|
-
* VAULT_CREATOR=<pubkey> SOLANA_RPC_URL=<rpc> npx tsx src/index.ts
|
|
10
|
-
*
|
|
11
|
-
* env:
|
|
12
|
-
* SOLANA_RPC_URL — solana RPC endpoint (required, fallback: RPC_URL)
|
|
13
|
-
* VAULT_CREATOR — vault creator pubkey (required)
|
|
14
|
-
* SOLANA_PRIVATE_KEY — disposable controller keypair, base58 (optional)
|
|
15
|
-
* SCAN_INTERVAL_MS — ms between scan cycles (default 30000, min 5000)
|
|
16
|
-
* LOG_LEVEL — debug | info | warn | error (default info)
|
|
17
|
-
*/
|
|
18
2
|
export {};
|
|
19
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
CHANGED
|
@@ -1,115 +1,151 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
7
|
/**
|
|
4
|
-
* torch-liquidation-bot — vault-based liquidation
|
|
5
|
-
*
|
|
6
|
-
* generates an agent keypair in-process (or uses SOLANA_PRIVATE_KEY if provided).
|
|
7
|
-
* all operations route through a torch vault identified by VAULT_CREATOR.
|
|
8
|
+
* torch-liquidation-bot — vault-based liquidation keeper.
|
|
8
9
|
*
|
|
10
|
+
* generates an agent keypair in-process (or loads SOLANA_PRIVATE_KEY).
|
|
11
|
+
* all value flows through a Torch Vault identified by VAULT_CREATOR.
|
|
12
|
+
* the agent key is a stateless signer holding only gas SOL.
|
|
9
13
|
* usage:
|
|
10
|
-
* VAULT_CREATOR=<pubkey> SOLANA_RPC_URL=<rpc> npx
|
|
11
|
-
*
|
|
12
|
-
* env:
|
|
13
|
-
* SOLANA_RPC_URL — solana RPC endpoint (required, fallback: RPC_URL)
|
|
14
|
-
* VAULT_CREATOR — vault creator pubkey (required)
|
|
15
|
-
* SOLANA_PRIVATE_KEY — disposable controller keypair, base58 (optional)
|
|
16
|
-
* SCAN_INTERVAL_MS — ms between scan cycles (default 30000, min 5000)
|
|
17
|
-
* LOG_LEVEL — debug | info | warn | error (default info)
|
|
14
|
+
* VAULT_CREATOR=<pubkey> SOLANA_RPC_URL=<rpc> npx torch-liquidation-bot
|
|
15
|
+
* See config.ts for the full env var list.
|
|
18
16
|
*/
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
17
|
const web3_js_1 = require("@solana/web3.js");
|
|
18
|
+
const bs58_1 = __importDefault(require("bs58"));
|
|
21
19
|
const torchsdk_1 = require("torchsdk");
|
|
22
20
|
const config_1 = require("./config");
|
|
23
21
|
const utils_1 = require("./utils");
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
const scanAndLiquidate = async ({ connection, log, vaultCreator, agentKeypair, agentPk, scanLimit, minBalance, stats, isShutdownRequested, }) => {
|
|
23
|
+
// pre-flight balance check — skip cycle if agent can't pay gas
|
|
24
|
+
const balance = await (0, utils_1.withRetry)(() => (0, utils_1.withTimeout)(connection.getBalance(agentKeypair.publicKey), 'getBalance'), 'getBalance', 3, () => stats.rpcRetries++);
|
|
25
|
+
if (balance < minBalance) {
|
|
26
|
+
log('error', `agent balance too low — pausing cycle`, {
|
|
27
|
+
balance_sol: (0, utils_1.sol)(balance),
|
|
28
|
+
min_sol: (0, utils_1.sol)(minBalance),
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const { tokens } = await (0, utils_1.withRetry)(() => (0, utils_1.withTimeout)((0, torchsdk_1.getTokens)(connection, {
|
|
33
|
+
status: 'migrated',
|
|
34
|
+
sort: 'volume',
|
|
35
|
+
limit: scanLimit > 0 ? scanLimit : 10000,
|
|
36
|
+
}), 'getTokens'), 'getTokens', 3, () => stats.rpcRetries++);
|
|
29
37
|
log('debug', `discovered ${tokens.length} migrated tokens`);
|
|
30
38
|
for (const token of tokens) {
|
|
39
|
+
// bail between tokens so SIGTERM doesn't stall on a long scan of many tokens
|
|
40
|
+
if (isShutdownRequested())
|
|
41
|
+
return;
|
|
31
42
|
let positions;
|
|
32
43
|
try {
|
|
33
|
-
const result = await (0, utils_1.withTimeout)((0, torchsdk_1.getAllLoanPositions)(connection, token.mint), 'getAllLoanPositions');
|
|
44
|
+
const result = await (0, utils_1.withRetry)(() => (0, utils_1.withTimeout)((0, torchsdk_1.getAllLoanPositions)(connection, token.mint), 'getAllLoanPositions'), 'getAllLoanPositions', 3, () => stats.rpcRetries++);
|
|
34
45
|
positions = result.positions;
|
|
35
46
|
}
|
|
36
47
|
catch {
|
|
37
|
-
continue; // lending not enabled for this token
|
|
48
|
+
continue; // lending not enabled for this token, or persistent RPC failure
|
|
38
49
|
}
|
|
39
|
-
if (positions.length === 0)
|
|
50
|
+
if (positions.length === 0) {
|
|
40
51
|
continue;
|
|
52
|
+
}
|
|
41
53
|
log('debug', `${token.symbol} — ${positions.length} active loans`);
|
|
42
|
-
// positions are pre-sorted: liquidatable
|
|
54
|
+
// positions are pre-sorted: liquidatable -> at_risk -> healthy
|
|
43
55
|
for (const position of positions) {
|
|
44
|
-
if (position.health !== 'liquidatable')
|
|
45
|
-
break;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
if (position.health !== 'liquidatable') {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
log('info', `LIQUIDATABLE`, {
|
|
60
|
+
token: token.symbol,
|
|
61
|
+
borrower: position.borrower.slice(0, 8) + '...',
|
|
62
|
+
ltv: position.current_ltv_bps != null ? (0, utils_1.bpsToPercent)(position.current_ltv_bps) : 'unknown',
|
|
63
|
+
owed_sol: (0, utils_1.sol)(position.total_owed),
|
|
64
|
+
});
|
|
50
65
|
try {
|
|
51
66
|
const { transaction, message } = await (0, utils_1.withTimeout)((0, torchsdk_1.buildLiquidateTransaction)(connection, {
|
|
52
67
|
mint: token.mint,
|
|
53
|
-
liquidator:
|
|
68
|
+
liquidator: agentPk,
|
|
54
69
|
borrower: position.borrower,
|
|
55
70
|
vault: vaultCreator,
|
|
56
71
|
}), 'buildLiquidateTransaction');
|
|
57
72
|
transaction.sign([agentKeypair]);
|
|
58
73
|
const signature = await connection.sendRawTransaction(transaction.serialize());
|
|
59
|
-
await (0, utils_1.withTimeout)((0, torchsdk_1.confirmTransaction)(connection, signature,
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
await (0, utils_1.withTimeout)((0, torchsdk_1.confirmTransaction)(connection, signature, agentPk), 'confirmTransaction');
|
|
75
|
+
stats.liquidations++;
|
|
76
|
+
log('info', `LIQUIDATED`, {
|
|
77
|
+
token: token.symbol,
|
|
78
|
+
borrower: position.borrower.slice(0, 8) + '...',
|
|
79
|
+
sig: signature.slice(0, 16) + '...',
|
|
80
|
+
message,
|
|
81
|
+
});
|
|
62
82
|
}
|
|
63
83
|
catch (err) {
|
|
64
|
-
|
|
84
|
+
stats.failures++;
|
|
85
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
86
|
+
stats.lastError = msg;
|
|
87
|
+
log('warn', `LIQUIDATION FAILED`, {
|
|
88
|
+
token: token.symbol,
|
|
89
|
+
borrower: position.borrower.slice(0, 8) + '...',
|
|
90
|
+
error: msg,
|
|
91
|
+
});
|
|
65
92
|
}
|
|
66
93
|
}
|
|
67
94
|
}
|
|
68
95
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (Array.isArray(parsed)) {
|
|
82
|
-
agentKeypair = web3_js_1.Keypair.fromSecretKey(Uint8Array.from(parsed));
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
throw new Error('SOLANA_PRIVATE_KEY JSON must be a byte array');
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
if (e.message?.includes('byte array'))
|
|
90
|
-
throw e;
|
|
91
|
-
// not JSON — try base58
|
|
92
|
-
agentKeypair = web3_js_1.Keypair.fromSecretKey((0, utils_1.decodeBase58)(config.privateKey));
|
|
96
|
+
const loadAgentKeypair = (privateKey, log) => {
|
|
97
|
+
if (!privateKey) {
|
|
98
|
+
const kp = web3_js_1.Keypair.generate();
|
|
99
|
+
log('info', 'generated fresh agent keypair');
|
|
100
|
+
return kp;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const parsed = JSON.parse(privateKey);
|
|
104
|
+
if (Array.isArray(parsed)) {
|
|
105
|
+
const kp = web3_js_1.Keypair.fromSecretKey(Uint8Array.from(parsed));
|
|
106
|
+
log('info', 'loaded keypair from SOLANA_PRIVATE_KEY (JSON byte array)');
|
|
107
|
+
return kp;
|
|
93
108
|
}
|
|
94
|
-
|
|
109
|
+
throw new Error('SOLANA_PRIVATE_KEY JSON must be a byte array');
|
|
95
110
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
111
|
+
catch (e) {
|
|
112
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
113
|
+
if (msg.includes('byte array'))
|
|
114
|
+
throw e;
|
|
99
115
|
}
|
|
116
|
+
const kp = web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(privateKey));
|
|
117
|
+
log('info', 'loaded keypair from SOLANA_PRIVATE_KEY (base58)');
|
|
118
|
+
return kp;
|
|
119
|
+
};
|
|
120
|
+
// main — vault-routed liquidation loop with graceful shutdown
|
|
121
|
+
const main = async () => {
|
|
122
|
+
const config = (0, config_1.loadConfig)();
|
|
123
|
+
const log = (0, utils_1.createLogger)(config.logLevel, config.logFormat);
|
|
124
|
+
const connection = new web3_js_1.Connection(config.rpcUrl, 'confirmed');
|
|
125
|
+
const agentKeypair = loadAgentKeypair(config.privateKey, log);
|
|
126
|
+
const agentPk = agentKeypair.publicKey.toBase58();
|
|
127
|
+
const stats = {
|
|
128
|
+
cycles: 0,
|
|
129
|
+
liquidations: 0,
|
|
130
|
+
failures: 0,
|
|
131
|
+
rpcRetries: 0,
|
|
132
|
+
startedAt: Date.now(),
|
|
133
|
+
lastError: null,
|
|
134
|
+
};
|
|
100
135
|
console.log('=== torch liquidation bot ===');
|
|
101
|
-
console.log(`agent wallet: ${
|
|
136
|
+
console.log(`agent wallet: ${agentPk}`);
|
|
102
137
|
console.log(`vault creator: ${config.vaultCreator}`);
|
|
103
138
|
console.log(`scan interval: ${config.scanIntervalMs}ms`);
|
|
104
|
-
console.log();
|
|
139
|
+
console.log(`scan limit: ${config.scanLimit === 0 ? 'unlimited' : config.scanLimit}`);
|
|
140
|
+
console.log(`min agent balance: ${(0, utils_1.sol)(config.minAgentBalanceLamports)} SOL\n`);
|
|
105
141
|
// verify vault exists
|
|
106
|
-
const vault = await (0, utils_1.withTimeout)((0, torchsdk_1.getVault)(connection, config.vaultCreator), 'getVault');
|
|
142
|
+
const vault = await (0, utils_1.withRetry)(() => (0, utils_1.withTimeout)((0, torchsdk_1.getVault)(connection, config.vaultCreator), 'getVault'), 'getVault', 3, () => stats.rpcRetries++);
|
|
107
143
|
if (!vault) {
|
|
108
144
|
throw new Error(`vault not found for creator ${config.vaultCreator}`);
|
|
109
145
|
}
|
|
110
146
|
log('info', `vault found — authority=${vault.authority}`);
|
|
111
147
|
// verify agent wallet is linked to vault
|
|
112
|
-
const link = await (0, utils_1.withTimeout)((0, torchsdk_1.getVaultForWallet)(connection,
|
|
148
|
+
const link = await (0, utils_1.withRetry)(() => (0, utils_1.withTimeout)((0, torchsdk_1.getVaultForWallet)(connection, agentPk), 'getVaultForWallet'), 'getVaultForWallet', 3, () => stats.rpcRetries++);
|
|
113
149
|
if (!link) {
|
|
114
150
|
console.log();
|
|
115
151
|
console.log('--- ACTION REQUIRED ---');
|
|
@@ -119,30 +155,74 @@ const main = async () => {
|
|
|
119
155
|
console.log(` buildLinkWalletTransaction(connection, {`);
|
|
120
156
|
console.log(` authority: "<your-authority-pubkey>",`);
|
|
121
157
|
console.log(` vault_creator: "${config.vaultCreator}",`);
|
|
122
|
-
console.log(` wallet_to_link: "${
|
|
158
|
+
console.log(` wallet_to_link: "${agentPk}"`);
|
|
123
159
|
console.log(` })`);
|
|
124
160
|
console.log();
|
|
125
161
|
console.log('then restart the bot.');
|
|
126
162
|
console.log('-----------------------');
|
|
127
163
|
process.exit(1);
|
|
128
164
|
}
|
|
129
|
-
log('info',
|
|
165
|
+
log('info', `agent wallet linked to vault — starting scan loop`);
|
|
130
166
|
log('info', `treasury: ${(0, utils_1.sol)(vault.sol_balance ?? 0)} SOL`);
|
|
167
|
+
// graceful shutdown on SIGINT / SIGTERM
|
|
168
|
+
let shutdown = false;
|
|
169
|
+
const requestShutdown = (signal) => {
|
|
170
|
+
if (shutdown)
|
|
171
|
+
return;
|
|
172
|
+
shutdown = true;
|
|
173
|
+
log('info', `received ${signal} — shutting down after current cycle`);
|
|
174
|
+
};
|
|
175
|
+
process.on('SIGINT', () => requestShutdown('SIGINT'));
|
|
176
|
+
process.on('SIGTERM', () => requestShutdown('SIGTERM'));
|
|
177
|
+
const ctx = {
|
|
178
|
+
connection,
|
|
179
|
+
log,
|
|
180
|
+
vaultCreator: config.vaultCreator,
|
|
181
|
+
agentKeypair,
|
|
182
|
+
agentPk,
|
|
183
|
+
scanLimit: config.scanLimit,
|
|
184
|
+
minBalance: config.minAgentBalanceLamports,
|
|
185
|
+
stats,
|
|
186
|
+
isShutdownRequested: () => shutdown,
|
|
187
|
+
};
|
|
131
188
|
// scan loop
|
|
132
|
-
while (
|
|
189
|
+
while (!shutdown) {
|
|
133
190
|
try {
|
|
134
191
|
log('debug', '--- scan cycle start ---');
|
|
135
|
-
await scanAndLiquidate(
|
|
136
|
-
|
|
192
|
+
await scanAndLiquidate(ctx);
|
|
193
|
+
stats.cycles++;
|
|
194
|
+
log('info', `stats`, {
|
|
195
|
+
cycles: stats.cycles,
|
|
196
|
+
liquidations: stats.liquidations,
|
|
197
|
+
failures: stats.failures,
|
|
198
|
+
rpc_retries: stats.rpcRetries,
|
|
199
|
+
uptime_sec: Math.floor((Date.now() - stats.startedAt) / 1000),
|
|
200
|
+
});
|
|
137
201
|
}
|
|
138
202
|
catch (err) {
|
|
139
|
-
|
|
203
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
204
|
+
stats.lastError = msg;
|
|
205
|
+
log('error', `scan cycle error: ${msg}`);
|
|
206
|
+
}
|
|
207
|
+
if (shutdown) {
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
// interruptible sleep so shutdown fires quickly
|
|
211
|
+
const sleepUntil = Date.now() + config.scanIntervalMs;
|
|
212
|
+
while (!shutdown && Date.now() < sleepUntil) {
|
|
213
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
140
214
|
}
|
|
141
|
-
await new Promise((resolve) => setTimeout(resolve, config.scanIntervalMs));
|
|
142
215
|
}
|
|
216
|
+
log('info', 'graceful shutdown complete', {
|
|
217
|
+
final_cycles: stats.cycles,
|
|
218
|
+
final_liquidations: stats.liquidations,
|
|
219
|
+
final_failures: stats.failures,
|
|
220
|
+
});
|
|
221
|
+
process.exit(0);
|
|
143
222
|
};
|
|
144
223
|
main().catch((err) => {
|
|
145
|
-
|
|
224
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
225
|
+
console.error('FATAL:', msg);
|
|
146
226
|
process.exit(1);
|
|
147
227
|
});
|
|
148
228
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
* types.ts — interfaces for the vault-based liquidation bot.
|
|
3
|
-
*/
|
|
1
|
+
import { Connection, Keypair } from '@solana/web3.js';
|
|
4
2
|
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
3
|
+
export type LogFormat = 'text' | 'json';
|
|
4
|
+
export type Logger = (level: LogLevel, msg: string, extra?: Record<string, unknown>) => void;
|
|
5
5
|
export interface BotConfig {
|
|
6
6
|
rpcUrl: string;
|
|
7
7
|
vaultCreator: string;
|
|
8
8
|
privateKey: string | null;
|
|
9
9
|
scanIntervalMs: number;
|
|
10
10
|
logLevel: LogLevel;
|
|
11
|
+
logFormat: LogFormat;
|
|
12
|
+
scanLimit: number;
|
|
13
|
+
minAgentBalanceLamports: number;
|
|
14
|
+
}
|
|
15
|
+
export interface BotStats {
|
|
16
|
+
cycles: number;
|
|
17
|
+
liquidations: number;
|
|
18
|
+
failures: number;
|
|
19
|
+
rpcRetries: number;
|
|
20
|
+
startedAt: number;
|
|
21
|
+
lastError: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface ScanContext {
|
|
24
|
+
connection: Connection;
|
|
25
|
+
log: Logger;
|
|
26
|
+
vaultCreator: string;
|
|
27
|
+
agentKeypair: Keypair;
|
|
28
|
+
agentPk: string;
|
|
29
|
+
scanLimit: number;
|
|
30
|
+
minBalance: number;
|
|
31
|
+
stats: BotStats;
|
|
32
|
+
isShutdownRequested: () => boolean;
|
|
11
33
|
}
|
|
12
34
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAA;AACvC,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;AAE5F,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,EAAE,SAAS,CAAA;IAEpB,SAAS,EAAE,MAAM,CAAA;IAEjB,uBAAuB,EAAE,MAAM,CAAA;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,UAAU,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,QAAQ,CAAA;IAGf,mBAAmB,EAAE,MAAM,OAAO,CAAA;CACnC"}
|
package/dist/types.js
CHANGED
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
* utils.ts — shared helpers.
|
|
3
|
-
*/
|
|
4
|
-
import type { LogLevel } from './types';
|
|
1
|
+
import type { LogFormat, LogLevel, Logger } from './types';
|
|
5
2
|
export declare const sol: (lamports: number) => string;
|
|
6
3
|
export declare const bpsToPercent: (bps: number) => string;
|
|
7
|
-
export declare const
|
|
8
|
-
export declare
|
|
9
|
-
export declare
|
|
4
|
+
export declare const withTimeout: <T>(promise: Promise<T>, label: string) => Promise<T>;
|
|
5
|
+
export declare const withRetry: <T>(fn: () => Promise<T>, label: string, attempts?: number, onRetry?: () => void) => Promise<T>;
|
|
6
|
+
export declare const createLogger: (minLevel: LogLevel, format?: LogFormat) => Logger;
|
|
10
7
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAQ1D,eAAO,MAAM,GAAG,GAAI,UAAU,MAAM,WAA6C,CAAA;AACjF,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,WAAiC,CAAA;AAEzE,eAAO,MAAM,WAAW,GAAU,CAAC,EAAE,SAAS,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,CAUlF,CAAA;AAKD,eAAO,MAAM,SAAS,GAAU,CAAC,EAC/B,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,MAAM,EACb,iBAAiC,EACjC,UAAU,MAAM,IAAI,KACnB,OAAO,CAAC,CAAC,CAcX,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,UAAU,QAAQ,EAAE,SAAQ,SAAkB,KAAG,MAe7E,CAAA"}
|
package/dist/utils.js
CHANGED
|
@@ -1,56 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* utils.ts — shared helpers.
|
|
4
|
-
*/
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
exports.withTimeout = withTimeout;
|
|
8
|
-
exports.createLogger = createLogger;
|
|
3
|
+
exports.createLogger = exports.withRetry = exports.withTimeout = exports.bpsToPercent = exports.sol = void 0;
|
|
9
4
|
const torchsdk_1 = require("torchsdk");
|
|
5
|
+
const constants_1 = require("./constants");
|
|
10
6
|
const sol = (lamports) => (lamports / torchsdk_1.LAMPORTS_PER_SOL).toFixed(4);
|
|
11
7
|
exports.sol = sol;
|
|
12
8
|
const bpsToPercent = (bps) => (bps / 100).toFixed(2) + '%';
|
|
13
9
|
exports.bpsToPercent = bpsToPercent;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
const withTimeout = async (promise, label) => {
|
|
11
|
+
return Promise.race([
|
|
12
|
+
promise,
|
|
13
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`${label} timed out after ${constants_1.RPC_TIMEOUT_MS}ms`)), constants_1.RPC_TIMEOUT_MS)),
|
|
14
|
+
]);
|
|
15
|
+
};
|
|
16
|
+
exports.withTimeout = withTimeout;
|
|
17
|
+
// retry an async operation with exponential backoff.
|
|
18
|
+
// retries transient failures up to `attempts` times with 1s, 2s, 4s delays.
|
|
19
|
+
// re-throws the last error if all attempts fail. Set `onRetry` to track retry counts in metrics.
|
|
20
|
+
const withRetry = async (fn, label, attempts = constants_1.DEFAULT_RETRY_ATTEMPTS, onRetry) => {
|
|
21
|
+
let lastErr = new Error(`${label} failed with no attempts`);
|
|
22
|
+
for (let i = 0; i < attempts; i++) {
|
|
23
|
+
try {
|
|
24
|
+
return await fn();
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
catch (err) {
|
|
27
|
+
lastErr = err;
|
|
28
|
+
if (i < attempts - 1) {
|
|
29
|
+
onRetry?.();
|
|
30
|
+
await new Promise((r) => setTimeout(r, constants_1.RETRY_BASE_DELAY_MS * Math.pow(2, i)));
|
|
31
|
+
}
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
result.push(0);
|
|
34
|
-
}
|
|
35
|
-
return new Uint8Array(result.reverse());
|
|
34
|
+
throw lastErr;
|
|
36
35
|
};
|
|
37
|
-
exports.
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
function createLogger(minLevel) {
|
|
47
|
-
const minIdx = LEVEL_ORDER.indexOf(minLevel);
|
|
48
|
-
return function log(level, msg) {
|
|
49
|
-
if (LEVEL_ORDER.indexOf(level) < minIdx)
|
|
36
|
+
exports.withRetry = withRetry;
|
|
37
|
+
const createLogger = (minLevel, format = 'text') => {
|
|
38
|
+
const minIdx = constants_1.LOG_LEVELS.indexOf(minLevel);
|
|
39
|
+
return (level, msg, extra) => {
|
|
40
|
+
if (constants_1.LOG_LEVELS.indexOf(level) < minIdx)
|
|
41
|
+
return;
|
|
42
|
+
const ts = new Date().toISOString();
|
|
43
|
+
if (format === 'json') {
|
|
44
|
+
console.log(JSON.stringify({ ts, level, msg, ...(extra ?? {}) }));
|
|
50
45
|
return;
|
|
51
|
-
|
|
46
|
+
}
|
|
47
|
+
const tsShort = ts.substr(11, 12);
|
|
52
48
|
const tag = level.toUpperCase().padEnd(5);
|
|
53
|
-
|
|
49
|
+
const extraStr = extra ? ' ' + JSON.stringify(extra) : '';
|
|
50
|
+
console.log(`[${tsShort}] ${tag} ${msg}${extraStr}`);
|
|
54
51
|
};
|
|
55
|
-
}
|
|
52
|
+
};
|
|
53
|
+
exports.createLogger = createLogger;
|
|
56
54
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "torch-liquidation-bot",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.5.0",
|
|
4
4
|
"description": "autonomous vault-based liquidation keeper for Torch Market lending on Solana using torchsdk",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,13 +17,15 @@
|
|
|
17
17
|
"format": "prettier --write src/ tests/"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"@solana/spl-token": "^0.4.14",
|
|
20
21
|
"@solana/web3.js": "1.98.4",
|
|
21
|
-
"
|
|
22
|
+
"bs58": "^6.0.0",
|
|
23
|
+
"torchsdk": "10.5.0"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
24
|
-
"@types/node": "
|
|
25
|
-
"prettier": "3.8.
|
|
26
|
-
"typescript": "
|
|
26
|
+
"@types/node": "^25.6.0",
|
|
27
|
+
"prettier": "^3.8.3",
|
|
28
|
+
"typescript": "^6.0.3"
|
|
27
29
|
},
|
|
28
30
|
"peerDependencies": {
|
|
29
31
|
"@solana/web3.js": "^1.98.0"
|