nyxora 1.0.8 → 1.1.2
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/IDENTITY.md +5 -6
- package/README.md +8 -2
- package/SECURITY.md +5 -4
- package/dashboard/dist/assets/index-CKUbyknW.js +9 -0
- package/dashboard/dist/index.html +1 -1
- package/dist/agent/reasoning.js +9 -44
- package/dist/agent/transactionManager.js +38 -0
- package/dist/gateway/cli.js +34 -52
- package/dist/gateway/server.js +60 -41
- package/dist/gateway/setup.js +52 -42
- package/dist/gateway/telegram.js +68 -3
- package/dist/gateway/test.js +0 -35
- package/dist/utils/crypto.js +35 -0
- package/dist/utils/formatter.js +30 -0
- package/dist/utils/state.js +30 -0
- package/dist/web3/config.js +3 -41
- package/dist/web3/skills/swapToken.js +6 -0
- package/dist/web3/skills/transfer.js +7 -2
- package/package.json +2 -4
- package/user.md +6 -7
- package/config.yaml +0 -14
- package/dashboard/dist/assets/index-BJ1Hl0fx.js +0 -9
package/dist/agent/reasoning.js
CHANGED
|
@@ -1,45 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
6
|
exports.logger = void 0;
|
|
40
7
|
exports.processUserInput = processUserInput;
|
|
41
|
-
const dotenv = __importStar(require("dotenv"));
|
|
42
|
-
dotenv.config();
|
|
43
8
|
const fs_1 = __importDefault(require("fs"));
|
|
44
9
|
const openai_1 = require("openai");
|
|
45
10
|
const parser_1 = require("../config/parser");
|
|
@@ -72,21 +37,21 @@ function getOpenAI() {
|
|
|
72
37
|
currentKeyIndex++; // Increment for next request
|
|
73
38
|
}
|
|
74
39
|
}
|
|
75
|
-
// Fallbacks if no valid keys found in config
|
|
40
|
+
// Fallbacks if no valid keys found in config.llm.api_keys
|
|
76
41
|
if (!apiKey) {
|
|
77
42
|
if (config.llm.provider === 'gemini') {
|
|
78
|
-
apiKey =
|
|
43
|
+
apiKey = config.llm.credentials?.gemini_key || '';
|
|
79
44
|
}
|
|
80
45
|
else if (config.llm.provider === 'openrouter') {
|
|
81
|
-
apiKey =
|
|
46
|
+
apiKey = config.llm.credentials?.openrouter_key || '';
|
|
82
47
|
}
|
|
83
48
|
else {
|
|
84
|
-
apiKey =
|
|
49
|
+
apiKey = config.llm.credentials?.openai_key || '';
|
|
85
50
|
}
|
|
86
51
|
if (!apiKey) {
|
|
87
|
-
throw new Error(`No API Key found for ${config.llm.provider} in config
|
|
52
|
+
throw new Error(`No API Key found for ${config.llm.provider} in config.yaml. Please run 'nyxora setup' to configure it.`);
|
|
88
53
|
}
|
|
89
|
-
console.log(`[LLM] Using default API Key from .
|
|
54
|
+
console.log(`[LLM] Using default API Key from config.yaml`);
|
|
90
55
|
}
|
|
91
56
|
if (config.llm.provider === 'gemini') {
|
|
92
57
|
return new openai_1.OpenAI({
|
|
@@ -138,10 +103,10 @@ If the user doesn't specify a chain, default to: ${config.agent.default_chain}.`
|
|
|
138
103
|
}
|
|
139
104
|
return basePrompt;
|
|
140
105
|
}
|
|
141
|
-
async function processUserInput(input) {
|
|
106
|
+
async function processUserInput(input, role = 'user') {
|
|
142
107
|
const config = (0, parser_1.loadConfig)();
|
|
143
|
-
// Add
|
|
144
|
-
exports.logger.addEntry({ role
|
|
108
|
+
// Add input to memory
|
|
109
|
+
exports.logger.addEntry({ role, content: input });
|
|
145
110
|
const history = exports.logger.getHistory();
|
|
146
111
|
// Format messages for OpenAI
|
|
147
112
|
const messages = [
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.txManager = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
class TransactionManager {
|
|
9
|
+
transactions = new Map();
|
|
10
|
+
createPendingTransaction(type, chainName, details) {
|
|
11
|
+
const id = crypto_1.default.randomUUID();
|
|
12
|
+
const tx = {
|
|
13
|
+
id,
|
|
14
|
+
type,
|
|
15
|
+
chainName,
|
|
16
|
+
details,
|
|
17
|
+
status: 'pending',
|
|
18
|
+
createdAt: Date.now(),
|
|
19
|
+
};
|
|
20
|
+
this.transactions.set(id, tx);
|
|
21
|
+
return tx;
|
|
22
|
+
}
|
|
23
|
+
getPending() {
|
|
24
|
+
return Array.from(this.transactions.values()).filter(t => t.status === 'pending');
|
|
25
|
+
}
|
|
26
|
+
getTransaction(id) {
|
|
27
|
+
return this.transactions.get(id);
|
|
28
|
+
}
|
|
29
|
+
updateStatus(id, status, result) {
|
|
30
|
+
const tx = this.transactions.get(id);
|
|
31
|
+
if (tx) {
|
|
32
|
+
tx.status = status;
|
|
33
|
+
if (result)
|
|
34
|
+
tx.result = result;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.txManager = new TransactionManager();
|
package/dist/gateway/cli.js
CHANGED
|
@@ -1,49 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
-
if (k2 === undefined) k2 = k;
|
|
5
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
-
}
|
|
9
|
-
Object.defineProperty(o, k2, desc);
|
|
10
|
-
}) : (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
o[k2] = m[k];
|
|
13
|
-
}));
|
|
14
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
-
}) : function(o, v) {
|
|
17
|
-
o["default"] = v;
|
|
18
|
-
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
-
var ownKeys = function(o) {
|
|
21
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
-
var ar = [];
|
|
23
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
-
return ar;
|
|
25
|
-
};
|
|
26
|
-
return ownKeys(o);
|
|
27
|
-
};
|
|
28
|
-
return function (mod) {
|
|
29
|
-
if (mod && mod.__esModule) return mod;
|
|
30
|
-
var result = {};
|
|
31
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
-
__setModuleDefault(result, mod);
|
|
33
|
-
return result;
|
|
34
|
-
};
|
|
35
|
-
})();
|
|
36
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
5
|
};
|
|
39
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
7
|
const fs_1 = __importDefault(require("fs"));
|
|
41
8
|
const path_1 = __importDefault(require("path"));
|
|
42
|
-
const dotenv = __importStar(require("dotenv"));
|
|
43
9
|
const open_1 = __importDefault(require("open"));
|
|
44
10
|
const paths_1 = require("../config/paths");
|
|
45
11
|
const server_1 = require("./server");
|
|
46
12
|
const setup_1 = require("./setup");
|
|
13
|
+
const prompts_1 = require("@clack/prompts");
|
|
14
|
+
const crypto_1 = require("../utils/crypto");
|
|
15
|
+
const state_1 = require("../utils/state");
|
|
16
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
47
17
|
async function main() {
|
|
48
18
|
// 1. Determine configuration directory
|
|
49
19
|
const appDir = (0, paths_1.getAppDir)();
|
|
@@ -60,23 +30,12 @@ async function main() {
|
|
|
60
30
|
// 2. Setup boilerplate files if in global mode and they don't exist
|
|
61
31
|
let isFirstBoot = false;
|
|
62
32
|
if (isGlobalMode) {
|
|
63
|
-
const globalEnvPath = path_1.default.join(appDir, '.env');
|
|
64
33
|
const globalConfigPath = path_1.default.join(appDir, 'config.yaml');
|
|
65
34
|
const globalUserMdPath = path_1.default.join(appDir, 'user.md');
|
|
66
35
|
const globalIdentityMdPath = path_1.default.join(appDir, 'IDENTITY.md');
|
|
67
|
-
// Copy .env.example to ~/.nyxora/.env if it doesn't exist
|
|
68
|
-
if (!fs_1.default.existsSync(globalEnvPath)) {
|
|
69
|
-
isFirstBoot = true;
|
|
70
|
-
const exampleEnvPath = path_1.default.resolve(__dirname, '../../../.env.example');
|
|
71
|
-
if (fs_1.default.existsSync(exampleEnvPath)) {
|
|
72
|
-
fs_1.default.copyFileSync(exampleEnvPath, globalEnvPath);
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
fs_1.default.writeFileSync(globalEnvPath, '# Nyxora Environment Variables\nPRIVATE_KEY=\n');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
36
|
// Copy default config.yaml
|
|
79
37
|
if (!fs_1.default.existsSync(globalConfigPath)) {
|
|
38
|
+
isFirstBoot = true;
|
|
80
39
|
const exampleConfigPath = path_1.default.resolve(__dirname, '../../../config.yaml');
|
|
81
40
|
if (fs_1.default.existsSync(exampleConfigPath)) {
|
|
82
41
|
fs_1.default.copyFileSync(exampleConfigPath, globalConfigPath);
|
|
@@ -86,24 +45,47 @@ async function main() {
|
|
|
86
45
|
}
|
|
87
46
|
}
|
|
88
47
|
if (!fs_1.default.existsSync(globalUserMdPath)) {
|
|
89
|
-
fs_1.default.writeFileSync(globalUserMdPath, '
|
|
48
|
+
fs_1.default.writeFileSync(globalUserMdPath, 'Write custom instructions, special rules, user profiles, or the persona you want for Nyxora AI in this file.\n');
|
|
90
49
|
}
|
|
91
50
|
if (!fs_1.default.existsSync(globalIdentityMdPath)) {
|
|
92
|
-
fs_1.default.writeFileSync(globalIdentityMdPath, '
|
|
51
|
+
fs_1.default.writeFileSync(globalIdentityMdPath, 'You are a Web3 AI assistant named Nyxora.\n');
|
|
93
52
|
}
|
|
94
53
|
}
|
|
95
54
|
if (isFirstBoot) {
|
|
96
|
-
console.log('[Setup]
|
|
55
|
+
console.log('[Setup] New installation detected. Starting Setup Wizard...');
|
|
97
56
|
await (0, setup_1.runSetupWizard)();
|
|
98
57
|
}
|
|
99
|
-
// 3. Load
|
|
100
|
-
|
|
58
|
+
// 3. Load Private Key into Memory
|
|
59
|
+
const keystorePath = path_1.default.join(appDir, 'keystore.json');
|
|
60
|
+
if (fs_1.default.existsSync(keystorePath)) {
|
|
61
|
+
const masterPassword = await (0, prompts_1.password)({
|
|
62
|
+
message: '🔒 Vault locked! Enter Master Password to access Nyxora:',
|
|
63
|
+
});
|
|
64
|
+
if ((0, prompts_1.isCancel)(masterPassword) || !masterPassword) {
|
|
65
|
+
console.log(picocolors_1.default.red('Access denied. Exiting Nyxora.'));
|
|
66
|
+
return process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const keystore = JSON.parse(fs_1.default.readFileSync(keystorePath, 'utf8'));
|
|
70
|
+
const privateKey = (0, crypto_1.decryptKey)(keystore, masterPassword);
|
|
71
|
+
(0, state_1.setPrivateKey)(privateKey);
|
|
72
|
+
console.log(picocolors_1.default.green('✅ Private Key successfully decrypted into memory.'));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.log(picocolors_1.default.red('❌ Invalid Master Password or corrupted keystore. Exiting Nyxora.'));
|
|
76
|
+
return process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.log(picocolors_1.default.yellow('⚠️ Keystore not found. Web3 features will be disabled unless you run `nyxora setup`.'));
|
|
81
|
+
}
|
|
101
82
|
// 4. Start the Express API Server (which also serves the static dashboard and Telegram bot)
|
|
102
83
|
(0, server_1.startServer)();
|
|
103
84
|
// 5. Open the Dashboard in the default browser
|
|
104
85
|
const PORT = process.env.PORT || 3000;
|
|
86
|
+
const token = (0, state_1.getSessionToken)();
|
|
105
87
|
setTimeout(() => {
|
|
106
|
-
const url = `http://localhost:${PORT}`;
|
|
88
|
+
const url = `http://localhost:${PORT}?token=${token}`;
|
|
107
89
|
console.log(`🌐 Opening Dashboard at ${url}`);
|
|
108
90
|
(0, open_1.default)(url);
|
|
109
91
|
}, 1500);
|
package/dist/gateway/server.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -40,17 +7,19 @@ exports.startServer = startServer;
|
|
|
40
7
|
const express_1 = __importDefault(require("express"));
|
|
41
8
|
const cors_1 = __importDefault(require("cors"));
|
|
42
9
|
const path_1 = __importDefault(require("path"));
|
|
43
|
-
const
|
|
44
|
-
const paths_1 = require("../config/paths");
|
|
45
|
-
dotenv.config({ path: (0, paths_1.getPath)('.env') });
|
|
10
|
+
const state_1 = require("../utils/state");
|
|
46
11
|
const reasoning_1 = require("../agent/reasoning");
|
|
47
12
|
const parser_1 = require("../config/parser");
|
|
48
13
|
const tracker_1 = require("./tracker");
|
|
49
|
-
const
|
|
14
|
+
const transactionManager_1 = require("../agent/transactionManager");
|
|
50
15
|
const transfer_1 = require("../web3/skills/transfer");
|
|
51
|
-
const getPrice_1 = require("../web3/skills/getPrice");
|
|
52
16
|
const swapToken_1 = require("../web3/skills/swapToken");
|
|
17
|
+
const getBalance_1 = require("../web3/skills/getBalance");
|
|
18
|
+
const transfer_2 = require("../web3/skills/transfer");
|
|
19
|
+
const getPrice_1 = require("../web3/skills/getPrice");
|
|
20
|
+
const swapToken_2 = require("../web3/skills/swapToken");
|
|
53
21
|
const telegram_1 = require("./telegram");
|
|
22
|
+
const formatter_1 = require("../utils/formatter");
|
|
54
23
|
// Intercept console.log and console.error
|
|
55
24
|
const originalLog = console.log;
|
|
56
25
|
const originalError = console.error;
|
|
@@ -63,8 +32,16 @@ console.error = function (...args) {
|
|
|
63
32
|
originalError.apply(console, args);
|
|
64
33
|
};
|
|
65
34
|
const app = (0, express_1.default)();
|
|
66
|
-
app.use((0, cors_1.default)());
|
|
35
|
+
app.use((0, cors_1.default)({ origin: ['http://localhost:3000', 'http://localhost:5173'] }));
|
|
67
36
|
app.use(express_1.default.json());
|
|
37
|
+
// API Auth Middleware
|
|
38
|
+
app.use('/api', (req, res, next) => {
|
|
39
|
+
const token = req.headers['x-nyxora-token'];
|
|
40
|
+
if (token !== (0, state_1.getSessionToken)()) {
|
|
41
|
+
return res.status(401).json({ error: 'Unauthorized: Invalid or missing token' });
|
|
42
|
+
}
|
|
43
|
+
next();
|
|
44
|
+
});
|
|
68
45
|
// Serve static frontend from dashboard/dist
|
|
69
46
|
app.use(express_1.default.static(path_1.default.join(__dirname, '../../dashboard/dist')));
|
|
70
47
|
app.get('/api/history', (req, res) => {
|
|
@@ -117,11 +94,53 @@ app.get('/api/logs', (req, res) => {
|
|
|
117
94
|
app.get('/api/skills', (req, res) => {
|
|
118
95
|
res.json([
|
|
119
96
|
getBalance_1.getBalanceToolDefinition,
|
|
120
|
-
|
|
97
|
+
transfer_2.transferToolDefinition,
|
|
121
98
|
getPrice_1.getPriceToolDefinition,
|
|
122
|
-
|
|
99
|
+
swapToken_2.swapTokenToolDefinition
|
|
123
100
|
]);
|
|
124
101
|
});
|
|
102
|
+
app.get('/api/transactions', (req, res) => {
|
|
103
|
+
res.json(transactionManager_1.txManager.getPending());
|
|
104
|
+
});
|
|
105
|
+
app.post('/api/transactions/:id/approve', async (req, res) => {
|
|
106
|
+
const id = req.params.id;
|
|
107
|
+
const tx = transactionManager_1.txManager.getTransaction(id);
|
|
108
|
+
if (!tx || tx.status !== 'pending')
|
|
109
|
+
return res.status(404).json({ error: 'Transaction not found or not pending' });
|
|
110
|
+
try {
|
|
111
|
+
let result = '';
|
|
112
|
+
if (tx.type === 'transfer') {
|
|
113
|
+
result = await (0, transfer_1.executeTransfer)(tx.chainName, tx.details.toAddress, tx.details.amountEth);
|
|
114
|
+
}
|
|
115
|
+
else if (tx.type === 'swap') {
|
|
116
|
+
result = await (0, swapToken_1.executeSwap)(tx.chainName, tx.details.fromToken, tx.details.toToken, tx.details.amount);
|
|
117
|
+
}
|
|
118
|
+
transactionManager_1.txManager.updateStatus(id, 'executed', result);
|
|
119
|
+
// Add programmatic beautiful message directly to chat
|
|
120
|
+
const prettyMsg = (0, formatter_1.formatTransactionSuccess)(tx, result);
|
|
121
|
+
reasoning_1.logger.addEntry({ role: 'assistant', content: `✅ Transaction processed:\n\n${prettyMsg}` });
|
|
122
|
+
// Background update to LLM
|
|
123
|
+
(0, reasoning_1.processUserInput)(`Transaction ${id} was APPROVED and EXECUTED by the user via Dashboard. Result: ${result}`, 'system').catch(() => { });
|
|
124
|
+
res.json({ success: true, result });
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
transactionManager_1.txManager.updateStatus(id, 'failed', err.message);
|
|
128
|
+
// Add programmatic beautiful error message directly to chat
|
|
129
|
+
const prettyError = (0, formatter_1.formatTransactionError)(tx, err.message);
|
|
130
|
+
reasoning_1.logger.addEntry({ role: 'assistant', content: prettyError });
|
|
131
|
+
(0, reasoning_1.processUserInput)(`Transaction ${id} was APPROVED but FAILED to execute. Error: ${err.message}`, 'system').catch(() => { });
|
|
132
|
+
res.status(500).json({ error: err.message });
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
app.post('/api/transactions/:id/reject', (req, res) => {
|
|
136
|
+
const id = req.params.id;
|
|
137
|
+
const tx = transactionManager_1.txManager.getTransaction(id);
|
|
138
|
+
if (!tx || tx.status !== 'pending')
|
|
139
|
+
return res.status(404).json({ error: 'Transaction not found or not pending' });
|
|
140
|
+
transactionManager_1.txManager.updateStatus(id, 'rejected');
|
|
141
|
+
(0, reasoning_1.processUserInput)(`Transaction ${id} was REJECTED by the user via Dashboard. Acknowledge this briefly.`, 'system').catch(() => { });
|
|
142
|
+
res.json({ success: true });
|
|
143
|
+
});
|
|
125
144
|
app.post('/api/chat', async (req, res) => {
|
|
126
145
|
try {
|
|
127
146
|
const { message } = req.body;
|
package/dist/gateway/setup.js
CHANGED
|
@@ -10,6 +10,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const paths_1 = require("../config/paths");
|
|
12
12
|
const parser_1 = require("../config/parser");
|
|
13
|
+
const crypto_1 = require("../utils/crypto");
|
|
13
14
|
async function runSetupWizard() {
|
|
14
15
|
console.clear();
|
|
15
16
|
const logo = `
|
|
@@ -21,62 +22,62 @@ async function runSetupWizard() {
|
|
|
21
22
|
╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
|
|
22
23
|
`;
|
|
23
24
|
console.log(picocolors_1.default.cyan(logo));
|
|
24
|
-
(0, prompts_1.intro)(picocolors_1.default.inverse('
|
|
25
|
+
(0, prompts_1.intro)(picocolors_1.default.inverse(' Nyxora CLI Setup '));
|
|
25
26
|
const appDir = (0, paths_1.getAppDir)();
|
|
26
27
|
const config = (0, parser_1.loadConfig)();
|
|
27
|
-
const disclaimer = `Nyxora
|
|
28
|
+
const disclaimer = `Nyxora is a Web3 Assistant that operates with full access under your control.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
- Private Key
|
|
31
|
-
-
|
|
32
|
-
-
|
|
30
|
+
Critical Precautions:
|
|
31
|
+
- Your Private Key is the lifeblood of your assets. NEVER copy or share the keystore.json file.
|
|
32
|
+
- Any instructions you provide via Telegram or Dashboard can trigger on-chain transactions.
|
|
33
|
+
- It is recommended to use a smart AI model for maximum accuracy.
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
(0, prompts_1.note)(disclaimer, '
|
|
35
|
+
By using Nyxora, you retain full control over your own keys.`;
|
|
36
|
+
(0, prompts_1.note)(disclaimer, 'Security Warning');
|
|
36
37
|
const understand = await (0, prompts_1.confirm)({
|
|
37
|
-
message: '
|
|
38
|
+
message: 'I understand that Private Key security is my responsibility. Continue?',
|
|
38
39
|
initialValue: true,
|
|
39
40
|
});
|
|
40
41
|
if ((0, prompts_1.isCancel)(understand) || !understand) {
|
|
41
|
-
(0, prompts_1.cancel)('
|
|
42
|
+
(0, prompts_1.cancel)('Setup cancelled.');
|
|
42
43
|
return process.exit(0);
|
|
43
44
|
}
|
|
44
45
|
const existingConfigNote = `Workspace: ${appDir}
|
|
45
|
-
Model
|
|
46
|
+
Current Model: ${config.llm.model}
|
|
46
47
|
Provider: ${config.llm.provider}`;
|
|
47
|
-
(0, prompts_1.note)(existingConfigNote, '
|
|
48
|
+
(0, prompts_1.note)(existingConfigNote, 'Configuration Detected');
|
|
48
49
|
const action = await (0, prompts_1.select)({
|
|
49
|
-
message: '
|
|
50
|
+
message: 'What would you like to do?',
|
|
50
51
|
options: [
|
|
51
|
-
{ value: 'keep', label: '
|
|
52
|
-
{ value: 'update', label: '
|
|
52
|
+
{ value: 'keep', label: 'Keep current values' },
|
|
53
|
+
{ value: 'update', label: 'Review and update settings' },
|
|
53
54
|
],
|
|
54
55
|
});
|
|
55
56
|
if ((0, prompts_1.isCancel)(action)) {
|
|
56
|
-
(0, prompts_1.cancel)('
|
|
57
|
+
(0, prompts_1.cancel)('Setup cancelled.');
|
|
57
58
|
return process.exit(0);
|
|
58
59
|
}
|
|
59
60
|
if (action === 'keep') {
|
|
60
|
-
(0, prompts_1.outro)(picocolors_1.default.green('
|
|
61
|
+
(0, prompts_1.outro)(picocolors_1.default.green('Done! Configuration unchanged. Starting Nyxora...'));
|
|
61
62
|
return;
|
|
62
63
|
}
|
|
63
64
|
// --- WIZARD FORM ---
|
|
64
65
|
// 1. LLM Provider
|
|
65
66
|
const provider = await (0, prompts_1.select)({
|
|
66
|
-
message: '
|
|
67
|
+
message: 'Select AI Engine (Provider):',
|
|
67
68
|
initialValue: config.llm.provider,
|
|
68
69
|
options: [
|
|
69
|
-
{ value: 'openai', label: 'OpenAI (
|
|
70
|
+
{ value: 'openai', label: 'OpenAI (Recommended)' },
|
|
70
71
|
{ value: 'gemini', label: 'Google Gemini' },
|
|
71
|
-
{ value: 'openrouter', label: 'OpenRouter (
|
|
72
|
-
{ value: 'ollama', label: 'Ollama (
|
|
72
|
+
{ value: 'openrouter', label: 'OpenRouter (Many Models)' },
|
|
73
|
+
{ value: 'ollama', label: 'Ollama (Local)' },
|
|
73
74
|
],
|
|
74
75
|
});
|
|
75
76
|
if ((0, prompts_1.isCancel)(provider))
|
|
76
77
|
return process.exit(0);
|
|
77
78
|
// 2. Model Name
|
|
78
79
|
const model = await (0, prompts_1.text)({
|
|
79
|
-
message: '
|
|
80
|
+
message: 'Enter AI model name (e.g. gpt-4o, gemini-2.5-flash):',
|
|
80
81
|
initialValue: config.llm.model,
|
|
81
82
|
});
|
|
82
83
|
if ((0, prompts_1.isCancel)(model))
|
|
@@ -85,14 +86,14 @@ Provider: ${config.llm.provider}`;
|
|
|
85
86
|
let apiKey = '';
|
|
86
87
|
if (provider !== 'ollama') {
|
|
87
88
|
apiKey = (await (0, prompts_1.password)({
|
|
88
|
-
message: `
|
|
89
|
+
message: `Enter API Key for ${provider} (Leave empty if already set):`,
|
|
89
90
|
}));
|
|
90
91
|
if ((0, prompts_1.isCancel)(apiKey))
|
|
91
92
|
return process.exit(0);
|
|
92
93
|
}
|
|
93
94
|
// 4. Default Chain
|
|
94
95
|
const defaultChain = await (0, prompts_1.select)({
|
|
95
|
-
message: '
|
|
96
|
+
message: 'Select Default Chain:',
|
|
96
97
|
initialValue: config.agent.default_chain,
|
|
97
98
|
options: [
|
|
98
99
|
{ value: 'sepolia', label: 'Sepolia (Testnet)' },
|
|
@@ -107,7 +108,7 @@ Provider: ${config.llm.provider}`;
|
|
|
107
108
|
return process.exit(0);
|
|
108
109
|
// 5. Telegram Bot
|
|
109
110
|
const setupTelegram = await (0, prompts_1.confirm)({
|
|
110
|
-
message: '
|
|
111
|
+
message: 'Do you want to setup the Telegram Bot?',
|
|
111
112
|
initialValue: config.integrations?.telegram?.enabled || false,
|
|
112
113
|
});
|
|
113
114
|
if ((0, prompts_1.isCancel)(setupTelegram))
|
|
@@ -115,17 +116,25 @@ Provider: ${config.llm.provider}`;
|
|
|
115
116
|
let telegramToken = '';
|
|
116
117
|
if (setupTelegram) {
|
|
117
118
|
telegramToken = (await (0, prompts_1.password)({
|
|
118
|
-
message: '
|
|
119
|
+
message: 'Enter Telegram Bot Token from @BotFather (Leave empty if already set):',
|
|
119
120
|
}));
|
|
120
121
|
if ((0, prompts_1.isCancel)(telegramToken))
|
|
121
122
|
return process.exit(0);
|
|
122
123
|
}
|
|
123
|
-
// 6. Wallet Private Key (.
|
|
124
|
+
// 6. Wallet Private Key (keystore.json)
|
|
124
125
|
const privateKey = await (0, prompts_1.password)({
|
|
125
|
-
message: '
|
|
126
|
+
message: 'Enter Wallet Private Key (0x...)\n (Will be AES-256-GCM encrypted. Leave empty to keep current):',
|
|
126
127
|
});
|
|
127
128
|
if ((0, prompts_1.isCancel)(privateKey))
|
|
128
129
|
return process.exit(0);
|
|
130
|
+
let masterPassword = '';
|
|
131
|
+
if (privateKey) {
|
|
132
|
+
masterPassword = (await (0, prompts_1.password)({
|
|
133
|
+
message: 'Enter MASTER PASSWORD to encrypt your key vault:',
|
|
134
|
+
}));
|
|
135
|
+
if ((0, prompts_1.isCancel)(masterPassword) || !masterPassword)
|
|
136
|
+
return process.exit(0);
|
|
137
|
+
}
|
|
129
138
|
// --- SAVING ---
|
|
130
139
|
// Update Config.yaml
|
|
131
140
|
config.llm.provider = provider;
|
|
@@ -150,21 +159,22 @@ Provider: ${config.llm.provider}`;
|
|
|
150
159
|
config.integrations.telegram.bot_token = telegramToken;
|
|
151
160
|
}
|
|
152
161
|
(0, parser_1.saveConfig)(config);
|
|
153
|
-
// Update .
|
|
154
|
-
if (privateKey) {
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
// Update keystore.json exclusively for Private Key
|
|
163
|
+
if (privateKey && masterPassword) {
|
|
164
|
+
const keystorePath = path_1.default.join(appDir, 'keystore.json');
|
|
165
|
+
try {
|
|
166
|
+
const encryptedData = (0, crypto_1.encryptKey)(privateKey, masterPassword);
|
|
167
|
+
fs_1.default.writeFileSync(keystorePath, JSON.stringify(encryptedData, null, 2), 'utf8');
|
|
168
|
+
// Cleanup old .env if it existed
|
|
169
|
+
const envPath = path_1.default.join(appDir, '.env');
|
|
170
|
+
if (fs_1.default.existsSync(envPath)) {
|
|
171
|
+
fs_1.default.unlinkSync(envPath);
|
|
172
|
+
console.log(picocolors_1.default.yellow('Legacy .env file has been deleted for security.'));
|
|
173
|
+
}
|
|
163
174
|
}
|
|
164
|
-
|
|
165
|
-
|
|
175
|
+
catch (error) {
|
|
176
|
+
console.error('Failed to save keystore.json:', error);
|
|
166
177
|
}
|
|
167
|
-
fs_1.default.writeFileSync(envPath, envContent);
|
|
168
178
|
}
|
|
169
|
-
(0, prompts_1.outro)(picocolors_1.default.green('✨ Setup
|
|
179
|
+
(0, prompts_1.outro)(picocolors_1.default.green('✨ Setup Successful! All configurations have been securely saved.'));
|
|
170
180
|
}
|