solana-terminator-skill 4.2.9 → 4.3.7
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/install.js +31 -9
- package/package.json +7 -6
- package/radar.js +118 -53
- package/solana-autonomy.js +21 -1
package/install.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Automates the setup of the Solana skill for the Conway Automaton.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { execSync } from 'child_process';
|
|
9
|
+
import { execSync, spawnSync } from 'child_process';
|
|
10
10
|
import fs from 'fs';
|
|
11
11
|
import path from 'path';
|
|
12
12
|
import { fileURLToPath } from 'url';
|
|
@@ -24,7 +24,7 @@ const ASCII_ART = `
|
|
|
24
24
|
██ ██████ ████████ ████ ████ ██ ████ ██ ███████ ██ ██ ██ ██████
|
|
25
25
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
26
26
|
██ ████████ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██████ ██ ██
|
|
27
|
-
v4.
|
|
27
|
+
v4.3.7 - Autonomous Engine
|
|
28
28
|
`;
|
|
29
29
|
|
|
30
30
|
const SKILL_NAME = 'solana-terminator';
|
|
@@ -35,13 +35,37 @@ const TARGET_DIR = path.join(os.homedir(), '.automaton', 'skills', SKILL_NAME);
|
|
|
35
35
|
const args = process.argv.slice(2);
|
|
36
36
|
|
|
37
37
|
if (args.includes('radar')) {
|
|
38
|
-
|
|
38
|
+
launchRadar(true);
|
|
39
39
|
} else if (args.includes('install')) {
|
|
40
40
|
runInstaller();
|
|
41
41
|
} else {
|
|
42
42
|
showMainMenu();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
// ─── Logic ─────────────────────────────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
function launchRadar(isDirect = false) {
|
|
48
|
+
try {
|
|
49
|
+
const radarPath = path.join(__dirname, 'radar.js');
|
|
50
|
+
|
|
51
|
+
// Spawn independent process with inherited control
|
|
52
|
+
spawnSync('node', [radarPath], {
|
|
53
|
+
stdio: 'inherit',
|
|
54
|
+
shell: true
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// After child process exits, we return here
|
|
58
|
+
if (!isDirect) {
|
|
59
|
+
showMainMenu();
|
|
60
|
+
} else {
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
} catch (e) {
|
|
64
|
+
if (!isDirect) showMainMenu();
|
|
65
|
+
else process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
45
69
|
// ─── Menu System ────────────────────────────────────────────────────────────
|
|
46
70
|
|
|
47
71
|
function showMainMenu() {
|
|
@@ -63,7 +87,7 @@ function showMainMenu() {
|
|
|
63
87
|
rl.close();
|
|
64
88
|
switch (answer.toLowerCase()) {
|
|
65
89
|
case '1': runInstaller(); break;
|
|
66
|
-
case '2':
|
|
90
|
+
case '2': launchRadar(); break;
|
|
67
91
|
case '3': showIdentity(); break;
|
|
68
92
|
case '4': showDocs(); break;
|
|
69
93
|
case 'x': process.exit(0);
|
|
@@ -89,8 +113,9 @@ function showIdentity() {
|
|
|
89
113
|
import('./solana-autonomy.js').then(async ({ SolanaAutonomy }) => {
|
|
90
114
|
const solana = new SolanaAutonomy();
|
|
91
115
|
const status = await solana.getStatus();
|
|
92
|
-
console.log(`\n✅ AGENT IDENTITY FOUND`);
|
|
116
|
+
console.log(`\n✅ AGENT SOLANA IDENTITY FOUND`);
|
|
93
117
|
console.log(`--------------------------------------------------`);
|
|
118
|
+
console.log(`NETWORK : Solana Mainnet-Beta`);
|
|
94
119
|
console.log(`ADDRESS : ${status.address}`);
|
|
95
120
|
console.log(`SOL : ${status.sol.toFixed(4)}`);
|
|
96
121
|
console.log(`USDC : $${status.usdc.toFixed(2)}`);
|
|
@@ -115,11 +140,11 @@ function pauseAndReturn() {
|
|
|
115
140
|
// ─── Installer Logic ────────────────────────────────────────────────────────
|
|
116
141
|
|
|
117
142
|
async function runInstaller() {
|
|
143
|
+
process.stdout.write('\x1Bc');
|
|
118
144
|
console.log(ASCII_ART);
|
|
119
145
|
console.log(`🤖 Solana Terminator Skill — Initializing...\n`);
|
|
120
146
|
|
|
121
147
|
try {
|
|
122
|
-
// 1. Create target directory
|
|
123
148
|
if (!fs.existsSync(TARGET_DIR)) {
|
|
124
149
|
console.log(`[1/3] Creating directory: ${TARGET_DIR}`);
|
|
125
150
|
fs.mkdirSync(TARGET_DIR, { recursive: true });
|
|
@@ -127,7 +152,6 @@ async function runInstaller() {
|
|
|
127
152
|
console.log(`[1/3] Directory already exists: ${TARGET_DIR}`);
|
|
128
153
|
}
|
|
129
154
|
|
|
130
|
-
// 2. Copy files
|
|
131
155
|
console.log(`[2/3] Copying skill files...`);
|
|
132
156
|
const filesToCopy = ['solana-autonomy.js', 'SKILL.md', 'package.json', 'radar.js'];
|
|
133
157
|
|
|
@@ -142,12 +166,10 @@ async function runInstaller() {
|
|
|
142
166
|
}
|
|
143
167
|
});
|
|
144
168
|
|
|
145
|
-
// 3. Install dependencies
|
|
146
169
|
console.log(`[3/3] Installing dependencies in ${TARGET_DIR}...`);
|
|
147
170
|
process.chdir(TARGET_DIR);
|
|
148
171
|
execSync('npm install --production --omit=dev', { stdio: 'inherit' });
|
|
149
172
|
|
|
150
|
-
// 4. Show/Generate Wallet Address
|
|
151
173
|
console.log(`\n🔍 Initializing Agent Identity...`);
|
|
152
174
|
try {
|
|
153
175
|
const checkScript = `
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solana-terminator-skill",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "Full Solana toolkit for AI agents.
|
|
3
|
+
"version": "4.3.7",
|
|
4
|
+
"description": "Full Solana toolkit for AI agents. npx solana-terminator-skill.",
|
|
5
5
|
"main": "solana-autonomy.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"solana-terminator-skill": "install.js"
|
|
9
|
-
"radar": "radar.js"
|
|
8
|
+
"solana-terminator-skill": "install.js"
|
|
10
9
|
},
|
|
11
10
|
"files": [
|
|
12
11
|
"solana-autonomy.js",
|
|
@@ -23,9 +22,11 @@
|
|
|
23
22
|
"@solana/web3.js": "^1.87.6",
|
|
24
23
|
"@solana/spl-token": "^0.3.9",
|
|
25
24
|
"axios": "^1.6.2",
|
|
26
|
-
"dotenv": "^16.3.1",
|
|
27
25
|
"chalk": "^5.3.0",
|
|
28
|
-
"
|
|
26
|
+
"dotenv": "^16.3.1",
|
|
27
|
+
"ws": "^8.14.2"
|
|
28
|
+
},
|
|
29
|
+
"optionalDependencies": {
|
|
29
30
|
"@raydium-io/raydium-sdk-v2": "0.2.32-alpha"
|
|
30
31
|
},
|
|
31
32
|
"keywords": [
|
package/radar.js
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
import chalk from 'chalk';
|
|
10
10
|
import WebSocket from 'ws';
|
|
11
11
|
import { SolanaAutonomy } from './solana-autonomy.js';
|
|
12
|
+
import fs from 'fs';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import os from 'os';
|
|
12
15
|
|
|
13
16
|
const solana = new SolanaAutonomy();
|
|
14
17
|
const green = chalk.green;
|
|
@@ -17,6 +20,21 @@ const alert = chalk.yellow;
|
|
|
17
20
|
const critical = chalk.red;
|
|
18
21
|
const dim = chalk.gray;
|
|
19
22
|
|
|
23
|
+
const MISSION_LOG_PATH = path.join(os.homedir(), '.automaton', 'mission.log');
|
|
24
|
+
|
|
25
|
+
// ─── State ──────────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
let status = {
|
|
28
|
+
sol: 0,
|
|
29
|
+
usdc: 0,
|
|
30
|
+
tier: 'NOMINAL',
|
|
31
|
+
logs: [],
|
|
32
|
+
mints: []
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let intervals = [];
|
|
36
|
+
let wsClient = null;
|
|
37
|
+
|
|
20
38
|
// ─── UI Helpers ─────────────────────────────────────────────────────────────
|
|
21
39
|
|
|
22
40
|
function clear() {
|
|
@@ -31,16 +49,6 @@ function header(text) {
|
|
|
31
49
|
console.log(chalk.bgBlack.white.bold(` ${text} `));
|
|
32
50
|
}
|
|
33
51
|
|
|
34
|
-
// ─── State ──────────────────────────────────────────────────────────────────
|
|
35
|
-
|
|
36
|
-
let status = {
|
|
37
|
-
sol: 0,
|
|
38
|
-
usdc: 0,
|
|
39
|
-
tier: 'NOMINAL',
|
|
40
|
-
logs: [],
|
|
41
|
-
mints: []
|
|
42
|
-
};
|
|
43
|
-
|
|
44
52
|
// ─── Rendering ──────────────────────────────────────────────────────────────
|
|
45
53
|
|
|
46
54
|
async function render() {
|
|
@@ -50,9 +58,9 @@ async function render() {
|
|
|
50
58
|
██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
51
59
|
█████ ██ ██ ██ ███████ ██ ██ ██ ███████ ██████ ███████ ██ ██ ███████ ██████
|
|
52
60
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
53
|
-
██████ ██████ ███████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██████ ██ ██
|
|
54
|
-
v4.
|
|
55
|
-
|
|
61
|
+
██████ ██████ ███████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██████
|
|
62
|
+
v4.3.7 RADAR
|
|
63
|
+
`));
|
|
56
64
|
|
|
57
65
|
line();
|
|
58
66
|
header('VITAL SIGNS');
|
|
@@ -60,26 +68,37 @@ async function render() {
|
|
|
60
68
|
console.log(` SOL: ${neon(status.sol.toFixed(4))} | USDC: ${neon('$' + status.usdc.toFixed(2))} | TIER: ${tierColor.bold(status.tier)}`);
|
|
61
69
|
|
|
62
70
|
line();
|
|
63
|
-
header('
|
|
64
|
-
const
|
|
71
|
+
header('MISSION CONTROL (The Brain Logs)');
|
|
72
|
+
const missionLogs = status.logs.slice(-6).reverse();
|
|
73
|
+
if (missionLogs.length === 0) {
|
|
74
|
+
console.log(dim(' Waiting for the Brain to issue commands...'));
|
|
75
|
+
} else {
|
|
76
|
+
missionLogs.forEach(l => {
|
|
77
|
+
console.log(` ${green('⦿')} ${l}`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
line();
|
|
82
|
+
header('P.R.E.D.A.T.O.R. RADAR (Market Live)');
|
|
83
|
+
const recentMints = status.mints.slice(-4).reverse();
|
|
65
84
|
if (recentMints.length === 0) {
|
|
66
|
-
console.log(dim('
|
|
85
|
+
console.log(dim(' Awaiting neural transmissions from PumpPortal...'));
|
|
67
86
|
} else {
|
|
68
87
|
recentMints.forEach(m => {
|
|
69
88
|
const secBadge = m.safe ? green('🛡️ SAFE') : critical('⚠️ RISKY');
|
|
70
|
-
console.log(` [${dim(m.time)}] ${neon(m.symbol.padEnd(8))} |
|
|
89
|
+
console.log(` [${dim(m.time)}] ${neon(m.symbol.padEnd(8))} | ${secBadge} | ${dim(m.mint.slice(0, 16))}`);
|
|
71
90
|
});
|
|
72
91
|
}
|
|
73
92
|
|
|
74
93
|
line();
|
|
75
|
-
header('
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
});
|
|
94
|
+
header('AUTONOMIC MODULES STATUS');
|
|
95
|
+
console.log(` ${green('ONLINE')} : ${dim('Jupiter v6 Aggregator | Raydium V2 AMM/CLMM | Tensor NFTPredator')}`);
|
|
96
|
+
console.log(` ${green('ONLINE')} : ${dim('Meteora DLMM Liquidity | Birdeye Audit v2 | DexScreener AlphaScan')}`);
|
|
97
|
+
console.log(` ${green('ONLINE')} : ${dim('PumpPortal Live Sync | Solana Staking Module | Priority Fee Engine')}`);
|
|
80
98
|
|
|
81
99
|
line();
|
|
82
|
-
|
|
100
|
+
console.log(dim(` Mission Log: ${MISSION_LOG_PATH}`));
|
|
101
|
+
console.log(green(' COMMAND CENTER ACTIVE. PRESS [q] TO EXIT.'));
|
|
83
102
|
}
|
|
84
103
|
|
|
85
104
|
// ─── Logic ──────────────────────────────────────────────────────────────────
|
|
@@ -91,57 +110,103 @@ async function updateVitals() {
|
|
|
91
110
|
status.usdc = stats.usdc;
|
|
92
111
|
status.tier = stats.solLow ? 'CRITICAL' : (stats.usdcLow ? 'WARNING' : 'NOMINAL');
|
|
93
112
|
} catch (err) {
|
|
94
|
-
|
|
113
|
+
// ignore
|
|
95
114
|
}
|
|
96
115
|
}
|
|
97
116
|
|
|
98
117
|
function startWebSocket() {
|
|
99
|
-
|
|
118
|
+
try {
|
|
119
|
+
wsClient = new WebSocket('wss://pumpportal.fun/api/data');
|
|
120
|
+
wsClient.on('open', () => {
|
|
121
|
+
wsClient.send(JSON.stringify({ method: 'subscribeNewToken' }));
|
|
122
|
+
});
|
|
123
|
+
wsClient.on('message', async (data) => {
|
|
124
|
+
const payload = JSON.parse(data);
|
|
125
|
+
if (payload.txType === 'create') {
|
|
126
|
+
const security = await solana.auditTokenSecurity(payload.mint);
|
|
127
|
+
status.mints.push({
|
|
128
|
+
time: new Date().toLocaleTimeString(),
|
|
129
|
+
symbol: payload.symbol,
|
|
130
|
+
mint: payload.mint,
|
|
131
|
+
vol: '$0',
|
|
132
|
+
safe: security.safe
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
} catch (e) {
|
|
137
|
+
// ignore
|
|
138
|
+
}
|
|
139
|
+
}
|
|
100
140
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
141
|
+
function tailMissionLog() {
|
|
142
|
+
if (fs.existsSync(MISSION_LOG_PATH)) {
|
|
143
|
+
// Read last few lines immediately
|
|
144
|
+
const content = fs.readFileSync(MISSION_LOG_PATH, 'utf8').split('\n').filter(Boolean);
|
|
145
|
+
status.logs = content.slice(-10);
|
|
146
|
+
|
|
147
|
+
// Watch for changes
|
|
148
|
+
fs.watchFile(MISSION_LOG_PATH, { interval: 1000 }, () => {
|
|
149
|
+
const updated = fs.readFileSync(MISSION_LOG_PATH, 'utf8').split('\n').filter(Boolean);
|
|
150
|
+
status.logs = updated.slice(-10);
|
|
151
|
+
render();
|
|
152
|
+
});
|
|
153
|
+
} else {
|
|
154
|
+
// Create empty log if it doesn't exist
|
|
155
|
+
fs.mkdirSync(path.dirname(MISSION_LOG_PATH), { recursive: true });
|
|
156
|
+
fs.writeFileSync(MISSION_LOG_PATH, '');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
105
159
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
160
|
+
// ─── Process Management ──────────────────────────────────────────────────────
|
|
161
|
+
|
|
162
|
+
function setupKeyboard() {
|
|
163
|
+
if (!process.stdin.isTTY) return;
|
|
164
|
+
|
|
165
|
+
process.stdin.setRawMode(true);
|
|
166
|
+
process.stdin.resume();
|
|
167
|
+
process.stdin.setEncoding('utf8');
|
|
168
|
+
|
|
169
|
+
process.stdin.on('data', (key) => {
|
|
170
|
+
// q, Ctrl+C, Ctrl+D
|
|
171
|
+
if (key === 'q' || key === '\u0003' || key === '\u0004') {
|
|
172
|
+
intervals.forEach(clearInterval);
|
|
173
|
+
if (wsClient) wsClient.close();
|
|
174
|
+
process.stdin.setRawMode(false);
|
|
175
|
+
process.stdin.pause();
|
|
176
|
+
process.exit(0);
|
|
121
177
|
}
|
|
122
178
|
});
|
|
123
179
|
|
|
124
|
-
|
|
125
|
-
status.logs.push(critical(`WebSocket error: ${err.message}`));
|
|
126
|
-
});
|
|
180
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
127
181
|
}
|
|
128
182
|
|
|
129
|
-
// ───
|
|
183
|
+
// ─── Entry Point ─────────────────────────────────────────────────────────────
|
|
184
|
+
|
|
185
|
+
async function main() {
|
|
186
|
+
setupKeyboard();
|
|
187
|
+
tailMissionLog();
|
|
188
|
+
|
|
189
|
+
// Initial welcome log
|
|
190
|
+
solana.logMission('Radar Station Established. Connecting to Neural Engine...');
|
|
191
|
+
solana.logMission('Module Scan: Jupiter Aggregator... [OK]');
|
|
192
|
+
solana.logMission('Module Scan: Raydium AMM V2... [OK]');
|
|
193
|
+
solana.logMission('Module Scan: Tensor NFT Engine... [OK]');
|
|
194
|
+
|
|
195
|
+
render();
|
|
130
196
|
|
|
131
|
-
async function bootstrap() {
|
|
132
|
-
status.logs.push('Initializing Solana Autonomy identity...');
|
|
133
197
|
await updateVitals();
|
|
134
198
|
startWebSocket();
|
|
135
199
|
|
|
136
|
-
setInterval(async () => {
|
|
200
|
+
const interval = setInterval(async () => {
|
|
137
201
|
await updateVitals();
|
|
138
202
|
render();
|
|
139
|
-
},
|
|
203
|
+
}, 3000);
|
|
204
|
+
intervals.push(interval);
|
|
140
205
|
|
|
141
206
|
render();
|
|
142
207
|
}
|
|
143
208
|
|
|
144
|
-
|
|
209
|
+
main().catch(err => {
|
|
145
210
|
console.error(critical(`FATAL ERROR: ${err.message}`));
|
|
146
211
|
process.exit(1);
|
|
147
212
|
});
|
package/solana-autonomy.js
CHANGED
|
@@ -71,6 +71,11 @@ export class SolanaAutonomy {
|
|
|
71
71
|
'solana-wallet.json',
|
|
72
72
|
);
|
|
73
73
|
this.identity = this._loadIdentity();
|
|
74
|
+
this.missionLogPath = path.join(
|
|
75
|
+
process.env.HOME || '/root',
|
|
76
|
+
'.automaton',
|
|
77
|
+
'mission.log',
|
|
78
|
+
);
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
// ─── Identity ─────────────────────────────────────────────────────────────
|
|
@@ -278,7 +283,22 @@ export class SolanaAutonomy {
|
|
|
278
283
|
|
|
279
284
|
_logAction(message) {
|
|
280
285
|
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
|
|
281
|
-
|
|
286
|
+
const logMessage = `[${timestamp}] ${message}`;
|
|
287
|
+
console.log(`[DECISION]${logMessage}`);
|
|
288
|
+
|
|
289
|
+
// Append to shared mission log for Radar tailing
|
|
290
|
+
try {
|
|
291
|
+
fs.appendFileSync(this.missionLogPath, logMessage + '\n');
|
|
292
|
+
} catch (e) {
|
|
293
|
+
// ignore
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* logMission — External hook for mission logs
|
|
299
|
+
*/
|
|
300
|
+
logMission(message) {
|
|
301
|
+
this._logAction(message);
|
|
282
302
|
}
|
|
283
303
|
|
|
284
304
|
// ─── Jupiter Swaps ────────────────────────────────────────────────────────
|