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.
@@ -7,11 +7,15 @@ exports.startTelegramBot = startTelegramBot;
7
7
  const node_telegram_bot_api_1 = __importDefault(require("node-telegram-bot-api"));
8
8
  const reasoning_1 = require("../agent/reasoning");
9
9
  const parser_1 = require("../config/parser");
10
+ const transactionManager_1 = require("../agent/transactionManager");
11
+ const transfer_1 = require("../web3/skills/transfer");
12
+ const swapToken_1 = require("../web3/skills/swapToken");
13
+ const formatter_1 = require("../utils/formatter");
10
14
  function startTelegramBot() {
11
15
  const config = (0, parser_1.loadConfig)();
12
- const token = config.integrations?.telegram?.bot_token || process.env.TELEGRAM_BOT_TOKEN;
16
+ const token = config.integrations?.telegram?.bot_token;
13
17
  if (!token) {
14
- console.log('[Telegram] No TELEGRAM_BOT_TOKEN found in .env. Bot is disabled.');
18
+ console.log('[Telegram] No TELEGRAM_BOT_TOKEN found in config.yaml. Bot is disabled.');
15
19
  return;
16
20
  }
17
21
  try {
@@ -29,13 +33,74 @@ function startTelegramBot() {
29
33
  // Feed the message to the AI agent
30
34
  const response = await (0, reasoning_1.processUserInput)(text);
31
35
  // Send the AI's response back to Telegram
36
+ // Check for newly created pending transactions
37
+ const pendingTxs = transactionManager_1.txManager.getPending();
38
+ if (pendingTxs.length > 0) {
39
+ const latestTx = pendingTxs[pendingTxs.length - 1];
40
+ // If the transaction was created within the last 2 minutes, show the inline keyboard
41
+ if (Date.now() - latestTx.createdAt < 120000) {
42
+ bot.sendMessage(chatId, response, {
43
+ reply_markup: {
44
+ inline_keyboard: [[
45
+ { text: '✅ Approve', callback_data: `approve_${latestTx.id}` },
46
+ { text: '❌ Reject', callback_data: `reject_${latestTx.id}` }
47
+ ]]
48
+ }
49
+ });
50
+ return;
51
+ }
52
+ }
32
53
  bot.sendMessage(chatId, response);
33
54
  }
34
55
  catch (error) {
35
56
  console.error('[Telegram] Error processing message:', error);
36
- bot.sendMessage(chatId, '❌ Maaf, saya mengalami gangguan saat memproses pesan Anda.');
57
+ bot.sendMessage(chatId, '❌ Sorry, I encountered an error while processing your message.');
37
58
  }
38
59
  });
60
+ bot.on('callback_query', async (query) => {
61
+ const chatId = query.message?.chat.id;
62
+ if (!chatId || !query.data)
63
+ return;
64
+ const [action, txId] = query.data.split('_');
65
+ const tx = transactionManager_1.txManager.getTransaction(txId);
66
+ if (!tx || tx.status !== 'pending') {
67
+ bot.answerCallbackQuery(query.id, { text: 'Transaction not found or already processed.', show_alert: true });
68
+ return;
69
+ }
70
+ if (action === 'approve') {
71
+ bot.answerCallbackQuery(query.id, { text: 'Processing transaction...' });
72
+ bot.sendMessage(chatId, `⏳ Processing transaction ${txId}...`);
73
+ try {
74
+ let result = '';
75
+ if (tx.type === 'transfer') {
76
+ result = await (0, transfer_1.executeTransfer)(tx.chainName, tx.details.toAddress, tx.details.amountEth);
77
+ }
78
+ else if (tx.type === 'swap') {
79
+ result = await (0, swapToken_1.executeSwap)(tx.chainName, tx.details.fromToken, tx.details.toToken, tx.details.amount);
80
+ }
81
+ transactionManager_1.txManager.updateStatus(txId, 'executed', result);
82
+ const prettyMsg = (0, formatter_1.formatTransactionSuccess)(tx, result);
83
+ bot.sendMessage(chatId, `✅ Transaction processed:\n\n${prettyMsg}`);
84
+ // Background update to LLM
85
+ (0, reasoning_1.processUserInput)(`Transaction ${txId} was APPROVED via Telegram. Result: ${result}`, 'system').catch(() => { });
86
+ }
87
+ catch (err) {
88
+ transactionManager_1.txManager.updateStatus(txId, 'failed', err.message);
89
+ const prettyError = (0, formatter_1.formatTransactionError)(tx, err.message);
90
+ bot.sendMessage(chatId, prettyError);
91
+ // Background update to LLM
92
+ (0, reasoning_1.processUserInput)(`Transaction ${txId} FAILED via Telegram. Error: ${err.message}`, 'system').catch(() => { });
93
+ }
94
+ }
95
+ else if (action === 'reject') {
96
+ transactionManager_1.txManager.updateStatus(txId, 'rejected');
97
+ (0, reasoning_1.processUserInput)(`Transaction ${txId} was REJECTED via Telegram. Acknowledge this briefly.`, 'system').catch(() => { });
98
+ bot.answerCallbackQuery(query.id, { text: 'Transaction cancelled.' });
99
+ bot.sendMessage(chatId, `❌ Transaction cancelled.`);
100
+ }
101
+ // Remove inline keyboard
102
+ bot.editMessageReplyMarkup({ inline_keyboard: [] }, { chat_id: chatId, message_id: query.message?.message_id });
103
+ });
39
104
  bot.on('polling_error', (error) => {
40
105
  console.error('[Telegram] Polling error:', error);
41
106
  });
