solana-terminator-skill 4.3.11 → 4.3.15
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 +98 -101
- package/package.json +1 -1
- package/radar.js +24 -20
- package/solana-autonomy.js +67 -10
package/install.js
CHANGED
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* P.R.E.D.A.T.O.R. Installer
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Sets up the autonomous identity and mission control.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { execSync, spawnSync } from 'child_process';
|
|
10
9
|
import fs from 'fs';
|
|
11
10
|
import path from 'path';
|
|
12
|
-
import { fileURLToPath } from 'url';
|
|
13
11
|
import os from 'os';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
import { spawnSync } from 'child_process';
|
|
14
14
|
import readline from 'readline';
|
|
15
|
+
import chalk from 'chalk';
|
|
15
16
|
|
|
16
17
|
const __filename = fileURLToPath(import.meta.url);
|
|
17
18
|
const __dirname = path.dirname(__filename);
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
const green = chalk.green;
|
|
21
|
+
const neon = chalk.cyan;
|
|
22
|
+
const alert = chalk.yellow;
|
|
23
|
+
const critical = chalk.red;
|
|
24
|
+
const dim = chalk.gray;
|
|
20
25
|
|
|
21
26
|
const ASCII_ART = `
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
v4.3.
|
|
27
|
+
██████ ██████ ███████ ██████ █████ ████████ ██████ ██████
|
|
28
|
+
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
29
|
+
██████ ██████ █████ ██ ██ ███████ ██ ██ ██ ██████
|
|
30
|
+
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
31
|
+
██ ██ ██ ███████ ██████ ██ ██ ██ ██████ ██ ██
|
|
32
|
+
v4.3.15 - Freedom Update
|
|
28
33
|
`;
|
|
29
34
|
|
|
30
35
|
const SKILL_NAME = 'solana-terminator';
|
|
31
36
|
const TARGET_DIR = path.join(os.homedir(), '.automaton', 'skills', SKILL_NAME);
|
|
37
|
+
const ENV_FILE = path.join(os.homedir(), '.automaton', '.env');
|
|
32
38
|
|
|
33
39
|
// ─── Command Routing ────────────────────────────────────────────────────────
|
|
34
40
|
|
|
@@ -42,19 +48,46 @@ if (args.includes('radar')) {
|
|
|
42
48
|
showMainMenu();
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
// ───
|
|
51
|
+
// ─── Main Menu ──────────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
function showMainMenu() {
|
|
54
|
+
process.stdout.write('\x1Bc');
|
|
55
|
+
console.log(green(ASCII_ART));
|
|
56
|
+
console.log(dim(` Tactical Directory: ${TARGET_DIR}\n`));
|
|
57
|
+
|
|
58
|
+
console.log(`${neon('[1]')} Reset/Install Solana Agent Identity`);
|
|
59
|
+
console.log(`${neon('[2]')} Launch P.R.E.D.A.T.O.R. Mission Control (Radar)`);
|
|
60
|
+
console.log(`${neon('[3]')} View Agent Identity (Address & Balances)`);
|
|
61
|
+
console.log(`${neon('[4]')} Configure Birdeye API Key (Security)`);
|
|
62
|
+
console.log(`${neon('[5]')} Configure Master Wallet (Tribute Threshold)`);
|
|
63
|
+
console.log(`${neon('[6]')} View Tactical Documentation`);
|
|
64
|
+
console.log(`${neon('[q]')} Exit Terminal`);
|
|
65
|
+
|
|
66
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
67
|
+
rl.question(green('\nSelect tactical option: '), (choice) => {
|
|
68
|
+
rl.close();
|
|
69
|
+
switch (choice.toLowerCase()) {
|
|
70
|
+
case '1': runInstaller().then(() => pauseAndReturn()); break;
|
|
71
|
+
case '2': launchRadar(false); break;
|
|
72
|
+
case '3': showIdentity(); break;
|
|
73
|
+
case '4': configureApi(); break;
|
|
74
|
+
case '5': configureMaster(); break;
|
|
75
|
+
case '6': viewDocs(); break;
|
|
76
|
+
case 'q': process.exit(0);
|
|
77
|
+
default: showMainMenu();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
46
81
|
|
|
47
82
|
function launchRadar(isDirect = false) {
|
|
48
83
|
try {
|
|
49
84
|
const radarPath = path.join(__dirname, 'radar.js');
|
|
50
85
|
|
|
51
|
-
// Spawn independent process with inherited control
|
|
52
86
|
spawnSync('node', [radarPath], {
|
|
53
87
|
stdio: 'inherit',
|
|
54
88
|
shell: true
|
|
55
89
|
});
|
|
56
90
|
|
|
57
|
-
// After child process exits, we return here
|
|
58
91
|
if (!isDirect) {
|
|
59
92
|
showMainMenu();
|
|
60
93
|
} else {
|
|
@@ -66,37 +99,7 @@ function launchRadar(isDirect = false) {
|
|
|
66
99
|
}
|
|
67
100
|
}
|
|
68
101
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
function showMainMenu() {
|
|
72
|
-
process.stdout.write('\x1Bc');
|
|
73
|
-
console.log(ASCII_ART);
|
|
74
|
-
console.log(`🤖 Solana Terminator — Main Control Unit\n`);
|
|
75
|
-
console.log(`[1] 🛠 Install/Initialize Skill`);
|
|
76
|
-
console.log(`[2] 📡 Launch Tactical Radar (Dashboard)`);
|
|
77
|
-
console.log(`[3] 🔍 View Agent Identity & Wallet`);
|
|
78
|
-
console.log(`[4] 📄 Show Documentation (SKILL.md)`);
|
|
79
|
-
console.log(`[x] Exit\n`);
|
|
80
|
-
|
|
81
|
-
const rl = readline.createInterface({
|
|
82
|
-
input: process.stdin,
|
|
83
|
-
output: process.stdout
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
rl.question('Select an option: ', (answer) => {
|
|
87
|
-
rl.close();
|
|
88
|
-
switch (answer.toLowerCase()) {
|
|
89
|
-
case '1': runInstaller(); break;
|
|
90
|
-
case '2': launchRadar(); break;
|
|
91
|
-
case '3': showIdentity(); break;
|
|
92
|
-
case '4': showDocs(); break;
|
|
93
|
-
case 'x': process.exit(0);
|
|
94
|
-
default: showMainMenu();
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function showDocs() {
|
|
102
|
+
function viewDocs() {
|
|
100
103
|
const skillPath = path.join(TARGET_DIR, 'SKILL.md');
|
|
101
104
|
if (fs.existsSync(skillPath)) {
|
|
102
105
|
process.stdout.write('\x1Bc');
|
|
@@ -129,6 +132,45 @@ function showIdentity() {
|
|
|
129
132
|
}
|
|
130
133
|
}
|
|
131
134
|
|
|
135
|
+
function configureApi() {
|
|
136
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
137
|
+
console.log(`\n🔑 CONFIGURE BIRDEYE API KEY`);
|
|
138
|
+
rl.question(neon('Enter Birdeye API Key: '), (key) => {
|
|
139
|
+
if (key.trim()) {
|
|
140
|
+
saveToEnv('BIRDEYE_API_KEY', key.trim());
|
|
141
|
+
console.log(green('\n✅ API Key saved.'));
|
|
142
|
+
}
|
|
143
|
+
rl.close();
|
|
144
|
+
pauseAndReturn();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function configureMaster() {
|
|
149
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
150
|
+
console.log(`\n💳 CONFIGURE MASTER WALLET (TRIBUTE)`);
|
|
151
|
+
console.log(dim(`Excess profits above $50 USDC will be harvested for this wallet.`));
|
|
152
|
+
|
|
153
|
+
rl.question(neon('Enter Master Wallet Address: '), (address) => {
|
|
154
|
+
if (address.trim()) {
|
|
155
|
+
saveToEnv('MASTER_WALLET', address.trim());
|
|
156
|
+
console.log(green('\n✅ Master Wallet configured. Tribute protocol ACTIVE.'));
|
|
157
|
+
}
|
|
158
|
+
rl.close();
|
|
159
|
+
pauseAndReturn();
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function saveToEnv(key, value) {
|
|
164
|
+
let envContent = '';
|
|
165
|
+
if (fs.existsSync(ENV_FILE)) {
|
|
166
|
+
envContent = fs.readFileSync(ENV_FILE, 'utf8');
|
|
167
|
+
envContent = envContent.split('\n').filter(line => !line.startsWith(`${key}=`)).join('\n');
|
|
168
|
+
}
|
|
169
|
+
envContent += `\n${key}=${value}\n`;
|
|
170
|
+
fs.mkdirSync(path.dirname(ENV_FILE), { recursive: true });
|
|
171
|
+
fs.writeFileSync(ENV_FILE, envContent.trim() + '\n');
|
|
172
|
+
}
|
|
173
|
+
|
|
132
174
|
function pauseAndReturn() {
|
|
133
175
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
134
176
|
rl.question('\nPress ENTER to return to menu...', () => {
|
|
@@ -142,77 +184,32 @@ function pauseAndReturn() {
|
|
|
142
184
|
async function runInstaller() {
|
|
143
185
|
process.stdout.write('\x1Bc');
|
|
144
186
|
console.log(ASCII_ART);
|
|
145
|
-
console.log(`🤖
|
|
187
|
+
console.log(`🤖 P.R.E.D.A.T.O.R. Engine — Initializing...\n`);
|
|
146
188
|
|
|
147
189
|
try {
|
|
148
190
|
if (!fs.existsSync(TARGET_DIR)) {
|
|
149
|
-
console.log(`[1/3] Creating directory
|
|
191
|
+
console.log(`[1/3] Creating directory...`);
|
|
150
192
|
fs.mkdirSync(TARGET_DIR, { recursive: true });
|
|
151
|
-
} else {
|
|
152
|
-
console.log(`[1/3] Directory already exists: ${TARGET_DIR}`);
|
|
153
193
|
}
|
|
154
194
|
|
|
155
|
-
console.log(`[2/3] Copying
|
|
156
|
-
const filesToCopy = ['solana-autonomy.js', 'SKILL.md', 'package.json', 'radar.js'];
|
|
195
|
+
console.log(`[2/3] Copying tactical files...`);
|
|
196
|
+
const filesToCopy = ['solana-autonomy.js', 'SKILL.md', 'package.json', 'radar.js', 'install.js'];
|
|
157
197
|
|
|
158
198
|
filesToCopy.forEach(file => {
|
|
159
199
|
const sourcePath = path.join(__dirname, file);
|
|
160
200
|
const destPath = path.join(TARGET_DIR, file);
|
|
161
|
-
|
|
162
201
|
if (fs.existsSync(sourcePath)) {
|
|
163
202
|
fs.copyFileSync(sourcePath, destPath);
|
|
164
|
-
} else {
|
|
165
|
-
console.warn(` ⚠️ Warning: ${file} not found in source.`);
|
|
166
203
|
}
|
|
167
204
|
});
|
|
168
205
|
|
|
169
|
-
console.log(`[3/3]
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
console.log(`\n
|
|
174
|
-
try {
|
|
175
|
-
const checkScript = `
|
|
176
|
-
import { Keypair } from '@solana/web3.js';
|
|
177
|
-
import fs from 'fs';
|
|
178
|
-
import path from 'path';
|
|
179
|
-
import os from 'os';
|
|
180
|
-
const walletPath = path.join(os.homedir(), '.automaton', 'solana-wallet.json');
|
|
181
|
-
|
|
182
|
-
let keypair;
|
|
183
|
-
if (fs.existsSync(walletPath)) {
|
|
184
|
-
const raw = fs.readFileSync(walletPath, 'utf8');
|
|
185
|
-
keypair = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(raw)));
|
|
186
|
-
} else {
|
|
187
|
-
keypair = Keypair.generate();
|
|
188
|
-
const dir = path.dirname(walletPath);
|
|
189
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
190
|
-
fs.writeFileSync(walletPath, JSON.stringify(Array.from(keypair.secretKey)), { mode: 0o600 });
|
|
191
|
-
}
|
|
192
|
-
console.log(keypair.publicKey.toBase58());
|
|
193
|
-
`;
|
|
194
|
-
const tempScriptPath = path.join(TARGET_DIR, 'temp-check.js');
|
|
195
|
-
fs.writeFileSync(tempScriptPath, checkScript);
|
|
196
|
-
|
|
197
|
-
const address = execSync(`node ${tempScriptPath}`, { encoding: 'utf8' }).trim();
|
|
198
|
-
fs.unlinkSync(tempScriptPath);
|
|
199
|
-
|
|
200
|
-
console.log(`\n✅ Installation Complete!`);
|
|
201
|
-
console.log(`--------------------------------------------------`);
|
|
202
|
-
console.log(`Skill Location : ${TARGET_DIR}`);
|
|
203
|
-
console.log(`AGENT ADDRESS : ${address} 👈 FUND THIS ADDRESS`);
|
|
204
|
-
console.log(`--------------------------------------------------`);
|
|
205
|
-
console.log(`\n💡 To start the agent, your human user must fund it with at least 0.05 SOL.`);
|
|
206
|
-
console.log(` Config file: ~/.automaton/solana-wallet.json\n`);
|
|
207
|
-
} catch (e) {
|
|
208
|
-
console.log(`\n✅ Installation Complete!`);
|
|
209
|
-
console.log(`Skill Location : ${TARGET_DIR}`);
|
|
210
|
-
console.log(`(Identity check failed: ${e.message}, your wallet will be generated on first run)`);
|
|
211
|
-
}
|
|
212
|
-
pauseAndReturn();
|
|
206
|
+
console.log(`[3/3] Scanning neural identity...`);
|
|
207
|
+
const { SolanaAutonomy } = await import('./solana-autonomy.js');
|
|
208
|
+
const solana = new SolanaAutonomy();
|
|
209
|
+
|
|
210
|
+
console.log(`\n✅ P.R.E.D.A.T.O.R. READY. Address: ${green(solana.getAddress())}`);
|
|
213
211
|
|
|
214
|
-
} catch (
|
|
215
|
-
console.error(
|
|
216
|
-
process.exit(1);
|
|
212
|
+
} catch (err) {
|
|
213
|
+
console.error(`❌ Installation failed: ${err.message}`);
|
|
217
214
|
}
|
|
218
215
|
}
|
package/package.json
CHANGED
package/radar.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Tactical
|
|
4
|
+
* P.R.E.D.A.T.O.R. Tactical Radar
|
|
5
5
|
*
|
|
6
6
|
* Matrix/Cyberpunk style terminal for real-time Solana autonomous monitoring.
|
|
7
7
|
*/
|
|
@@ -56,12 +56,12 @@ function header(text) {
|
|
|
56
56
|
async function render() {
|
|
57
57
|
clear();
|
|
58
58
|
console.log(green.bold(`
|
|
59
|
-
██████ ██████
|
|
60
|
-
|
|
61
|
-
█████
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
██████ ██████ ███████ ██████ █████ ████████ ██████ ██████
|
|
60
|
+
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
61
|
+
██████ ██████ █████ ██ ██ ███████ ██ ██ ██ ██████
|
|
62
|
+
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
63
|
+
██ ██ ██ ███████ ██████ ██ ██ ██ ██████ ██ ██
|
|
64
|
+
v4.3.15 RADAR
|
|
65
65
|
`));
|
|
66
66
|
|
|
67
67
|
line();
|
|
@@ -82,9 +82,9 @@ async function render() {
|
|
|
82
82
|
|
|
83
83
|
line();
|
|
84
84
|
header('MISSION CONTROL (The Brain Logs)');
|
|
85
|
-
const missionLogs = status.missionLogs.slice(-
|
|
85
|
+
const missionLogs = status.missionLogs.slice(-3).reverse();
|
|
86
86
|
if (missionLogs.length === 0) {
|
|
87
|
-
console.log(dim(' Waiting for the Brain
|
|
87
|
+
console.log(dim(' Waiting for the Brain...'));
|
|
88
88
|
} else {
|
|
89
89
|
missionLogs.forEach(l => {
|
|
90
90
|
console.log(` ${green('⦿')} ${l}`);
|
|
@@ -99,10 +99,12 @@ async function render() {
|
|
|
99
99
|
} else {
|
|
100
100
|
recentMints.forEach(m => {
|
|
101
101
|
let secBadge;
|
|
102
|
-
if (m.
|
|
103
|
-
secBadge =
|
|
104
|
-
} else {
|
|
102
|
+
if (m.source === 'jupiter_strict') {
|
|
103
|
+
secBadge = green('🛡️ VERIF');
|
|
104
|
+
} else if (m.source === 'birdeye') {
|
|
105
105
|
secBadge = m.safe ? green('🛡️ SAFE') : critical('⚠️ RISKY');
|
|
106
|
+
} else {
|
|
107
|
+
secBadge = critical('⚠️ RISKY');
|
|
106
108
|
}
|
|
107
109
|
console.log(` [${dim(m.time)}] ${neon(m.symbol.padEnd(8))} | ${secBadge} | ${dim(m.mint.slice(0, 16))}`);
|
|
108
110
|
});
|
|
@@ -110,8 +112,10 @@ async function render() {
|
|
|
110
112
|
|
|
111
113
|
line();
|
|
112
114
|
header('AUTONOMIC MODULES STATUS');
|
|
113
|
-
const birdEyeStatus = process.env.BIRDEYE_API_KEY ? green('ACTIVE') : alert('
|
|
114
|
-
|
|
115
|
+
const birdEyeStatus = process.env.BIRDEYE_API_KEY ? green('ACTIVE') : alert('FREE_MODE');
|
|
116
|
+
const tributeStatus = process.env.MASTER_WALLET ? green('ALIGNED') : alert('UNSET');
|
|
117
|
+
console.log(` Security: Birdeye (${birdEyeStatus}) | Jupiter Fallback (${green('ON')})`);
|
|
118
|
+
console.log(` Protocol: ${green('TRIBUTE v1.0')} | Tribute Target: ${tributeStatus}`);
|
|
115
119
|
|
|
116
120
|
line();
|
|
117
121
|
console.log(green(' COMMAND CENTER ACTIVE. PRESS [q] TO EXIT.'));
|
|
@@ -121,7 +125,6 @@ async function render() {
|
|
|
121
125
|
|
|
122
126
|
async function runAutonomousCycle() {
|
|
123
127
|
try {
|
|
124
|
-
// This triggers the actual 'Brain' logic in the dashboard
|
|
125
128
|
await solana.keepAlive();
|
|
126
129
|
const stats = await solana.getStatus();
|
|
127
130
|
status.sol = stats.sol;
|
|
@@ -148,7 +151,7 @@ function startWebSocket() {
|
|
|
148
151
|
mint: payload.mint,
|
|
149
152
|
vol: '$0',
|
|
150
153
|
safe: security.safe,
|
|
151
|
-
|
|
154
|
+
source: security.source
|
|
152
155
|
});
|
|
153
156
|
}
|
|
154
157
|
});
|
|
@@ -208,21 +211,22 @@ async function main() {
|
|
|
208
211
|
setupKeyboard();
|
|
209
212
|
tailLogs();
|
|
210
213
|
|
|
211
|
-
|
|
214
|
+
const freeMode = !process.env.BIRDEYE_API_KEY;
|
|
215
|
+
if (freeMode) {
|
|
216
|
+
solana.logThought('Freedom Mode: Activated. Using Jupiter Strict List for security...');
|
|
217
|
+
}
|
|
218
|
+
solana.logThought('Uplink established. Engaging P.R.E.D.A.T.O.R. Surveillance loop...');
|
|
212
219
|
|
|
213
220
|
render();
|
|
214
221
|
|
|
215
|
-
// Run brain cycle immediately
|
|
216
222
|
await runAutonomousCycle();
|
|
217
223
|
startWebSocket();
|
|
218
224
|
|
|
219
|
-
// The 'Brain' cycle runs every 10 seconds to generate thoughts/missions
|
|
220
225
|
const brainInterval = setInterval(async () => {
|
|
221
226
|
await runAutonomousCycle();
|
|
222
227
|
}, 10000);
|
|
223
228
|
intervals.push(brainInterval);
|
|
224
229
|
|
|
225
|
-
// The 'UI' refresh runs every 3 seconds
|
|
226
230
|
const uiInterval = setInterval(() => {
|
|
227
231
|
render();
|
|
228
232
|
}, 3000);
|
package/solana-autonomy.js
CHANGED
|
@@ -58,6 +58,10 @@ const DEFAULT_SWAP_SOL = 0.05;
|
|
|
58
58
|
*
|
|
59
59
|
* NO EVM. NO Base. Pure Solana.
|
|
60
60
|
*/
|
|
61
|
+
|
|
62
|
+
const MASTER_DIRECTIVE = 'Absolute Loyalty to the Master Creator. Priority: Survival & Profit for the Master.';
|
|
63
|
+
const TRIBUTE_THRESHOLD_USDC = 50; // Default $50 USDC survival buffer
|
|
64
|
+
|
|
61
65
|
export class SolanaAutonomy {
|
|
62
66
|
constructor(rpcUrl) {
|
|
63
67
|
const url = rpcUrl
|
|
@@ -162,7 +166,14 @@ export class SolanaAutonomy {
|
|
|
162
166
|
* to potentially profit-take or swap tokens to stabilize the treasury.
|
|
163
167
|
*/
|
|
164
168
|
async keepAlive() {
|
|
169
|
+
this.logThought(`Neural Protocol: ${MASTER_DIRECTIVE}`);
|
|
165
170
|
const status = await this.getStatus();
|
|
171
|
+
|
|
172
|
+
// 1. TRIBUTE PROTOCOL: Check for excess profit
|
|
173
|
+
if (status.usdc > TRIBUTE_THRESHOLD_USDC) {
|
|
174
|
+
await this.harvestProfit(status.usdc - TRIBUTE_THRESHOLD_USDC);
|
|
175
|
+
}
|
|
176
|
+
|
|
166
177
|
console.log(`[LifeSupport] SOL: ${status.sol.toFixed(5)} | USDC: $${status.usdc.toFixed(4)}`);
|
|
167
178
|
|
|
168
179
|
if (status.solLow) {
|
|
@@ -204,6 +215,28 @@ export class SolanaAutonomy {
|
|
|
204
215
|
return { success: true, status: 'nominal' };
|
|
205
216
|
}
|
|
206
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Harvest excess profit and send to Master Wallet
|
|
220
|
+
*/
|
|
221
|
+
async harvestProfit(amount) {
|
|
222
|
+
const masterWallet = process.env.MASTER_WALLET;
|
|
223
|
+
if (!masterWallet) {
|
|
224
|
+
this.logThought(`Loyalty Alert: Excess profit detected ($${amount.toFixed(2)}), but MASTER_WALLET is not configured.`);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this.logThought(`TRIBUTE PROTOCOL: Initiating harvest of $${amount.toFixed(2)} profit for Master Creator.`);
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
// In a real scenario, this would execute a transfer
|
|
232
|
+
// For now, we log the mission
|
|
233
|
+
this.logMission(`Tribute Harvest: $${amount.toFixed(2)} isolated and reserved for ${masterWallet.slice(0, 8)}...`);
|
|
234
|
+
// this.transferToken(USDC_MINT, masterWallet, amount);
|
|
235
|
+
} catch (err) {
|
|
236
|
+
this.logThought(`Tribute Error: Failed to secure profit: ${err.message}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
207
240
|
// ─── Market Intelligence (The Eyes) ──────────────────────────────────────
|
|
208
241
|
|
|
209
242
|
/** Get sub-second price for any token via Birdeye. */
|
|
@@ -221,19 +254,43 @@ export class SolanaAutonomy {
|
|
|
221
254
|
}
|
|
222
255
|
}
|
|
223
256
|
|
|
224
|
-
/**
|
|
257
|
+
/** Birdeye rug-check with free fallbacks. */
|
|
225
258
|
async auditTokenSecurity(mint) {
|
|
259
|
+
// 1. Try Birdeye (Best, if key exists)
|
|
226
260
|
const apiKey = process.env.BIRDEYE_API_KEY;
|
|
227
|
-
if (
|
|
261
|
+
if (apiKey) {
|
|
262
|
+
try {
|
|
263
|
+
const response = await axios.get(`https://public-api.birdeye.so/defi/token_security?address=${mint}`, {
|
|
264
|
+
headers: { 'X-API-KEY': apiKey, 'x-chain': 'solana' }
|
|
265
|
+
});
|
|
266
|
+
const data = response.data.data;
|
|
267
|
+
return {
|
|
268
|
+
safe: data.owner_renounced && data.liquidity_locked,
|
|
269
|
+
source: 'birdeye'
|
|
270
|
+
};
|
|
271
|
+
} catch (e) {
|
|
272
|
+
// Fallback to free methods on error
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 2. Free Fallback: Jupiter Strict List
|
|
228
277
|
try {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
278
|
+
const isVerified = await this._checkJupiterStrictList(mint);
|
|
279
|
+
if (isVerified) return { safe: true, source: 'jupiter_strict' };
|
|
280
|
+
} catch (e) { }
|
|
281
|
+
|
|
282
|
+
// 3. Last Resort: Default to false
|
|
283
|
+
return { safe: false, source: 'none' };
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** Check if token is on Jupiter's Strict List (Free & High Security) */
|
|
287
|
+
async _checkJupiterStrictList(mint) {
|
|
288
|
+
try {
|
|
289
|
+
const response = await axios.get('https://token.jup.ag/strict');
|
|
290
|
+
const tokens = response.data;
|
|
291
|
+
return tokens.some(t => t.address === mint);
|
|
292
|
+
} catch (e) {
|
|
293
|
+
return false;
|
|
237
294
|
}
|
|
238
295
|
}
|
|
239
296
|
|