nyxora 26.6.29 → 26.6.30
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/CHANGELOG.md +17 -0
- package/README.md +51 -1
- package/dist/packages/core/src/agent/llmProvider.js +2 -2
- package/dist/packages/core/src/agent/osAgent.js +3 -3
- package/dist/packages/core/src/agent/reasoning.js +6 -10
- package/dist/packages/core/src/agent/web3Agent.js +3 -3
- package/dist/packages/core/src/config/defiConfigManager.js +9 -3
- package/dist/packages/core/src/config/marketConfigManager.js +9 -4
- package/dist/packages/core/src/config/parser.js +2 -4
- package/dist/packages/core/src/gateway/chat.js +2 -4
- package/dist/packages/core/src/gateway/cli.js +3 -3
- package/dist/packages/core/src/gateway/doctor.js +2 -2
- package/dist/packages/core/src/gateway/googleAuthModule.js +2 -2
- package/dist/packages/core/src/gateway/server.js +19 -10
- package/dist/packages/core/src/gateway/setup.js +2 -2
- package/dist/packages/core/src/gateway/telegram.js +12 -2
- package/dist/packages/core/src/gateway/tracker.js +3 -5
- package/dist/packages/core/src/memory/episodic.js +1 -3
- package/dist/packages/core/src/memory/logger.js +2 -4
- package/dist/packages/core/src/plugin/registry.js +1 -3
- package/dist/packages/core/src/system/skills/updateSecurityPolicy.js +1 -1
- package/dist/packages/core/src/utils/dynamicTokenUpdater.js +1 -3
- package/dist/packages/core/src/web3/aggregator/providerRegistry.js +1 -1
- package/dist/packages/core/src/web3/skills/checkPortfolio.js +1 -1
- package/dist/packages/core/src/web3/skills/marketAnalysis.js +18 -20
- package/dist/packages/core/src/web3/utils/marketEngine.js +1 -1
- package/dist/packages/core/src/web3/utils/tokens.js +2 -4
- package/dist/packages/core/src/web3/utils/vaultClient.js +4 -6
- package/dist/packages/policy/src/server.js +1 -1
- package/dist/packages/signer/src/server.js +1 -1
- package/package.json +2 -3
- package/packages/core/package.json +1 -1
- package/packages/core/src/agent/llmProvider.ts +2 -2
- package/packages/core/src/agent/osAgent.ts +3 -3
- package/packages/core/src/agent/reasoning.ts +6 -10
- package/packages/core/src/agent/web3Agent.ts +3 -3
- package/packages/core/src/config/defiConfigManager.ts +8 -3
- package/packages/core/src/config/marketConfigManager.ts +8 -4
- package/packages/core/src/config/parser.ts +2 -4
- package/packages/core/src/gateway/chat.ts +2 -4
- package/packages/core/src/gateway/cli.ts +3 -3
- package/packages/core/src/gateway/doctor.ts +2 -2
- package/packages/core/src/gateway/googleAuthModule.ts +2 -2
- package/packages/core/src/gateway/server.ts +19 -10
- package/packages/core/src/gateway/setup.ts +2 -2
- package/packages/core/src/gateway/telegram.ts +13 -2
- package/packages/core/src/gateway/tracker.ts +3 -5
- package/packages/core/src/memory/episodic.ts +1 -3
- package/packages/core/src/memory/logger.ts +2 -4
- package/packages/core/src/plugin/registry.ts +1 -3
- package/packages/core/src/system/skills/updateSecurityPolicy.ts +1 -1
- package/packages/core/src/utils/dynamicTokenUpdater.ts +1 -3
- package/packages/core/src/web3/aggregator/providerRegistry.ts +1 -1
- package/packages/core/src/web3/skills/checkPortfolio.ts +1 -1
- package/packages/core/src/web3/skills/marketAnalysis.ts +18 -20
- package/packages/core/src/web3/utils/marketEngine.ts +1 -1
- package/packages/core/src/web3/utils/tokens.ts +2 -4
- package/packages/core/src/web3/utils/vaultClient.ts +4 -6
- package/packages/dashboard/dist/assets/{index-BoFANMsj.js → index-Djg8yTDk.js} +3 -3
- package/packages/dashboard/dist/assets/index-VEis1hNq.css +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package.json +1 -7
- package/packages/mcp-server/package.json +1 -1
- package/packages/policy/package.json +1 -1
- package/packages/policy/src/server.ts +1 -1
- package/packages/signer/package.json +1 -1
- package/packages/signer/src/server.ts +1 -1
- package/packages/dashboard/dist/assets/index-K1CmXmAE.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepashangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [26.6.30]
|
|
9
|
+
### UI/UX & Quality of Life
|
|
10
|
+
- **AI Web Platform Style Empty State**: Overhauled the default chat interface when no messages are present. The dashboard now features a sleek, centered "What's on your mind today?" greeting, automatically repositioning the input bar to the center.
|
|
11
|
+
- **Dynamic Trending Tokens**: Replaced static suggestion pills with real-time Trending Tokens powered by the backend CoinGecko integration. Tokens gracefully appear under the input bar when the chat is empty.
|
|
12
|
+
- **English Token Prompt Translation**: Updated the auto-fill prompt for trending token analysis to English ("Please provide the latest market analysis for...").
|
|
13
|
+
- **Fixed Sticky Routing Cache**: Removed legacy `localStorage` persistence for `currentView`. The application now strictly resets to the `chat` interface upon every reload, preventing users from getting stuck in isolated menus (like Settings) across sessions.
|
|
14
|
+
|
|
15
|
+
### Infrastructure & Quality Assurance
|
|
16
|
+
- **Automated CI/CD Workflows**: Implemented robust GitHub Actions (`.github/workflows/ci.yml`) to automatically validate codebase integrity (build, test) on every push and pull request to the `main` branch.
|
|
17
|
+
- **Linter Eradication**: Completely uninstalled and removed all traces of ESLint, Oxlint, `lint-staged`, and Husky pre-commit hooks from the monorepo to grant developers absolute freedom and eliminate commit friction.
|
|
18
|
+
- **Mass Codebase Remediation**: Executed a highly targeted regex-based refactoring script across the monorepo to resolve over 150 instances of "empty block statement" warnings specifically targeting hollow `catch (e) {}` blocks, cleaning up legacy code overhead.
|
|
19
|
+
|
|
20
|
+
### Localization & Architecture
|
|
21
|
+
- **Global Codebase Standardization**: Conducted a comprehensive audit and translated 15+ hardcoded Indonesian string literals (UI error boundaries, LLM exception handling, Market Intelligence routing logic) into professional, crypto-native English to support international open-source contributors.
|
|
22
|
+
- **Dynamic Local-First Timezones**: Eradicated hardcoded `id-ID` and `Asia/Jakarta` parameter bindings deep within `reasoning.ts`, `osAgent.ts`, and `web3Agent.ts`. Nyxora now natively inherits the user's host OS timezone context while securely formatting dates in `en-US` for accurate LLM semantic parsing.
|
|
23
|
+
- **Text-to-Speech (TTS) Accent Correction**: Repaired the Dashboard's audio synthesis module by migrating `utterance.lang` to `en-US`, completely resolving the robotic accent glitch when reading English crypto analytics aloud.
|
|
24
|
+
|
|
8
25
|
## [26.6.29]
|
|
9
26
|
### Release & Stability
|
|
10
27
|
- **Beta Phase**: Nyxora officially enters the stable Beta phase for wider public testing.
|
package/README.md
CHANGED
|
@@ -16,6 +16,51 @@ Nyxora is a **secure, non-custodial runtime infrastructure for autonomous onchai
|
|
|
16
16
|
|
|
17
17
|
It operates under a **Zero-Trust, Defense-in-Depth Cryptographically Bound Human-in-the-Loop** execution model, ensuring that Remote AIs (LLMs) never have unilateral access to your funds.
|
|
18
18
|
|
|
19
|
+
<br/>
|
|
20
|
+
|
|
21
|
+
## ⚡ Supported Ecosystem & Integrations
|
|
22
|
+
|
|
23
|
+
**🧠 The Brain (AI / LLM Providers)**
|
|
24
|
+
<p align="center">
|
|
25
|
+
<a href="https://openai.com/"><img src="https://img.shields.io/badge/OpenAI-000000?style=for-the-badge&logo=openai&logoColor=white" alt="OpenAI"></a>
|
|
26
|
+
<a href="https://cloud.google.com/ai/gemini?hl=id"><img src="https://img.shields.io/badge/Google_AI_Studio-4285F4?style=for-the-badge&logo=googlegemini&logoColor=white" alt="Google AI Studio"></a>
|
|
27
|
+
<a href="https://claude.com/platform/api"><img src="https://img.shields.io/badge/Anthropic-D97757?style=for-the-badge&logo=anthropic&logoColor=white" alt="Anthropic"></a>
|
|
28
|
+
<a href="https://console.groq.com/keys"><img src="https://img.shields.io/badge/Groq-F55036?style=for-the-badge&logo=groq&logoColor=white" alt="Groq"></a>
|
|
29
|
+
<a href="https://mistral.ai/"><img src="https://img.shields.io/badge/Mistral-F26522?style=for-the-badge&logo=mistral&logoColor=white" alt="Mistral"></a>
|
|
30
|
+
<a href="https://x.ai/"><img src="https://img.shields.io/badge/xAI-000000?style=for-the-badge&logo=x&logoColor=white" alt="xAI"></a>
|
|
31
|
+
<a href="https://www.deepseek.com/en/"><img src="https://img.shields.io/badge/DeepSeek-4D6BFE?style=for-the-badge&logo=deepseek&logoColor=white" alt="DeepSeek"></a>
|
|
32
|
+
<a href="https://openrouter.ai/"><img src="https://img.shields.io/badge/OpenRouter-1A1A1A?style=for-the-badge&logo=openrouter&logoColor=white" alt="OpenRouter"></a>
|
|
33
|
+
<a href="https://ollama.com/"><img src="https://img.shields.io/badge/Ollama-FFFFFF?style=for-the-badge&logo=ollama&logoColor=black" alt="Ollama"></a>
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
**⛓️ The Muscles (Web3 & DeFi Ecosystem)**
|
|
37
|
+
<p align="center">
|
|
38
|
+
<a href="https://www.base.org/"><img src="https://img.shields.io/badge/Base-0052FF?style=for-the-badge&logo=coinbase&logoColor=white" alt="Base"></a>
|
|
39
|
+
<a href="https://arbitrum.io/"><img src="https://img.shields.io/badge/Arbitrum-28A0F0?style=for-the-badge&logoColor=white" alt="Arbitrum"></a>
|
|
40
|
+
<a href="https://optimism.io/"><img src="https://img.shields.io/badge/Optimism-FF0420?style=for-the-badge&logo=optimism&logoColor=white" alt="Optimism"></a>
|
|
41
|
+
<a href="https://ethereum.org/"><img src="https://img.shields.io/badge/Ethereum-627EEA?style=for-the-badge&logo=ethereum&logoColor=white" alt="Ethereum"></a>
|
|
42
|
+
<a href="https://www.bnbchain.org/en/bnb-smart-chain"><img src="https://img.shields.io/badge/BSC-F0B90B?style=for-the-badge&logo=binance&logoColor=black" alt="BSC"></a>
|
|
43
|
+
<a href="https://1inch.com/id"><img src="https://img.shields.io/badge/1inch-051024?style=for-the-badge&logoColor=white" alt="1inch"></a>
|
|
44
|
+
<a href="https://0x.org/"><img src="https://img.shields.io/badge/0x-000000?style=for-the-badge&logoColor=white" alt="0x"></a>
|
|
45
|
+
<a href="https://li.fi/"><img src="https://img.shields.io/badge/LI.FI-F7C2FF?style=for-the-badge&logoColor=white" alt="LI.FI"></a>
|
|
46
|
+
<a href="https://kyberswap.com/"><img src="https://img.shields.io/badge/KyberSwap-31CB9E?style=for-the-badge&logoColor=white" alt="KyberSwap"></a>
|
|
47
|
+
<a href="https://openocean.finance/"><img src="https://img.shields.io/badge/OpenOcean-000000?style=for-the-badge&logoColor=white" alt="OpenOcean"></a>
|
|
48
|
+
<a href="https://relay.link/"><img src="https://img.shields.io/badge/Relay-4A00E0?style=for-the-badge&logoColor=white" alt="Relay"></a>
|
|
49
|
+
<a href="https://www.coingecko.com/"><img src="https://img.shields.io/badge/CoinGecko-8CC63F?style=for-the-badge&logoColor=white" alt="CoinGecko"></a>
|
|
50
|
+
<a href="https://coinmarketcap.com/"><img src="https://img.shields.io/badge/CoinMarketCap-1A52F9?style=for-the-badge&logo=coinmarketcap&logoColor=white" alt="CoinMarketCap"></a>
|
|
51
|
+
<a href="https://dexscreener.com/"><img src="https://img.shields.io/badge/DexScreener-171717?style=for-the-badge&logoColor=white" alt="DexScreener"></a>
|
|
52
|
+
<a href="https://gopluslabs.io/en"><img src="https://img.shields.io/badge/GoPlus_Security-10B981?style=for-the-badge&logoColor=white" alt="GoPlus Labs"></a>
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
**💻 Core Technologies**
|
|
56
|
+
<p align="center">
|
|
57
|
+
<a href="https://react.dev/"><img src="https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB" alt="React"></a>
|
|
58
|
+
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript"></a>
|
|
59
|
+
<a href="https://viem.sh/"><img src="https://img.shields.io/badge/Viem-1E1E2E?style=for-the-badge&logo=v&logoColor=white" alt="Viem"></a>
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<br/>
|
|
63
|
+
|
|
19
64
|
---
|
|
20
65
|
|
|
21
66
|
## 🔥 Key Features
|
|
@@ -179,7 +224,12 @@ For complete technical deep-dives into our Cryptographic Architecture, please vi
|
|
|
179
224
|
**❤️ Support the Project**
|
|
180
225
|
|
|
181
226
|
Building and maintaining a highly secure, zero-trust architecture takes significant time and resources. If you love what we are building, you can help us keep Nyxora open, secure, and constantly evolving by sending a coffee our way:
|
|
182
|
-
- **EVM :** `
|
|
227
|
+
- **EVM :** `0x18a30D5DB50D287dbA669c5672CD71246CC4c4c6`
|
|
183
228
|
|
|
184
229
|
---
|
|
185
230
|
**License:** MIT License
|
|
231
|
+
|
|
232
|
+
<br>
|
|
233
|
+
<p align="center">
|
|
234
|
+
<sub><b>Disclaimer:</b> All product names, logos, and brands are property of their respective owners. All company, product, and service names used in this website/repository are for identification purposes only. Use of these names, logos, and brands does not imply endorsement or official partnership.</sub>
|
|
235
|
+
</p>
|
|
@@ -48,7 +48,7 @@ class AnthropicAdapter {
|
|
|
48
48
|
input: JSON.parse(tc.function.arguments)
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
|
-
catch
|
|
51
|
+
catch { }
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
anthropicMessages.push({ role: 'assistant', content: blocks.length > 0 ? blocks : m.content });
|
|
@@ -161,7 +161,7 @@ class GeminiAdapter {
|
|
|
161
161
|
}
|
|
162
162
|
});
|
|
163
163
|
}
|
|
164
|
-
catch
|
|
164
|
+
catch { }
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
if (parts.length > 0) {
|
|
@@ -16,7 +16,7 @@ exports.logger = new logger_1.Logger();
|
|
|
16
16
|
const llmUtils_1 = require("../utils/llmUtils");
|
|
17
17
|
function getSystemPrompt(context = 'os') {
|
|
18
18
|
const config = (0, parser_1.loadConfig)();
|
|
19
|
-
const currentDateTime = new Date().toLocaleString('
|
|
19
|
+
const currentDateTime = new Date().toLocaleString('en-US');
|
|
20
20
|
let basePrompt = `You are Nyxora's OS Agent (System & Automation Specialist).
|
|
21
21
|
The current real-world date and time is: ${currentDateTime}.
|
|
22
22
|
|
|
@@ -42,7 +42,7 @@ CRITICAL RULE 5: TOOL CONFIDENCE. NEVER fabricate file contents or command outpu
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
catch
|
|
45
|
+
catch { }
|
|
46
46
|
return basePrompt;
|
|
47
47
|
}
|
|
48
48
|
async function processOsIntent(input, role = 'user', onProgress, sessionId) {
|
|
@@ -201,7 +201,7 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
|
|
|
201
201
|
const status = error?.status || error?.response?.status;
|
|
202
202
|
let errorMsg = '⚠️ All models are temporarily rate-limited. Please try again in a few minutes.';
|
|
203
203
|
if (status === 400 || (error.message && error.message.toLowerCase().includes('invalid'))) {
|
|
204
|
-
errorMsg = '⚠️
|
|
204
|
+
errorMsg = '⚠️ Failed to parse instruction. The LLM had trouble determining the appropriate tool format. Please describe your command more specifically.';
|
|
205
205
|
}
|
|
206
206
|
exports.logger.addEntry({ role: 'assistant', content: errorMsg }, sessionId);
|
|
207
207
|
return errorMsg;
|
|
@@ -15,7 +15,7 @@ exports.logger = new logger_1.Logger();
|
|
|
15
15
|
const llmUtils_1 = require("../utils/llmUtils");
|
|
16
16
|
function getSystemPrompt(context = 'general') {
|
|
17
17
|
const config = (0, parser_1.loadConfig)();
|
|
18
|
-
const currentDateTime = new Date().toLocaleString('
|
|
18
|
+
const currentDateTime = new Date().toLocaleString('en-US');
|
|
19
19
|
let basePrompt = "";
|
|
20
20
|
if (context === 'web3') {
|
|
21
21
|
basePrompt = `You are Nyxora's Web3 Agent (DeFi Specialist).
|
|
@@ -131,9 +131,7 @@ Do NOT perform any web3 tasks or generic answers until they provide all 4 detail
|
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
catch
|
|
135
|
-
// Ignore db errors if not initialized
|
|
136
|
-
}
|
|
134
|
+
catch { }
|
|
137
135
|
// V3: Inject Personalized Risk Profile
|
|
138
136
|
try {
|
|
139
137
|
const profile = exports.logger.getUserProfile();
|
|
@@ -148,9 +146,7 @@ Do NOT perform any web3 tasks or generic answers until they provide all 4 detail
|
|
|
148
146
|
basePrompt += `CRITICAL: You MUST adhere to these risk parameters when advising the user or executing tools. If a requested action violates these parameters (e.g., buying a high-risk memecoin when 'Avoid Memecoins' is YES), you MUST warn the user and refuse execution unless they explicitly override.\n`;
|
|
149
147
|
}
|
|
150
148
|
}
|
|
151
|
-
catch
|
|
152
|
-
// Ignore if db not ready
|
|
153
|
-
}
|
|
149
|
+
catch { }
|
|
154
150
|
return basePrompt;
|
|
155
151
|
}
|
|
156
152
|
const web3Agent_1 = require("./web3Agent");
|
|
@@ -230,7 +226,7 @@ Reply with EXACTLY ONE WORD.`;
|
|
|
230
226
|
}
|
|
231
227
|
finalContent = finalContent.trim();
|
|
232
228
|
if (!finalContent) {
|
|
233
|
-
finalContent = "⚠️ LLM
|
|
229
|
+
finalContent = "⚠️ The LLM returned an empty or truncated response. This usually happens due to API connection fluctuations or temporary rate limits. Please try again.";
|
|
234
230
|
}
|
|
235
231
|
exports.logger.addEntry({ role: 'assistant', content: finalContent }, sessionId);
|
|
236
232
|
return finalContent;
|
|
@@ -238,9 +234,9 @@ Reply with EXACTLY ONE WORD.`;
|
|
|
238
234
|
catch (error) {
|
|
239
235
|
console.error("General LLM Error:", error);
|
|
240
236
|
const status = error?.status || error?.response?.status;
|
|
241
|
-
let errorMsg = '⚠️
|
|
237
|
+
let errorMsg = '⚠️ The system is experiencing LLM API rate limits. Please wait a few seconds and try again.';
|
|
242
238
|
if (status === 400 || (error.message && error.message.toLowerCase().includes('invalid'))) {
|
|
243
|
-
errorMsg = '⚠️
|
|
239
|
+
errorMsg = '⚠️ An error occurred. The LLM failed to format the tool or message correctly.';
|
|
244
240
|
}
|
|
245
241
|
exports.logger.addEntry({ role: 'assistant', content: errorMsg }, sessionId);
|
|
246
242
|
return errorMsg;
|
|
@@ -16,7 +16,7 @@ exports.logger = new logger_1.Logger();
|
|
|
16
16
|
const llmUtils_1 = require("../utils/llmUtils");
|
|
17
17
|
function getSystemPrompt(context = 'web3') {
|
|
18
18
|
const config = (0, parser_1.loadConfig)();
|
|
19
|
-
const currentDateTime = new Date().toLocaleString('
|
|
19
|
+
const currentDateTime = new Date().toLocaleString('en-US');
|
|
20
20
|
let basePrompt = `You are Nyxora's Web3 Agent (DeFi Specialist).
|
|
21
21
|
The current real-world date and time is: ${currentDateTime}.
|
|
22
22
|
Default Chain: ${config.agent.default_chain}
|
|
@@ -46,7 +46,7 @@ CRITICAL RULE 8: AMOUNT PRECISION. Use 6 decimal places for precision, or 2 if >
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
catch
|
|
49
|
+
catch { }
|
|
50
50
|
return basePrompt;
|
|
51
51
|
}
|
|
52
52
|
async function processWeb3Intent(input, role = 'user', onProgress, sessionId) {
|
|
@@ -210,7 +210,7 @@ async function processWeb3Intent(input, role = 'user', onProgress, sessionId) {
|
|
|
210
210
|
const status = error?.status || error?.response?.status;
|
|
211
211
|
let errorMsg = '⚠️ All models are temporarily rate-limited. Please try again in a few minutes.';
|
|
212
212
|
if (status === 400 || (error.message && error.message.toLowerCase().includes('invalid'))) {
|
|
213
|
-
errorMsg = '⚠️
|
|
213
|
+
errorMsg = '⚠️ Failed to parse instruction. The LLM had trouble determining the appropriate tool format. Please describe your command more specifically.';
|
|
214
214
|
}
|
|
215
215
|
exports.logger.addEntry({ role: 'assistant', content: errorMsg }, sessionId);
|
|
216
216
|
return errorMsg;
|
|
@@ -22,11 +22,17 @@ function loadDefiKeys() {
|
|
|
22
22
|
return {};
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
function saveDefiKeys(newKeys) {
|
|
25
|
+
function saveDefiKeys(newKeys, overwrite = false) {
|
|
26
26
|
const configPath = (0, paths_1.getPath)('defi_keys.yaml');
|
|
27
27
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
let merged;
|
|
29
|
+
if (overwrite) {
|
|
30
|
+
merged = newKeys;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const currentKeys = loadDefiKeys();
|
|
34
|
+
merged = { ...currentKeys, ...newKeys };
|
|
35
|
+
}
|
|
30
36
|
const yamlStr = yaml_1.default.stringify(merged);
|
|
31
37
|
fs_1.default.writeFileSync(configPath, yamlStr, 'utf8');
|
|
32
38
|
}
|
|
@@ -23,11 +23,16 @@ function loadMarketKeys() {
|
|
|
23
23
|
return {};
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
function saveMarketKeys(keys) {
|
|
26
|
+
function saveMarketKeys(keys, overwrite = false) {
|
|
27
27
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
let updated;
|
|
29
|
+
if (overwrite) {
|
|
30
|
+
updated = { ...keys };
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const existing = loadMarketKeys();
|
|
34
|
+
updated = { ...existing, ...keys };
|
|
35
|
+
}
|
|
31
36
|
// Remove empty values
|
|
32
37
|
for (const k in updated) {
|
|
33
38
|
if (!updated[k] || updated[k].trim() === '') {
|
|
@@ -31,9 +31,7 @@ function getEncryptionKeySync() {
|
|
|
31
31
|
if (pk)
|
|
32
32
|
masterKeyRaw = pk;
|
|
33
33
|
}
|
|
34
|
-
catch
|
|
35
|
-
// Ignore
|
|
36
|
-
}
|
|
34
|
+
catch { }
|
|
37
35
|
}
|
|
38
36
|
if (!masterKeyRaw) {
|
|
39
37
|
try {
|
|
@@ -46,7 +44,7 @@ function getEncryptionKeySync() {
|
|
|
46
44
|
try {
|
|
47
45
|
fs_1.default.writeFileSync(masterKeyPath, masterKeyRaw, { mode: 0o600 });
|
|
48
46
|
}
|
|
49
|
-
catch
|
|
47
|
+
catch { }
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
catch (e) {
|
|
@@ -20,7 +20,7 @@ async function chatInteractive() {
|
|
|
20
20
|
const parsed = JSON.parse(token);
|
|
21
21
|
token = parsed.token;
|
|
22
22
|
}
|
|
23
|
-
catch
|
|
23
|
+
catch { }
|
|
24
24
|
}
|
|
25
25
|
const logo = `
|
|
26
26
|
███╗ ██╗██╗ ██╗██╗ ██╗ ██████╗ ██████╗ █████╗
|
|
@@ -108,9 +108,7 @@ async function chatInteractive() {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
catch
|
|
112
|
-
// silently ignore fetch errors for tx polling
|
|
113
|
-
}
|
|
111
|
+
catch { }
|
|
114
112
|
}
|
|
115
113
|
catch (error) {
|
|
116
114
|
s.stop(picocolors_1.default.red('Connection failed.'));
|
|
@@ -137,7 +137,7 @@ async function main() {
|
|
|
137
137
|
if (fs_1.default.existsSync(vaultPath))
|
|
138
138
|
fs_1.default.unlinkSync(vaultPath);
|
|
139
139
|
}
|
|
140
|
-
catch
|
|
140
|
+
catch { }
|
|
141
141
|
}
|
|
142
142
|
catch (e) {
|
|
143
143
|
const vaultDir = path_1.default.join(os_1.default.homedir(), '.nyxora', 'auth');
|
|
@@ -190,13 +190,13 @@ async function main() {
|
|
|
190
190
|
try {
|
|
191
191
|
await walletEntry.deletePassword();
|
|
192
192
|
}
|
|
193
|
-
catch
|
|
193
|
+
catch { }
|
|
194
194
|
console.log(picocolors_1.default.green('✅ Wallet key removed from OS Keyring.'));
|
|
195
195
|
const masterEntry = new Entry('nyxora', 'config_master');
|
|
196
196
|
try {
|
|
197
197
|
await masterEntry.deletePassword();
|
|
198
198
|
}
|
|
199
|
-
catch
|
|
199
|
+
catch { }
|
|
200
200
|
console.log(picocolors_1.default.green('✅ Master key removed from OS Keyring.'));
|
|
201
201
|
}
|
|
202
202
|
catch (e) {
|
|
@@ -101,7 +101,7 @@ async function runDoctor() {
|
|
|
101
101
|
process.kill(parseInt(pidStr, 10), 0);
|
|
102
102
|
isDaemonRunning = true;
|
|
103
103
|
}
|
|
104
|
-
catch
|
|
104
|
+
catch { }
|
|
105
105
|
}
|
|
106
106
|
if (isDaemonRunning && !port3000Free) {
|
|
107
107
|
console.log(`${picocolors_1.default.green('✓')} Port 3000 (Core/Gateway API) ${picocolors_1.default.cyan('[In Use by Nyxora]')}`);
|
|
@@ -123,7 +123,7 @@ async function runDoctor() {
|
|
|
123
123
|
try {
|
|
124
124
|
sockExists = fs_1.default.existsSync(sockPath);
|
|
125
125
|
}
|
|
126
|
-
catch
|
|
126
|
+
catch { }
|
|
127
127
|
if (sockExists) {
|
|
128
128
|
if (isDaemonRunning) {
|
|
129
129
|
console.log(`${picocolors_1.default.green('✓')} ${name} UDS (${sockPath}) ${picocolors_1.default.cyan('[In Use by Nyxora]')}`);
|
|
@@ -139,13 +139,13 @@ async function logoutGoogle() {
|
|
|
139
139
|
const entry = new Entry('nyxora', 'google_refresh_token');
|
|
140
140
|
await entry.deletePassword();
|
|
141
141
|
}
|
|
142
|
-
catch
|
|
142
|
+
catch { }
|
|
143
143
|
try {
|
|
144
144
|
if (fs_1.default.existsSync(FALLBACK_TOKEN_PATH)) {
|
|
145
145
|
fs_1.default.unlinkSync(FALLBACK_TOKEN_PATH);
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
catch
|
|
148
|
+
catch { }
|
|
149
149
|
accessToken = null;
|
|
150
150
|
tokenExpiry = 0;
|
|
151
151
|
console.log('[Google Auth] Successfully logged out.');
|
|
@@ -269,9 +269,9 @@ app.post('/api/config', (req, res) => {
|
|
|
269
269
|
const newConfig = {
|
|
270
270
|
...currentConfig,
|
|
271
271
|
...req.body,
|
|
272
|
-
agent: { ...currentConfig.agent, ...
|
|
273
|
-
llm: { ...currentConfig.llm, ...
|
|
274
|
-
web3: { ...currentConfig.web3, ...
|
|
272
|
+
agent: { ...currentConfig.agent, ...req.body.agent },
|
|
273
|
+
llm: { ...currentConfig.llm, ...req.body.llm },
|
|
274
|
+
web3: { ...currentConfig.web3, ...req.body.web3 }
|
|
275
275
|
};
|
|
276
276
|
// Save merged configuration to file
|
|
277
277
|
(0, parser_1.saveConfig)(newConfig);
|
|
@@ -345,7 +345,7 @@ app.delete('/api/defi-keys/:id', (req, res) => {
|
|
|
345
345
|
try {
|
|
346
346
|
const keys = (0, defiConfigManager_1.loadDefiKeys)();
|
|
347
347
|
delete keys[req.params.id];
|
|
348
|
-
(0, defiConfigManager_1.saveDefiKeys)(keys);
|
|
348
|
+
(0, defiConfigManager_1.saveDefiKeys)(keys, true);
|
|
349
349
|
res.json({ success: true });
|
|
350
350
|
}
|
|
351
351
|
catch (error) {
|
|
@@ -387,6 +387,17 @@ app.post('/api/market-keys', (req, res) => {
|
|
|
387
387
|
res.status(500).json({ error: error.message });
|
|
388
388
|
}
|
|
389
389
|
});
|
|
390
|
+
app.delete('/api/market-keys/:id', (req, res) => {
|
|
391
|
+
try {
|
|
392
|
+
const keys = (0, marketConfigManager_1.loadMarketKeys)();
|
|
393
|
+
delete keys[req.params.id];
|
|
394
|
+
(0, marketConfigManager_1.saveMarketKeys)(keys, true);
|
|
395
|
+
res.json({ success: true });
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
res.status(500).json({ error: error.message });
|
|
399
|
+
}
|
|
400
|
+
});
|
|
390
401
|
// Get skills from PluginManager dynamically
|
|
391
402
|
const getWeb3Skills = () => {
|
|
392
403
|
return registry_1.pluginManager.getPlugins()
|
|
@@ -723,7 +734,7 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
723
734
|
});
|
|
724
735
|
}
|
|
725
736
|
// 2. Combine TOKEN_MAP and YAML whitelist for this chain
|
|
726
|
-
const tokensToQuery = { ...
|
|
737
|
+
const tokensToQuery = { ...tokens_1.TOKEN_MAP[chainName] };
|
|
727
738
|
// Inject whitelisted tokens
|
|
728
739
|
userCustomTokens.forEach(t => {
|
|
729
740
|
if (t.chainName === chainName && t.symbol && t.address) {
|
|
@@ -758,9 +769,7 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
758
769
|
});
|
|
759
770
|
}
|
|
760
771
|
}
|
|
761
|
-
catch
|
|
762
|
-
// Ignore read errors
|
|
763
|
-
}
|
|
772
|
+
catch { }
|
|
764
773
|
}));
|
|
765
774
|
}
|
|
766
775
|
catch (e) {
|
|
@@ -1030,7 +1039,7 @@ async function autoMigrateKeys() {
|
|
|
1030
1039
|
console.log('[Auto-Migrate] Migrated legacy keys from OS Keyring.');
|
|
1031
1040
|
}
|
|
1032
1041
|
}
|
|
1033
|
-
catch
|
|
1042
|
+
catch { }
|
|
1034
1043
|
if (Object.keys(extractedKeys).length === 0 && fs_1.default.existsSync(vaultPath)) {
|
|
1035
1044
|
try {
|
|
1036
1045
|
const file = fs_1.default.readFileSync(vaultPath, 'utf8');
|
|
@@ -1038,7 +1047,7 @@ async function autoMigrateKeys() {
|
|
|
1038
1047
|
fs_1.default.unlinkSync(vaultPath);
|
|
1039
1048
|
console.log('[Auto-Migrate] Migrated legacy keys from api_vault.key.');
|
|
1040
1049
|
}
|
|
1041
|
-
catch
|
|
1050
|
+
catch { }
|
|
1042
1051
|
}
|
|
1043
1052
|
if (Object.keys(extractedKeys).length > 0) {
|
|
1044
1053
|
const config = (0, parser_1.loadConfig)();
|
|
@@ -386,7 +386,7 @@ Provider: ${config.llm.provider}`;
|
|
|
386
386
|
try {
|
|
387
387
|
bot.stop();
|
|
388
388
|
}
|
|
389
|
-
catch
|
|
389
|
+
catch { }
|
|
390
390
|
authorizedChatId = undefined;
|
|
391
391
|
telegramToken = '';
|
|
392
392
|
}
|
|
@@ -401,7 +401,7 @@ Provider: ${config.llm.provider}`;
|
|
|
401
401
|
if (bot)
|
|
402
402
|
bot.stop();
|
|
403
403
|
}
|
|
404
|
-
catch
|
|
404
|
+
catch { }
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
407
|
}
|
|
@@ -19,6 +19,7 @@ const mintNft_1 = require("../web3/skills/mintNft");
|
|
|
19
19
|
const customTx_1 = require("../web3/skills/customTx");
|
|
20
20
|
const executeDefi_1 = require("../web3/skills/executeDefi");
|
|
21
21
|
const revokeApprovals_1 = require("../web3/skills/revokeApprovals");
|
|
22
|
+
const checkRegistryStatus_1 = require("../web3/skills/checkRegistryStatus");
|
|
22
23
|
const formatter_1 = require("../utils/formatter");
|
|
23
24
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
24
25
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -133,7 +134,7 @@ function startTelegramBot() {
|
|
|
133
134
|
await ctx.api.editMessageText(ctx.chat.id, progressMsgId, `<i>${progressText.replace(/_/g, '')}</i>`, { parse_mode: 'HTML' });
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
|
-
catch
|
|
137
|
+
catch { }
|
|
137
138
|
};
|
|
138
139
|
const response = await (0, reasoning_1.processUserInput)(text, 'user', onProgress, `telegram_${ctx.chat?.id}`);
|
|
139
140
|
if (progressMsgId) {
|
|
@@ -187,7 +188,7 @@ function startTelegramBot() {
|
|
|
187
188
|
await ctx.api.editMessageText(ctx.chat.id, progressMsgId, `<i>${progressText.replace(/_/g, '')}</i>`, { parse_mode: 'HTML' });
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
|
-
catch
|
|
191
|
+
catch { }
|
|
191
192
|
};
|
|
192
193
|
const response = await (0, reasoning_1.processUserInput)(prompt, 'user', onProgress, `telegram_${ctx.chat?.id}`);
|
|
193
194
|
if (progressMsgId) {
|
|
@@ -211,6 +212,15 @@ function startTelegramBot() {
|
|
|
211
212
|
await ctx.reply(`⏳ Processing transaction ${txId}...`);
|
|
212
213
|
await ctx.api.editMessageReplyMarkup(ctx.chat.id, ctx.msg.message_id, { reply_markup: { inline_keyboard: [] } }).catch(() => { });
|
|
213
214
|
try {
|
|
215
|
+
// --- Arbitrum Registry Kill-Switch Interceptor ---
|
|
216
|
+
const registryCheck = await (0, checkRegistryStatus_1.checkRegistryStatus)();
|
|
217
|
+
if (!registryCheck.isActive) {
|
|
218
|
+
transactionManager_1.txManager.updateStatus(txId, 'failed', registryCheck.reason);
|
|
219
|
+
reasoning_1.logger.addEntry({ role: 'assistant', content: `❌ **Security Blocked:** ${registryCheck.reason}` }, `telegram_${ctx.chat?.id}`);
|
|
220
|
+
await ctx.reply(formatToTelegramHTML(`❌ **Security Blocked:** ${registryCheck.reason}`), { parse_mode: 'HTML' });
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// ------------------------------------------------
|
|
214
224
|
let result = '';
|
|
215
225
|
if (tx.type === 'transfer') {
|
|
216
226
|
result = await (0, transfer_1.executeTransfer)(tx.chainName, tx.details, true);
|
|
@@ -52,9 +52,7 @@ let trackerFile = '';
|
|
|
52
52
|
try {
|
|
53
53
|
trackerFile = (0, paths_1.getPath)('tracker.json');
|
|
54
54
|
}
|
|
55
|
-
catch
|
|
56
|
-
// Fallback
|
|
57
|
-
}
|
|
55
|
+
catch { }
|
|
58
56
|
function loadState() {
|
|
59
57
|
if (!trackerFile)
|
|
60
58
|
return;
|
|
@@ -71,7 +69,7 @@ function loadState() {
|
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
|
-
catch
|
|
72
|
+
catch { }
|
|
75
73
|
}
|
|
76
74
|
let savePending = false;
|
|
77
75
|
function saveState() {
|
|
@@ -100,7 +98,7 @@ function flushState() {
|
|
|
100
98
|
try {
|
|
101
99
|
fs_1.default.writeFileSync(trackerFile, JSON.stringify({ stats, eventLogs, gatewayLogs }));
|
|
102
100
|
}
|
|
103
|
-
catch
|
|
101
|
+
catch { }
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
104
|
process.on('exit', flushState);
|
|
@@ -86,9 +86,7 @@ class Logger {
|
|
|
86
86
|
try {
|
|
87
87
|
this.db.prepare('ALTER TABLE messages ADD COLUMN session_id TEXT').run();
|
|
88
88
|
}
|
|
89
|
-
catch
|
|
90
|
-
// Column probably already exists
|
|
91
|
-
}
|
|
89
|
+
catch { }
|
|
92
90
|
// Migration logic from old memory.json to SQLite
|
|
93
91
|
const config = (0, parser_1.loadConfig)() || {};
|
|
94
92
|
const oldJsonPath = (0, paths_1.getPath)((config && config.memory && config.memory.path) ? config.memory.path : 'memory.json');
|
|
@@ -210,7 +208,7 @@ class Logger {
|
|
|
210
208
|
this.db.prepare('INSERT INTO sessions (id, title) VALUES (?, ?)').run(sessionId, title);
|
|
211
209
|
}
|
|
212
210
|
}
|
|
213
|
-
catch
|
|
211
|
+
catch { }
|
|
214
212
|
}
|
|
215
213
|
const insert = this.db.prepare(`
|
|
216
214
|
INSERT INTO messages (session_id, role, content, name, tool_call_id, tool_calls)
|
|
@@ -14,7 +14,7 @@ function updateSecurityPolicy(rule, action) {
|
|
|
14
14
|
let policyRules = { max_usd_per_tx: 999999999, whitelist_only: false, require_approval: true, custom_llm_rules: [] };
|
|
15
15
|
if (fs_1.default.existsSync(policyPath)) {
|
|
16
16
|
const file = fs_1.default.readFileSync(policyPath, 'utf8');
|
|
17
|
-
policyRules = { ...policyRules, ...
|
|
17
|
+
policyRules = { ...policyRules, ...yaml_1.default.parse(file) };
|
|
18
18
|
}
|
|
19
19
|
if (!Array.isArray(policyRules.custom_llm_rules)) {
|
|
20
20
|
policyRules.custom_llm_rules = [];
|
|
@@ -27,9 +27,7 @@ async function fetchDynamicTokens() {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
catch
|
|
31
|
-
// Ignore cache error
|
|
32
|
-
}
|
|
30
|
+
catch { }
|
|
33
31
|
const result = {};
|
|
34
32
|
console.log('[DynamicTokenUpdater] Fetching updated token lists...');
|
|
35
33
|
for (const [chain, url] of Object.entries(TOKEN_LIST_URLS)) {
|
|
@@ -162,7 +162,7 @@ async function checkPortfolio(chainName, address) {
|
|
|
162
162
|
});
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
-
catch
|
|
165
|
+
catch { }
|
|
166
166
|
}
|
|
167
167
|
for (const b of nonZeroBalances) {
|
|
168
168
|
const lookupAddr = String((b.isNative ? (chainTokens?.WETH || chainTokens?.WBNB) : b.address) || "").toLowerCase();
|