@@ -1,41 +1,6 @@
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
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  const reasoning_1 = require("../agent/reasoning");
37
- const dotenv = __importStar(require("dotenv"));
38
- dotenv.config();
39
4
  async function run() {
40
5
  console.log('🤖 Agent Test Started...');
41
6
  console.log('👤 You: Tolong cek saldo native di jaringan ethereum');
@@ -0,0 +1,35 @@
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.encryptKey = encryptKey;
7
+ exports.decryptKey = decryptKey;
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ function encryptKey(privateKey, password) {
10
+ const salt = crypto_1.default.randomBytes(16);
11
+ const key = crypto_1.default.pbkdf2Sync(password, salt, 100000, 32, 'sha256');
12
+ const iv = crypto_1.default.randomBytes(12);
13
+ const cipher = crypto_1.default.createCipheriv('aes-256-gcm', key, iv);
14
+ let encrypted = cipher.update(privateKey, 'utf8', 'hex');
15
+ encrypted += cipher.final('hex');
16
+ const authTag = cipher.getAuthTag().toString('hex');
17
+ return {
18
+ salt: salt.toString('hex'),
19
+ iv: iv.toString('hex'),
20
+ authTag,
21
+ encryptedData: encrypted
22
+ };
23
+ }
24
+ function decryptKey(keystore, password) {
25
+ const salt = Buffer.from(keystore.salt, 'hex');
26
+ const iv = Buffer.from(keystore.iv, 'hex');
27
+ const authTag = Buffer.from(keystore.authTag, 'hex');
28
+ const encryptedText = Buffer.from(keystore.encryptedData, 'hex');
29
+ const key = crypto_1.default.pbkdf2Sync(password, salt, 100000, 32, 'sha256');
30
+ const decipher = crypto_1.default.createDecipheriv('aes-256-gcm', key, iv);
31
+ decipher.setAuthTag(authTag);
32
+ let decrypted = decipher.update(encryptedText, undefined, 'utf8');
33
+ decrypted += decipher.final('utf8');
34
+ return decrypted;
35
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatTransactionSuccess = formatTransactionSuccess;
4
+ exports.formatTransactionError = formatTransactionError;
5
+ function formatTransactionSuccess(tx, rawResult) {
6
+ let txHash = 'N/A';
7
+ try {
8
+ const parsed = JSON.parse(rawResult);
9
+ if (parsed.txHash)
10
+ txHash = parsed.txHash;
11
+ }
12
+ catch (e) {
13
+ const hashMatch = rawResult.match(/Hash: (0x[a-fA-F0-9]+)/);
14
+ if (hashMatch) {
15
+ txHash = hashMatch[1];
16
+ }
17
+ }
18
+ const chainFormatted = tx.chainName.charAt(0).toUpperCase() + tx.chainName.slice(1);
19
+ if (tx.type === 'swap') {
20
+ return `Alright, I have completed the swap from ${tx.details.amount} ${tx.details.fromToken.toUpperCase()} to ${tx.details.toToken.toUpperCase()}.\n\nChain: ${chainFormatted}\nTx Hash:\n${txHash}`;
21
+ }
22
+ else if (tx.type === 'transfer') {
23
+ return `Alright, I have completed the transfer of ${tx.details.amountEth} tokens to ${tx.details.toAddress}.\n\nChain: ${chainFormatted}\nTx Hash:\n${txHash}`;
24
+ }
25
+ return `Transaction successful!\n\nChain: ${chainFormatted}\nTx Hash:\n${txHash}`;
26
+ }
27
+ function formatTransactionError(tx, errorMsg) {
28
+ const chainFormatted = tx.chainName.charAt(0).toUpperCase() + tx.chainName.slice(1);
29
+ return `❌ Failed to process transaction on ${chainFormatted}.\n\nError: ${errorMsg}`;
30
+ }
@@ -0,0 +1,30 @@
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.getSessionToken = getSessionToken;
7
+ exports.setPrivateKey = setPrivateKey;
8
+ exports.getPrivateKey = getPrivateKey;
9
+ exports.clearPrivateKey = clearPrivateKey;
10
+ let decryptedPrivateKey = null;
11
+ let sessionToken = null;
12
+ const crypto_1 = __importDefault(require("crypto"));
13
+ function getSessionToken() {
14
+ if (!sessionToken) {
15
+ sessionToken = crypto_1.default.randomBytes(32).toString('hex');
16
+ }
17
+ return sessionToken;
18
+ }
19
+ function setPrivateKey(key) {
20
+ decryptedPrivateKey = key;
21
+ }
22
+ function getPrivateKey() {
23
+ if (!decryptedPrivateKey) {
24
+ throw new Error('Private key is not loaded into memory. Please authenticate first.');
25
+ }
26
+ return decryptedPrivateKey;
27
+ }
28
+ function clearPrivateKey() {
29
+ decryptedPrivateKey = null;
30
+ }
@@ -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
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.supportedChains = void 0;
37
4
  exports.getPublicClient = getPublicClient;
@@ -40,9 +7,8 @@ exports.getAddress = getAddress;
40
7
  const viem_1 = require("viem");
41
8
  const accounts_1 = require("viem/accounts");
42
9
  const chains_1 = require("viem/chains");
43
- const dotenv = __importStar(require("dotenv"));
44
10
  const parser_1 = require("../config/parser");
45
- dotenv.config();
11
+ const state_1 = require("../utils/state");
46
12
  exports.supportedChains = {
47
13
  ethereum: chains_1.mainnet,
48
14
  base: chains_1.base,
@@ -67,9 +33,7 @@ function getWalletClient(chainName) {
67
33
  const chain = exports.supportedChains[chainName];
68
34
  if (!chain)
69
35
  throw new Error(`Unsupported chain: ${chainName}`);
70
- const privateKey = process.env.PRIVATE_KEY;
71
- if (!privateKey)
72
- throw new Error('PRIVATE_KEY is not set in .env');
36
+ const privateKey = (0, state_1.getPrivateKey)();
73
37
  const account = (0, accounts_1.privateKeyToAccount)(privateKey);
74
38
  const config = (0, parser_1.loadConfig)();
75
39
  const rpcUrl = config.web3?.rpc_urls?.[chainName];
@@ -81,8 +45,6 @@ function getWalletClient(chainName) {
81
45
  });
82
46
  }
83
47
  function getAddress() {
84
- const privateKey = process.env.PRIVATE_KEY;
85
- if (!privateKey)
86
- throw new Error('PRIVATE_KEY is not set in .env');
48
+ const privateKey = (0, state_1.getPrivateKey)();
87
49
  return (0, accounts_1.privateKeyToAccount)(privateKey).address;
88
50
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.swapTokenToolDefinition = void 0;
4
4
  exports.swapToken = swapToken;
5
+ exports.executeSwap = executeSwap;
5
6
  exports.swapTokenToolDefinition = {
6
7
  type: "function",
7
8
  function: {
@@ -31,7 +32,12 @@ exports.swapTokenToolDefinition = {
31
32
  },
32
33
  },
33
34
  };
35
+ const transactionManager_1 = require("../../agent/transactionManager");
34
36
  async function swapToken(chainName, fromToken, toToken, amount) {
37
+ const tx = transactionManager_1.txManager.createPendingTransaction('swap', chainName, { fromToken, toToken, amount });
38
+ return `TRANSACTION_PENDING: I have prepared the token swap. Transaction ID: ${tx.id}. Wait for user to approve.`;
39
+ }
40
+ async function executeSwap(chainName, fromToken, toToken, amount) {
35
41
  try {
36
42
  // Generate simulated exchange rate for testnet/demo purposes
37
43
  let rate = 1.0;
@@ -2,19 +2,24 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transferToolDefinition = void 0;
4
4
  exports.transferNative = transferNative;
5
+ exports.executeTransfer = executeTransfer;
5
6
  const viem_1 = require("viem");
6
7
  const config_1 = require("../config");
8
+ const transactionManager_1 = require("../../agent/transactionManager");
7
9
  async function transferNative(chainName, toAddress, amountEth) {
10
+ const tx = transactionManager_1.txManager.createPendingTransaction('transfer', chainName, { toAddress, amountEth });
11
+ return `TRANSACTION_PENDING: I have prepared the transfer. Transaction ID: ${tx.id}. Wait for user to approve.`;
12
+ }
13
+ async function executeTransfer(chainName, toAddress, amountEth) {
8
14
  try {
9
15
  const client = (0, config_1.getWalletClient)(chainName);
10
- // Attempt to send the transaction
11
16
  const hash = await client.sendTransaction({
12
17
  account: client.account,
13
18
  chain: client.chain,
14
19
  to: toAddress,
15
20
  value: (0, viem_1.parseEther)(amountEth),
16
21
  });
17
- return `Successfully transferred ${amountEth} native token on ${chainName}. Transaction hash: ${hash}`;
22
+ return `Transaction successful. Hash: ${hash}`;
18
23
  }
19
24
  catch (error) {
20
25
  return `Failed to transfer: ${error.message}`;
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "nyxora",
3
- "version": "1.0.8",
3
+ "version": "1.1.2",
4
4
  "description": "",
5
5
  "main": "dist/gateway/cli.js",
6
6
  "files": [
7
7
  "dist",
8
8
  "dashboard/dist",
9
- "config.yaml",
10
9
  "user.md",
11
10
  "IDENTITY.md",
12
11
  "SECURITY.md",
@@ -20,7 +19,7 @@
20
19
  "start": "node dist/gateway/cli.js",
21
20
  "dashboard": "npm run build && node dist/gateway/cli.js",
22
21
  "test": "echo \"Error: no test specified\" && exit 1",
23
- "deploy": "npm run build && git add . && git commit -m \"chore: auto-deploy new feature\" && git push && npm publish"
22
+ "deploy": "npm run build && git add . && git commit -m \"chore: auto-deploy new feature\" && git push && git push --tags && npm publish"
24
23
  },
25
24
  "keywords": [],
26
25
  "author": "",
@@ -30,7 +29,6 @@
30
29
  "@clack/prompts": "^1.4.0",
31
30
  "concurrently": "^9.2.1",
32
31
  "cors": "^2.8.6",
33
- "dotenv": "^17.4.2",
34
32
  "express": "^5.2.1",
35
33
  "node-telegram-bot-api": "^0.67.0",
36
34
  "open": "^11.0.0",
package/user.md CHANGED
@@ -1,10 +1,9 @@
1
- Tuliskan instruksi kustom, aturan khusus, profil pengguna, atau persona yang Anda inginkan untuk Nyxora AI di file ini.
1
+ Write custom instructions, special rules, user profiles, or the persona you want for Nyxora AI in this file.
2
2
 
3
- Setiap kali agen membaca pesan Anda, ia akan membaca file ini terlebih dahulu sebagai pedoman utama.
3
+ Every time the agent reads your messages, it will read this file first as its primary guideline.
4
4
 
5
- Contoh:
6
-
7
- * "Panggil saya dengan sebutan Yudha"
8
- * "Gunakan gaya bahasa santai dan gaul"
9
- * "Fokuskan analisis pada sudut pandang teknikal trading"
5
+ Examples:
10
6
 
7
+ * "Call me Yudha"
8
+ * "Use casual and slang language"
9
+ * "Focus analysis from a technical trading perspective"
package/config.yaml DELETED
@@ -1,14 +0,0 @@
1
- agent:
2
- name: Nyxora-EVM-Agent
3
- default_chain: sepolia
4
- llm:
5
- provider: gemini
6
- model: gemini-2.5-flash
7
- temperature: 0.2
8
- credentials: {}
9
- memory:
10
- type: file
11
- path: ./memory.json
12
- integrations:
13
- telegram:
14
- enabled: false