nyxora 26.7.2 → 26.7.3

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.
Files changed (167) hide show
  1. package/CHANGELOG.md +95 -47
  2. package/README.md +23 -19
  3. package/bin/nyxora.mjs +4 -6
  4. package/dist/launcher.js +44 -8
  5. package/dist/packages/core/src/agent/bridgeWatcher.js +3 -2
  6. package/dist/packages/core/src/agent/cronManager.js +2 -2
  7. package/dist/packages/core/src/agent/llmProvider.js +242 -0
  8. package/dist/packages/core/src/agent/nyxDaemon.js +97 -0
  9. package/dist/packages/core/src/agent/osAgent.js +203 -29
  10. package/dist/packages/core/src/agent/reasoning.js +353 -60
  11. package/dist/packages/core/src/agent/reasoningScratchpad.js +47 -0
  12. package/dist/packages/core/src/agent/transactionManager.js +36 -31
  13. package/dist/packages/core/src/agent/web3Agent.js +263 -37
  14. package/dist/packages/core/src/cognitive/cognitiveManager.js +63 -10
  15. package/dist/packages/core/src/config/parser.js +10 -4
  16. package/dist/packages/core/src/gateway/chat.js +56 -13
  17. package/dist/packages/core/src/gateway/cli.js +3 -0
  18. package/dist/packages/core/src/gateway/discordAdapter.js +81 -0
  19. package/dist/packages/core/src/gateway/server.js +58 -9
  20. package/dist/packages/core/src/gateway/setup-ml.js +64 -0
  21. package/dist/packages/core/src/gateway/setup.js +39 -3
  22. package/dist/packages/core/src/gateway/telegram.js +120 -24
  23. package/dist/packages/core/src/memory/episodic.js +47 -3
  24. package/dist/packages/core/src/memory/logger.js +120 -2
  25. package/dist/packages/core/src/memory/promotionEngine.js +18 -5
  26. package/dist/packages/core/src/system/agentskills.js +10 -0
  27. package/dist/packages/core/src/system/plugins/GoogleWorkspacePlugin.js +1 -1
  28. package/dist/packages/core/src/system/plugins/SystemCorePlugin.js +1 -1
  29. package/dist/packages/core/src/system/plugins/SystemExternalPlugin.js +1 -1
  30. package/dist/packages/core/src/system/plugins/SystemPluginInstallerPlugin.js +1 -1
  31. package/dist/packages/core/src/system/plugins/SystemSocialPlugin.js +1 -1
  32. package/dist/packages/core/src/system/plugins/SystemWebPlugin.js +1 -1
  33. package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +3 -3
  34. package/dist/packages/core/src/system/plugins/createSkill.js +1 -1
  35. package/dist/packages/core/src/system/skillExtractor.js +16 -5
  36. package/dist/packages/core/src/system/skills/forgetMemory.js +6 -4
  37. package/dist/packages/core/src/system/skills/scheduleTask.js +7 -2
  38. package/dist/packages/core/src/test_mainnet.js +45 -0
  39. package/dist/packages/core/src/utils/contextSummarizer.js +82 -0
  40. package/dist/packages/core/src/utils/skillManager.js +1 -1
  41. package/dist/packages/core/src/utils/streamSimulator.js +85 -0
  42. package/dist/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.js +28 -11
  43. package/dist/packages/core/src/web3/aggregator/providers/OpBridgeProvider.js +41 -27
  44. package/dist/packages/core/src/web3/aggregator/providers/TestnetSwapProvider.js +65 -0
  45. package/dist/packages/core/src/web3/aggregator/routeSelector.js +7 -1
  46. package/dist/packages/core/src/web3/plugins/Web3DefiPlugin.js +1 -1
  47. package/dist/packages/core/src/web3/plugins/Web3MarketPlugin.js +5 -125
  48. package/dist/packages/core/src/web3/plugins/Web3SecurityPlugin.js +1 -1
  49. package/dist/packages/core/src/web3/plugins/Web3WalletPlugin.js +1 -1
  50. package/dist/packages/core/src/web3/skills/bridgeToken.js +19 -4
  51. package/dist/packages/core/src/web3/skills/checkAddress.js +2 -0
  52. package/dist/packages/core/src/web3/skills/checkPortfolio.js +22 -2
  53. package/dist/packages/core/src/web3/skills/checkSecurity.js +2 -0
  54. package/dist/packages/core/src/web3/skills/confirmPendingTx.js +1 -1
  55. package/dist/packages/core/src/web3/skills/createLimitOrder.js +15 -1
  56. package/dist/packages/core/src/web3/skills/customTx.js +3 -0
  57. package/dist/packages/core/src/web3/skills/defiLending.js +2 -0
  58. package/dist/packages/core/src/web3/skills/getBalance.js +2 -0
  59. package/dist/packages/core/src/web3/skills/getPrice.js +134 -27
  60. package/dist/packages/core/src/web3/skills/getTxHistory.js +2 -0
  61. package/dist/packages/core/src/web3/skills/marketAnalysis.js +28 -191
  62. package/dist/packages/core/src/web3/skills/mintNft.js +3 -0
  63. package/dist/packages/core/src/web3/skills/provideLiquidity.js +16 -12
  64. package/dist/packages/core/src/web3/skills/revokeApprovals.js +2 -0
  65. package/dist/packages/core/src/web3/skills/swapToken.js +20 -2
  66. package/dist/packages/core/src/web3/skills/transfer.js +2 -0
  67. package/dist/packages/core/src/web3/skills/yieldVault.js +2 -0
  68. package/dist/packages/core/src/web3/utils/chains.js +19 -0
  69. package/dist/packages/core/src/web3/utils/marketEngine.js +26 -33
  70. package/dist/packages/signer/src/NyxoraSigner.js +181 -0
  71. package/dist/packages/signer/src/index.js +17 -0
  72. package/dist/packages/signer/src/server.js +25 -161
  73. package/launcher.ts +38 -9
  74. package/package.json +6 -2
  75. package/packages/core/package.json +21 -10
  76. package/packages/core/src/agent/bridgeWatcher.ts +3 -2
  77. package/packages/core/src/agent/cronManager.ts +2 -2
  78. package/packages/core/src/agent/llmProvider.ts +219 -0
  79. package/packages/core/src/agent/nyxDaemon.ts +104 -0
  80. package/packages/core/src/agent/osAgent.ts +230 -32
  81. package/packages/core/src/agent/reasoning.ts +376 -64
  82. package/packages/core/src/agent/reasoningScratchpad.ts +45 -0
  83. package/packages/core/src/agent/transactionManager.ts +36 -28
  84. package/packages/core/src/agent/web3Agent.ts +291 -40
  85. package/packages/core/src/cognitive/cognitiveManager.ts +65 -10
  86. package/packages/core/src/cognitive/prompts/web3/market-analysis.md +24 -0
  87. package/packages/core/src/cognitive/prompts/web3/portfolio-review.md +29 -0
  88. package/packages/core/src/cognitive/prompts/web3/risk-assessment.md +28 -0
  89. package/packages/core/src/cognitive/prompts/web3/trade-planning.md +30 -0
  90. package/packages/core/src/config/parser.ts +15 -4
  91. package/packages/core/src/gateway/chat.ts +57 -15
  92. package/packages/core/src/gateway/cli.ts +4 -0
  93. package/packages/core/src/gateway/discordAdapter.ts +87 -0
  94. package/packages/core/src/gateway/server.ts +66 -10
  95. package/packages/core/src/gateway/setup-ml.ts +68 -0
  96. package/packages/core/src/gateway/setup.ts +41 -3
  97. package/packages/core/src/gateway/telegram.ts +138 -27
  98. package/packages/core/src/memory/episodic.ts +64 -3
  99. package/packages/core/src/memory/logger.ts +142 -2
  100. package/packages/core/src/memory/promotionEngine.ts +19 -5
  101. package/packages/core/src/system/agentskills.ts +10 -0
  102. package/packages/core/src/system/plugins/GoogleWorkspacePlugin.ts +1 -1
  103. package/packages/core/src/system/plugins/SystemCorePlugin.ts +1 -1
  104. package/packages/core/src/system/plugins/SystemExternalPlugin.ts +1 -1
  105. package/packages/core/src/system/plugins/SystemPluginInstallerPlugin.ts +1 -1
  106. package/packages/core/src/system/plugins/SystemSocialPlugin.ts +1 -1
  107. package/packages/core/src/system/plugins/SystemWebPlugin.ts +1 -1
  108. package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +3 -3
  109. package/packages/core/src/system/plugins/createSkill.ts +1 -1
  110. package/packages/core/src/system/skillExtractor.ts +16 -5
  111. package/packages/core/src/system/skills/forgetMemory.ts +7 -4
  112. package/packages/core/src/system/skills/scheduleTask.ts +7 -2
  113. package/packages/core/src/utils/contextSummarizer.ts +100 -0
  114. package/packages/core/src/utils/skillManager.ts +1 -1
  115. package/packages/core/src/utils/streamSimulator.ts +88 -0
  116. package/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.ts +30 -11
  117. package/packages/core/src/web3/aggregator/providers/OpBridgeProvider.ts +43 -29
  118. package/packages/core/src/web3/aggregator/routeSelector.ts +6 -1
  119. package/packages/core/src/web3/plugins/Web3DefiPlugin.ts +1 -1
  120. package/packages/core/src/web3/plugins/Web3MarketPlugin.ts +6 -125
  121. package/packages/core/src/web3/plugins/Web3SecurityPlugin.ts +1 -1
  122. package/packages/core/src/web3/plugins/Web3WalletPlugin.ts +1 -1
  123. package/packages/core/src/web3/skills/bridgeToken.ts +21 -7
  124. package/packages/core/src/web3/skills/checkAddress.ts +2 -0
  125. package/packages/core/src/web3/skills/checkPortfolio.ts +23 -2
  126. package/packages/core/src/web3/skills/checkSecurity.ts +2 -0
  127. package/packages/core/src/web3/skills/confirmPendingTx.ts +1 -1
  128. package/packages/core/src/web3/skills/createLimitOrder.ts +17 -2
  129. package/packages/core/src/web3/skills/customTx.ts +3 -0
  130. package/packages/core/src/web3/skills/defiLending.ts +2 -0
  131. package/packages/core/src/web3/skills/getBalance.ts +2 -0
  132. package/packages/core/src/web3/skills/getPrice.ts +134 -30
  133. package/packages/core/src/web3/skills/getTxHistory.ts +2 -0
  134. package/packages/core/src/web3/skills/marketAnalysis.ts +45 -188
  135. package/packages/core/src/web3/skills/mintNft.ts +3 -0
  136. package/packages/core/src/web3/skills/provideLiquidity.ts +16 -10
  137. package/packages/core/src/web3/skills/revokeApprovals.ts +2 -0
  138. package/packages/core/src/web3/skills/swapToken.ts +20 -3
  139. package/packages/core/src/web3/skills/transfer.ts +2 -0
  140. package/packages/core/src/web3/skills/yieldVault.ts +2 -0
  141. package/packages/core/src/web3/utils/chains.ts +12 -0
  142. package/packages/core/src/web3/utils/marketEngine.ts +27 -33
  143. package/packages/dashboard/dist/assets/index-BTfp141V.js +18 -0
  144. package/packages/dashboard/dist/assets/index-DK2sTU47.css +1 -0
  145. package/packages/dashboard/dist/index.html +2 -2
  146. package/packages/dashboard/package.json +10 -10
  147. package/packages/mcp-server/dist/server.js +5 -1
  148. package/packages/mcp-server/package.json +6 -6
  149. package/packages/mcp-server/src/server.ts +11 -7
  150. package/packages/policy/package.json +3 -3
  151. package/packages/signer/package.json +16 -6
  152. package/packages/signer/src/NyxoraSigner.ts +161 -0
  153. package/packages/signer/src/index.ts +1 -0
  154. package/packages/signer/src/server.ts +25 -135
  155. package/dist/packages/core/src/agent/honchoDaemon.js +0 -91
  156. package/dist/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -54
  157. package/dist/packages/core/src/gateway/test.js +0 -15
  158. package/dist/packages/core/src/web3/Web3DefiPlugin.js +0 -28
  159. package/dist/packages/core/src/web3/aggregator/aggregatorMainnet.js +0 -260
  160. package/dist/packages/core/src/web3/aggregator/aggregatorTestnet.js +0 -119
  161. package/dist/packages/core/src/web3/skills/nativeOpBridge.js +0 -71
  162. package/packages/core/src/agent/honchoDaemon.ts +0 -96
  163. package/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -41
  164. package/packages/core/src/plugin/registry.test.ts +0 -46
  165. package/packages/core/src/utils/formatter.test.ts +0 -41
  166. package/packages/dashboard/dist/assets/index-CSoNa5cx.css +0 -1
  167. package/packages/dashboard/dist/assets/index-DbRWEoSr.js +0 -16
@@ -0,0 +1 @@
1
+ :root{--bg-color:#3b4252;--bg-secondary:#434c5e;--bg-sidebar:#2e3440;--text-primary:#eceff4;--text-secondary:#d8dee9;--accent:#88c0d0;--accent-hover:#81a1c1;--glass-bg:#2e3440b3;--glass-border:#d8dee91a;--chat-user:#88c0d0;--chat-user-text:#2e3440;--chat-agent:#2e3440;--tool-bg:#4c566a;--success:#a3be8c;--danger:#bf616a;--terminal-bg:#1e222a;--btn-primary-bg:#81a1c1}body.light-theme{--bg-color:#fdfbf6;--bg-secondary:#f4f1e1;--bg-sidebar:#fdfbf6;--text-primary:#1a2b2b;--text-secondary:#5c6b6b;--accent:#8a9a86;--accent-hover:#72826e;--glass-bg:#fdfbf6cc;--glass-border:#1a2b2b14;--chat-user:#eef0e5;--chat-user-text:#1a2b2b;--chat-agent:#fff;--tool-bg:#f4f1e1;--success:#6b8e23;--danger:#cd5c5c;--terminal-bg:#eef0e5;--nav-text:var(--text-secondary);--nav-section:var(--text-secondary);--btn-primary-bg:var(--text-secondary)}*{box-sizing:border-box;margin:0;padding:0}body{background-color:var(--bg-color);color:var(--text-primary);height:100vh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;overflow:hidden}.settings-menu-item{cursor:pointer;color:var(--text-secondary);border-radius:6px;align-items:center;gap:12px;margin-bottom:4px;padding:8px 12px;font-size:.9rem;transition:all .2s;display:flex}.settings-menu-item:hover{color:var(--text-primary);background:#ffffff0d}.settings-menu-item.active{background:var(--accent);color:var(--bg-secondary);font-weight:500}.settings-menu-item.active svg{color:var(--bg-secondary)}.settings-scroll-container::-webkit-scrollbar{width:6px}.settings-scroll-container::-webkit-scrollbar-track{background:0 0}.settings-scroll-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:10px}#root{width:100vw;height:100vh;display:flex}.sidebar{background-color:var(--bg-sidebar);border-right:1px solid var(--glass-border);z-index:100;flex-direction:column;width:280px;display:flex;overflow-x:hidden}.agent-identity-card{background:linear-gradient(#3b82f60d 0%,#0000 100%);border-bottom:1px solid #ffffff0d;align-items:center;gap:16px;margin-bottom:8px;padding:24px;display:flex}.agent-avatar{justify-content:center;align-items:center;display:flex}.agent-info{flex-direction:column;gap:4px;display:flex}.agent-name{color:var(--text-primary);letter-spacing:-.025em;font-size:1.1rem;font-weight:700}.agent-status{color:#4ade80;letter-spacing:.05em;align-items:center;gap:6px;font-size:.75rem;font-weight:600;display:flex}.status-dot{background-color:#4ade80;border-radius:50%;width:8px;height:8px;animation:2s infinite pulse-green;box-shadow:0 0 8px #4ade80}@keyframes pulse-green{0%{transform:scale(.95);box-shadow:0 0 #4ade80b3}70%{transform:scale(1);box-shadow:0 0 0 6px #4ade8000}to{transform:scale(.95);box-shadow:0 0 #4ade8000}}.sidebar-scroll-area{flex:1;padding-bottom:24px;overflow:hidden auto}.sidebar-scroll-area::-webkit-scrollbar{width:4px}.sidebar-scroll-area::-webkit-scrollbar-thumb{background:#ffffff0d}body.light-theme .sidebar-scroll-area::-webkit-scrollbar-thumb{background:#00000026}.sidebar-section{color:var(--nav-section,#8b9bb4);padding:24px 24px 8px;font-size:.75rem;font-weight:500}.sidebar-nav{flex-direction:column;gap:4px;padding:0 16px;display:flex}.nav-item{color:var(--nav-text,#94a3b8);cursor:pointer;border:1px solid #0000;border-radius:8px;align-items:center;gap:10px;padding:8px 12px;font-size:.8rem;font-weight:500;transition:all .25s cubic-bezier(.4,0,.2,1);display:flex}.nav-icon{transition:transform .25s cubic-bezier(.4,0,.2,1)}.nav-item:hover{color:var(--text-primary);background-color:#ffffff08;transform:translate(4px)}.nav-item:hover .nav-icon{color:var(--text-primary);transform:scale(1.1)}.sessions-list{flex:none!important;justify-content:flex-start!important;gap:0!important;height:max-content!important}.session-item{justify-content:space-between;flex:none!important;height:max-content!important;min-height:28px!important;margin-top:0!important;margin-bottom:2px!important;padding:4px 10px!important}.delete-session-btn{color:#bf616a;cursor:pointer;opacity:0;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:4px;transition:opacity .2s,transform .2s;display:flex}.delete-session-btn:hover{background:#bf616a33;transform:scale(1.1)}.session-item:hover .delete-session-btn{opacity:1}.nav-item.active{color:var(--text-primary);border-left:3px solid var(--accent);background:linear-gradient(90deg,#3b82f626 0%,#0000 100%);border-radius:4px 12px 12px 4px;font-weight:600}.nav-item.active .nav-icon{color:var(--accent)}.main-content{background-image:radial-gradient(at 0 0,#3b82f61a 0,#0000 50%),radial-gradient(at 100% 100%,#8b5cf61a 0,#0000 50%);flex-direction:column;flex:1;max-width:100vw;display:flex;overflow-x:hidden}.topbar{border-bottom:1px solid var(--glass-border);background:var(--bg-color);justify-content:space-between;align-items:center;height:64px;padding:0 24px;display:flex}.topbar-left{color:var(--text-secondary);align-items:center;gap:16px;font-size:.95rem;font-weight:500;display:flex}.topbar-right{align-items:center;gap:12px;display:flex}.custom-network-selector{position:relative}.network-selector-pill{background-color:var(--accent);color:#000;cursor:pointer;border:none;border-radius:9999px;outline:none;align-items:center;gap:8px;padding:8px 16px;font-family:inherit;font-size:.85rem;font-weight:600;transition:all .2s;display:flex}.network-selector-pill:hover{opacity:.9;box-shadow:0 0 10px #88c0d066}.network-selector-pill:focus-visible{box-shadow:0 0 0 2px #88c0d080}.network-icon{flex-shrink:0}.network-chevron{opacity:.7;margin-left:4px}.network-dropdown-menu{background:var(--bg-secondary);border:1px solid var(--glass-border);z-index:100;border-radius:12px;min-width:180px;margin:0;padding:6px;list-style:none;animation:.2s ease-out dropdownSlideIn;position:absolute;top:calc(100% + 8px);right:0;box-shadow:0 12px 32px #00000080}@keyframes dropdownSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.network-dropdown-item{cursor:pointer;color:var(--text-primary);border-radius:8px;padding:10px 14px;font-size:.85rem;transition:background .1s}.network-dropdown-item:hover{background:var(--glass-border)}.network-dropdown-item.active{background:var(--bg-hover);color:var(--accent);font-weight:600}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.workspace-container{width:100%;height:calc(100vh - 64px);display:flex}.chat-wrapper{flex-direction:column;height:100%;padding:24px 0;display:flex}.chat-wrapper.empty-state-wrapper{justify-content:center;padding-bottom:10vh}.resizer{background:var(--glass-border);cursor:col-resize;z-index:10;width:6px;transition:background .2s}.resizer:hover,.resizer:active{background:var(--accent)}.canvas-panel{background:var(--bg-sidebar);background-image:radial-gradient(#3b82f60d 0,#0000 80%);flex-direction:column;flex:1;padding:32px;display:flex;position:relative;overflow-y:auto}.canvas-panel::-webkit-scrollbar{width:6px}.canvas-panel::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}body.light-theme .canvas-panel::-webkit-scrollbar-thumb{background:#00000026}.canvas-header{border-bottom:1px solid #ffffff0d;justify-content:space-between;align-items:center;margin-bottom:32px;padding-bottom:16px;display:flex}.canvas-title{color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;align-items:center;gap:8px;font-family:monospace;font-size:.85rem;display:flex}.canvas-empty{color:#475569;flex-direction:column;justify-content:center;align-items:center;gap:16px;height:100%;display:flex}.empty-state-title{color:#fff}body.light-theme .empty-state-title{background:linear-gradient(135deg,#1e293b 0%,#475569 100%);-webkit-text-fill-color:transparent;-webkit-background-clip:text}.chat-container{flex-direction:column;flex:1;gap:20px;padding:0 24px;display:flex;overflow-y:auto}.chat-container::-webkit-scrollbar{width:6px}.chat-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}.styled-scroll{scroll-behavior:smooth;-webkit-overflow-scrolling:touch;will-change:scroll-position}.styled-scroll::-webkit-scrollbar{width:6px}.styled-scroll::-webkit-scrollbar-track{background:0 0}.styled-scroll::-webkit-scrollbar-thumb{background:#fff3;border-radius:4px}.styled-scroll::-webkit-scrollbar-thumb:hover{background:#fff6}body.light-theme .chat-container::-webkit-scrollbar-thumb{background:#00000026}body.light-theme .styled-scroll::-webkit-scrollbar-thumb{background:#0003}body.light-theme .styled-scroll::-webkit-scrollbar-thumb:hover{background:#00000059}.message-wrapper{flex-direction:column;max-width:95%;animation:.3s ease-out forwards fadeIn;display:flex}.message-wrapper.agent{flex-direction:row;align-self:flex-start;align-items:flex-end;gap:8px}.message-wrapper.user{flex-direction:row-reverse;align-self:flex-end;align-items:flex-end;gap:8px}.copy-btn{color:var(--text-secondary);cursor:pointer;opacity:0;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:6px;transition:opacity .2s,background .2s;display:flex}.copy-btn:hover{background:var(--bg-secondary);color:var(--text-primary)}.message-wrapper:hover .copy-btn{opacity:1}.message-bubble{white-space:pre-wrap;word-break:break-word;overflow-wrap:break-word;border-radius:18px;padding:14px 18px;font-size:.95rem;line-height:1.6;box-shadow:0 4px 6px -1px #0000001a}.user .message-bubble{background-color:var(--chat-user);color:var(--chat-user-text);border-bottom-right-radius:4px}.agent .message-bubble{background-color:var(--chat-agent);border:1px solid var(--glass-border);color:var(--text-primary);border-bottom-left-radius:4px}.tool-call{color:var(--text-secondary);background:var(--tool-bg);border:1px solid var(--glass-border);border-radius:12px;align-items:center;gap:8px;margin-top:10px;padding:10px 14px;font-size:.85rem;display:flex}.tool-call code{color:var(--accent);font-family:monospace}.input-area{padding:20px 24px 0}.input-form{background:var(--bg-secondary);border:1px solid var(--glass-border);border-radius:24px;align-items:flex-end;gap:8px;width:100%;max-width:900px;margin:0 auto;padding:10px 14px;transition:all .2s;display:flex;box-shadow:0 4px 15px #0000001a}.input-form:focus-within{border-color:var(--accent);box-shadow:0 0 0 2px #3b82f633}.chat-input{color:var(--text-primary);background:0 0;border:none;outline:none;flex:1;padding:8px 12px;font-family:inherit;font-size:.95rem}.send-button{background:var(--accent);color:var(--text-primary);cursor:pointer;border:none;border-radius:50%;justify-content:center;align-items:center;width:36px;height:36px;transition:all .2s;display:flex}.voice-button{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;border-radius:50%;justify-content:center;align-items:center;width:36px;height:36px;transition:all .2s;display:flex}.voice-button:hover{color:var(--text-primary);border-color:#ef4444}.action-menu-container{background:0 0;border-radius:9999px;align-items:center;margin-right:8px;padding:0;transition:all .3s cubic-bezier(.4,0,.2,1);display:flex;position:relative;overflow:hidden}.action-menu-container:hover{background:var(--bg-secondary)}.action-menu-items{opacity:0;pointer-events:none;align-items:center;gap:4px;width:0;transition:all .3s cubic-bezier(.4,0,.2,1);display:flex;transform:translate(-10px)}.action-menu-container:hover .action-menu-items{opacity:1;pointer-events:auto;width:76px;margin-left:4px;margin-right:4px;transform:translate(0)}.plus-button{z-index:2;background:0 0;border:none;transition:transform .3s}.action-menu-container:hover .plus-button{color:var(--accent);transform:rotate(45deg)}.action-menu-items .voice-button{background:0 0;border:none;width:32px;height:32px}.action-menu-items .voice-button:hover{background:#ffffff1a;border-color:#0000}.voice-button.listening{color:#ef4444;background:#ef444433;border-color:#ef4444;animation:1.5s infinite pulse-red}.voice-button.active-mode{color:#3b82f6;border-color:#3b82f6}.voice-button.speaking{color:#3b82f6;background:#3b82f633;border-color:#3b82f6;animation:1.5s infinite pulse-blue}@keyframes pulse-red{0%{box-shadow:0 0 #ef444466}70%{box-shadow:0 0 0 10px #ef444400}to{box-shadow:0 0 #ef444400}}@keyframes pulse-blue{0%{box-shadow:0 0 #3b82f666}70%{box-shadow:0 0 0 10px #3b82f600}to{box-shadow:0 0 #3b82f600}}.send-button:hover:not(:disabled){background:var(--accent-hover);transform:scale(1.05)}.send-button:disabled{opacity:.5;cursor:not-allowed}.typing-indicator{background-color:var(--chat-agent);border:1px solid var(--glass-border);border-radius:18px 18px 18px 4px;align-self:flex-start;gap:4px;width:fit-content;padding:14px 18px;display:flex}.dot{background:var(--text-secondary);border-radius:50%;width:6px;height:6px;animation:1.4s ease-in-out infinite both bounce}.dot:first-child{animation-delay:-.32s}.dot:nth-child(2){animation-delay:-.16s}@keyframes bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.prompt-suggestions{gap:12px;margin-bottom:12px;display:flex;overflow-x:auto}.prompt-suggestions button{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;white-space:nowrap;border-radius:20px;padding:8px 16px;font-size:.85rem;transition:all .2s}.prompt-suggestions button:hover{border-color:var(--accent);color:var(--text-primary)}.trending-tokens{color:var(--text-secondary);justify-content:center;align-items:center;gap:12px;margin-top:12px;font-size:.8rem;display:flex}.token-tag{background:var(--accent);color:var(--bg-color);cursor:pointer;border-radius:12px;padding:4px 10px;font-weight:600;transition:transform .2s,filter .2s}.token-tag:hover{filter:brightness(1.2);transform:translateY(-2px)}.nord-label{color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px;font-size:.75rem;font-weight:700;display:block}.nord-pill-input{background-color:var(--glass-bg);border:1px solid var(--glass-border);width:100%;color:var(--accent);border-radius:9999px;outline:none;padding:10px 20px;font-size:.9rem;font-weight:600;transition:all .2s}.nord-pill-input:focus{border-color:var(--accent);box-shadow:0 0 10px var(--accent)}.nord-pill-input::placeholder{color:var(--text-secondary);opacity:.7}.nord-input{background-color:var(--bg-sidebar);border:1px solid var(--glass-border);width:100%;color:var(--text-primary);border-radius:6px;outline:none;padding:10px 14px;font-size:.9rem;transition:all .2s}.nord-input:focus{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent)}.nord-input::placeholder{color:var(--text-secondary);opacity:.7}.nord-slider{appearance:none;background:var(--tool-bg);border-radius:3px;outline:none;width:100%;height:6px;margin-top:10px}.nord-slider::-webkit-slider-thumb{appearance:none;background:var(--text-primary);cursor:pointer;border:2px solid var(--accent);border-radius:50%;width:18px;height:18px;transition:all .2s}.nord-slider::-webkit-slider-thumb:hover{background:#fff;transform:scale(1.1)}.nord-slider::-moz-range-thumb{background:var(--text-primary);cursor:pointer;border:2px solid var(--accent);border-radius:50%;width:18px;height:18px;transition:all .2s}.nord-btn-primary{background-color:var(--btn-primary-bg);color:var(--bg-sidebar);cursor:pointer;border:none;border-radius:6px;justify-content:center;align-items:center;padding:10px 20px;font-size:.9rem;font-weight:600;transition:background-color .2s;display:flex}.nord-btn-primary:hover{background-color:var(--accent)}.nord-btn-primary:disabled{background-color:var(--tool-bg);color:#8fbcbb;cursor:not-allowed}.nord-panel-header{border-bottom:1px solid var(--glass-border);align-items:center;gap:10px;margin-bottom:20px;padding-bottom:12px;display:flex}.nord-panel-header h3{color:var(--text-primary);margin:0;font-size:1.1rem;font-weight:600}.sidebar.collapsed{width:68px}.nav-label,.agent-info,.sidebar-section,.delete-session-btn,.agent-avatar,.sessions-list,.agent-identity-card,.sidebar-nav,.nav-item{white-space:nowrap;transition:all .3s cubic-bezier(.4,0,.2,1)}.sidebar.collapsed .nav-label,.sidebar.collapsed .agent-info,.sidebar.collapsed .sidebar-section,.sidebar.collapsed .delete-session-btn,.sidebar.collapsed .agent-avatar,.sidebar.collapsed .sessions-list{opacity:0!important;width:0!important;min-width:0!important;height:0!important;min-height:0!important;margin:0!important;padding:0!important;overflow:hidden!important}.sidebar.collapsed .agent-identity-card{justify-content:center;border-bottom-color:#0000!important;gap:0!important;min-height:60px!important;margin-bottom:0!important;padding:16px 0 4px!important}.sidebar.collapsed .sidebar-toggle-btn{border-radius:50%;margin-top:0;padding:8px;position:static!important}.sidebar.collapsed .sidebar-toggle-btn:hover{background-color:#ffffff0d!important}.sidebar.collapsed .sidebar-nav{align-items:center;gap:2px!important;padding:4px 0 0!important}.sidebar.collapsed .nav-item{justify-content:center;border-width:0!important;border-color:#0000!important;border-radius:50%!important;gap:0!important;width:36px!important;height:36px!important;margin:0 auto!important;padding:0!important}.sidebar.collapsed .nav-item.active{background:#3b82f633!important;border-width:0!important;border-color:#0000!important}.sidebar.collapsed .session-item{border-radius:50%}.sidebar.collapsed .nav-item .nav-icon{margin:0}.spinner{color:var(--text-secondary);animation:1s linear infinite spin}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.overview-container{height:calc(100vh - 64px);color:var(--text-primary);scroll-behavior:smooth;-webkit-overflow-scrolling:touch;will-change:scroll-position;padding:24px;font-family:Inter,sans-serif;overflow-y:auto}.settings-subpanel{width:100%;color:var(--text-primary);font-family:Inter,sans-serif}.overview-container::-webkit-scrollbar{width:6px}.overview-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}body.light-theme .overview-container::-webkit-scrollbar-thumb{background:#00000026}.overview-header h1{margin-bottom:4px;font-size:1.5rem;font-weight:600}.overview-header p{color:var(--text-secondary);margin-bottom:24px;font-size:.9rem}.panel{background:var(--bg-secondary);border:1px solid var(--glass-border);border-radius:12px;margin-bottom:24px;padding:20px}.panel-header h3{margin-bottom:4px;font-size:1.1rem;font-weight:600}.panel-header p{color:var(--text-secondary);margin-bottom:16px;font-size:.85rem}.form-group{margin-bottom:16px}.form-row{gap:16px;display:flex}.flex-1{flex:1}label{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:8px;font-size:.75rem;display:block}input,select{background:var(--bg-color);border:1px solid var(--glass-border);width:100%;color:var(--text-primary);border-radius:8px;padding:10px 12px;font-family:monospace;font-size:.9rem}input:read-only{color:var(--text-secondary)}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon svg{color:var(--text-secondary);cursor:pointer;position:absolute;right:12px}.form-actions{align-items:center;gap:12px;margin-top:20px;display:flex}.btn-primary{color:var(--text-primary);cursor:pointer;background:#3b82f6;border:none;border-radius:6px;padding:8px 16px;font-size:.9rem}.btn-secondary{color:var(--text-primary);cursor:pointer;background:0 0;border:1px solid #fff3;border-radius:6px;padding:8px 16px;font-size:.9rem}.action-hint{color:var(--text-secondary);margin-left:8px;font-size:.85rem}.snapshot-grid{grid-template-columns:repeat(4,1fr);gap:20px;display:grid}.stat-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.text-green{color:#22c55e}.stat-block p{color:var(--text-secondary);margin-top:8px;font-size:.8rem;line-height:1.4}.metrics-grid{grid-template-columns:repeat(5,1fr);gap:16px;margin-bottom:32px;display:grid}.metric-card{background:var(--bg-secondary);border:1px solid var(--glass-border);border-radius:12px;padding:16px}.metric-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.metric-sub{color:var(--text-secondary);font-size:.75rem}.section-title{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:12px;font-size:.75rem}.session-item{justify-content:space-between;margin-bottom:24px;padding:16px 20px;display:flex}.text-secondary{color:var(--text-secondary)}.attention-panel{background:#eab3081a;border:1px solid #eab30833;border-radius:12px;flex-direction:column;margin-bottom:24px;padding:16px 20px;display:flex}.attention-header{color:#eab308;align-items:center;gap:8px;margin-bottom:8px;display:flex}.attention-header h4{font-size:1rem;font-weight:600}.attention-content p{margin-bottom:4px;font-size:.95rem}.attention-content span{font-size:.85rem}.logs-grid{grid-template-columns:1fr 1fr;gap:16px;display:grid}.log-panel{background:var(--terminal-bg);border:1px solid var(--glass-border);border-radius:12px;flex-direction:column;height:300px;display:flex;overflow:hidden}.log-header{background:var(--glass-border);border-bottom:1px solid var(--glass-border);padding:12px 16px;font-size:.85rem;font-weight:600}.badge{background:#ffffff1a;border-radius:10px;margin-left:8px;padding:2px 6px;font-size:.7rem}.log-content{flex-direction:column;gap:4px;padding:12px 16px;display:flex;overflow:auto}.log-content::-webkit-scrollbar{width:6px;height:6px}.log-content::-webkit-scrollbar-thumb{background:var(--glass-border);border-radius:4px}.log-content::-webkit-scrollbar-thumb:hover{background:var(--glass-border)}.log-content::-webkit-scrollbar-corner{background:0 0}.memory-log-container::-webkit-scrollbar{width:6px;height:6px}.memory-log-container::-webkit-scrollbar-thumb{background:var(--glass-border);border-radius:4px}.memory-log-container::-webkit-scrollbar-thumb:hover{background:var(--glass-border)}.memory-log-container::-webkit-scrollbar-corner{background:0 0}.log-content code,.log-json{color:#a3a3a3;word-break:break-all;font-family:Consolas,Monaco,monospace;font-size:.75rem;line-height:1.4}.log-row{gap:12px;margin-bottom:4px;font-family:Consolas,Monaco,monospace;font-size:.75rem;display:flex}.log-time{color:#fb923c;min-width:60px}.log-msg{color:#d1d5db}.log-meta{color:#6b7280}.gateway-row{margin-bottom:2px}.search-chat-container{flex-direction:column;width:100%;max-width:800px;margin:0 auto;padding:40px 20px;animation:.3s ease-out fadeIn;display:flex}.search-chat-header{justify-content:center;margin-bottom:40px;display:flex}.search-input-wrapper{width:100%;max-width:600px;position:relative}.search-icon{color:var(--text-secondary);position:absolute;top:50%;left:20px;transform:translateY(-50%)}.search-input{border:1px solid var(--glass-border);background:var(--bg-sidebar);width:100%;color:var(--text-primary);border-radius:30px;outline:none;padding:16px 20px 16px 50px;font-size:1.1rem;transition:all .2s;box-shadow:0 4px 20px #0000000d}.search-input:focus{border-color:var(--accent);background:var(--bg-color);box-shadow:0 4px 25px #0000001a}.search-results-area{flex-direction:column;display:flex}.search-results-title{color:var(--text-secondary);margin-bottom:16px;padding-left:8px;font-size:.9rem;font-weight:500}.search-result-item{cursor:pointer;border-radius:12px;align-items:center;padding:16px;transition:background-color .2s;display:flex}.search-result-item:hover{background-color:var(--bg-sidebar)}.result-title{color:var(--text-primary);align-items:center;gap:12px;font-size:1rem;display:flex}.result-icon{color:var(--text-secondary)}.search-no-results{text-align:center;color:var(--text-secondary);padding:40px;font-style:italic}.login-container{background-color:var(--bg-color,#1e222a);background-image:linear-gradient(#ffffff08 1px,#0000 1px),linear-gradient(90deg,#ffffff08 1px,#0000 1px),radial-gradient(circle,#3b82f626,#0000 60%);background-size:40px 40px,40px 40px,100% 100%;justify-content:center;align-items:center;width:100vw;height:100vh;display:flex;overflow:hidden}.login-card{-webkit-backdrop-filter:blur(16px);background:#1e222a99;border:1px solid #ffffff14;border-radius:16px;flex-direction:column;width:420px;animation:.4s ease-out fadeInScale;display:flex;overflow:hidden;box-shadow:0 25px 50px -12px #00000080}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.login-card-header{background:#0003;border-bottom:1px solid #ffffff0d;align-items:center;gap:8px;height:38px;padding:0 16px;display:flex}.mac-dot{border-radius:50%;width:12px;height:12px}.mac-dot.red{background-color:#ff5f56}.mac-dot.yellow{background-color:#ffbd2e}.mac-dot.green{background-color:#27c93f}.login-card-body{flex-direction:column;align-items:center;padding:40px 32px 48px;display:flex}.login-logo{margin-bottom:12px;animation:4s ease-in-out infinite pulseLogo}@keyframes pulseLogo{0%{filter:drop-shadow(0 0 8px #a3be8c4d)}50%{filter:drop-shadow(0 0 16px #a3be8cb3)}to{filter:drop-shadow(0 0 8px #a3be8c4d)}}.login-title{color:var(--text-primary);margin-bottom:4px;font-size:1.5rem;font-weight:600}.login-subtitle{color:var(--text-secondary);text-align:center;margin-bottom:32px;font-size:.9rem}.login-form{flex-direction:column;gap:16px;width:100%;display:flex}.login-input-group{width:100%;position:relative}.login-input{border:1px solid var(--glass-border);width:100%;color:var(--text-primary);box-sizing:border-box;background:#0000004d;border-radius:24px;outline:none;padding:14px 16px 14px 44px;font-size:1rem;transition:all .2s}.login-input:focus{border-color:var(--accent);box-shadow:0 0 0 2px #a3be8c33}.login-input-icon{color:var(--text-secondary);pointer-events:none;position:absolute;top:50%;left:16px;transform:translateY(-50%)}.login-button{background-color:var(--accent);color:#1e222a;cursor:pointer;border:none;border-radius:24px;justify-content:center;align-items:center;gap:8px;width:100%;padding:14px;font-size:1rem;font-weight:600;transition:all .2s;display:flex}.login-button:hover:not(:disabled){background-color:#b4cf9a;transform:translateY(-1px)}.login-button:disabled{opacity:.7;cursor:not-allowed}.login-error{color:#bf616a;text-align:center;min-height:20px;margin-top:12px;font-size:.85rem}.login-hint{color:var(--text-secondary);text-align:center;opacity:.6;margin-top:24px;font-size:.75rem}body.light-theme .login-card{background:var(--glass-bg);border-color:var(--glass-border);box-shadow:0 25px 50px -12px #00000026}body.light-theme .login-card-header{border-bottom-color:var(--glass-border);background:#0000000d}body.light-theme .login-input{background:#00000008}body.light-theme .login-button{color:#fff}
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Nyxora Dashboard</title>
8
- <script type="module" crossorigin src="/assets/index-DbRWEoSr.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-CSoNa5cx.css">
8
+ <script type="module" crossorigin src="/assets/index-BTfp141V.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-DK2sTU47.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nyxora-dashboard",
3
3
  "private": true,
4
- "version": "26.7.2",
4
+ "version": "26.7.3",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -9,18 +9,18 @@
9
9
  "preview": "vite preview"
10
10
  },
11
11
  "dependencies": {
12
- "lucide-react": "^0.474.0",
12
+ "lucide-react": "^1.22.0",
13
13
  "react": "^18.3.1",
14
14
  "react-dom": "^18.3.1",
15
- "viem": "^2.51.0"
15
+ "viem": "^2.53.1"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/node": "^22.0.0",
19
- "@types/react": "^18.3.3",
20
- "@types/react-dom": "^18.3.0",
21
- "@vitejs/plugin-react": "^6.0.2",
22
- "globals": "^17.6.0",
23
- "typescript": "~6.0.2",
24
- "vite": "^8.0.16"
18
+ "@types/node": "^26.0.1",
19
+ "@types/react": "^18.3.31",
20
+ "@types/react-dom": "^18.3.7",
21
+ "@vitejs/plugin-react": "^6.0.3",
22
+ "globals": "^17.7.0",
23
+ "typescript": "~6.0.3",
24
+ "vite": "^8.1.0"
25
25
  }
26
26
  }
@@ -96,9 +96,13 @@ server.tool("get_wallet_address", "Fetch the secure Ethereum wallet address mana
96
96
  server.tool("request_transaction", "Request an EVM transaction (transfer, swap, bridge). This will be evaluated by the Policy Engine. If approved, it returns a pending Transaction ID.", {
97
97
  type: zod_1.z.enum(['transfer', 'swap', 'bridge', 'mint', 'custom']).describe("The type of transaction"),
98
98
  chainName: zod_1.z.string().describe("The target blockchain network (e.g. 'ethereum', 'base', 'arbitrum')"),
99
- details: zod_1.z.any().describe("Detailed payload. For 'transfer': { to: string, amountWei: string }. For 'swap': { tokenIn: string, tokenOut: string, amountInWei: string }.")
99
+ details: zod_1.z.string().describe("JSON string payload. For 'transfer': { to: string, amountWei: string }. For 'swap': { tokenIn: string, tokenOut: string, amountInWei: string }.")
100
100
  }, async (args) => {
101
101
  try {
102
+ // Parse details back to object since it's passed as string
103
+ if (typeof args.details === 'string') {
104
+ args.details = JSON.parse(args.details);
105
+ }
102
106
  const response = await callPolicyEngine('/request-tx', 'POST', args);
103
107
  return {
104
108
  content: [{ type: "text", text: `Transaction requested successfully. Transaction ID: ${response.id}. Status: ${response.status}` }]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nyxora-mcp-server",
3
- "version": "26.7.2",
3
+ "version": "26.7.3",
4
4
  "description": "Nyxora MCP Subserver, for external AI clients",
5
5
  "main": "dist/server.js",
6
6
  "scripts": {
@@ -10,12 +10,12 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/sdk": "^1.29.0",
13
- "jsonwebtoken": "^9.0.2",
14
- "zod": "^3.24.2"
13
+ "jsonwebtoken": "^9.0.3",
14
+ "zod": "^4.4.3"
15
15
  },
16
16
  "devDependencies": {
17
- "@types/jsonwebtoken": "^9.0.5",
18
- "@types/node": "^20.0.0",
19
- "typescript": "^5.0.0"
17
+ "@types/jsonwebtoken": "^9.0.10",
18
+ "@types/node": "^26.0.1",
19
+ "typescript": "^6.0.3"
20
20
  }
21
21
  }
@@ -90,12 +90,12 @@ server.tool(
90
90
  try {
91
91
  const response = await callPolicyEngine('/address', 'GET');
92
92
  return {
93
- content: [{ type: "text", text: `Wallet Address: ${response.address}` }]
93
+ content: [{ type: "text" as const, text: `Wallet Address: ${response.address}` }]
94
94
  };
95
95
  } catch (e: any) {
96
96
  return {
97
97
  isError: true,
98
- content: [{ type: "text", text: e.message }]
98
+ content: [{ type: "text" as const, text: e.message }]
99
99
  };
100
100
  }
101
101
  }
@@ -108,18 +108,22 @@ server.tool(
108
108
  {
109
109
  type: z.enum(['transfer', 'swap', 'bridge', 'mint', 'custom']).describe("The type of transaction"),
110
110
  chainName: z.string().describe("The target blockchain network (e.g. 'ethereum', 'base', 'arbitrum')"),
111
- details: z.any().describe("Detailed payload. For 'transfer': { to: string, amountWei: string }. For 'swap': { tokenIn: string, tokenOut: string, amountInWei: string }.")
112
- },
113
- async (args) => {
111
+ details: z.string().describe("JSON string payload. For 'transfer': { to: string, amountWei: string }. For 'swap': { tokenIn: string, tokenOut: string, amountInWei: string }.")
112
+ } as any,
113
+ async (args: any) => {
114
114
  try {
115
+ // Parse details back to object since it's passed as string
116
+ if (typeof args.details === 'string') {
117
+ args.details = JSON.parse(args.details);
118
+ }
115
119
  const response = await callPolicyEngine('/request-tx', 'POST', args);
116
120
  return {
117
- content: [{ type: "text", text: `Transaction requested successfully. Transaction ID: ${response.id}. Status: ${response.status}` }]
121
+ content: [{ type: "text" as const, text: `Transaction requested successfully. Transaction ID: ${response.id}. Status: ${response.status}` }]
118
122
  };
119
123
  } catch (e: any) {
120
124
  return {
121
125
  isError: true,
122
- content: [{ type: "text", text: `Transaction Request Failed! ${e.message}` }]
126
+ content: [{ type: "text" as const, text: `Transaction Request Failed! ${e.message}` }]
123
127
  };
124
128
  }
125
129
  }
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "nyxora-policy-engine",
3
- "version": "26.7.2",
3
+ "version": "26.7.3",
4
4
  "private": true,
5
5
  "main": "src/server.ts",
6
6
  "dependencies": {
7
7
  "@msgpack/msgpack": "^3.1.3",
8
8
  "chokidar": "^5.0.0",
9
9
  "express": "^5.2.1",
10
- "jsonwebtoken": "^9.0.2",
10
+ "jsonwebtoken": "^9.0.3",
11
11
  "yaml": "^2.9.0",
12
- "zod": "^3.24.2"
12
+ "zod": "^4.4.3"
13
13
  }
14
14
  }
@@ -1,12 +1,22 @@
1
1
  {
2
- "name": "nyxora-signer",
3
- "version": "26.7.2",
4
- "private": true,
5
- "main": "src/server.ts",
2
+ "name": "@nyxora-sdk/signer",
3
+ "version": "26.7.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc"
14
+ },
6
15
  "dependencies": {
7
16
  "@napi-rs/keyring": "^1.3.0",
8
17
  "express": "^5.2.1",
9
- "jsonwebtoken": "^9.0.2",
10
- "viem": "^2.51.0"
18
+ "jsonwebtoken": "^9.0.3",
19
+ "viem": "^2.21.0",
20
+ "typescript": "^5.0.0"
11
21
  }
12
22
  }
@@ -0,0 +1,161 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ import { Entry } from '@napi-rs/keyring';
5
+ import { privateKeyToAccount, PrivateKeyAccount } from 'viem/accounts';
6
+ import { createWalletClient, http, publicActions, WalletClient, PublicClient } from 'viem';
7
+ import * as chains from 'viem/chains';
8
+
9
+ export interface NyxoraSignerOptions {
10
+ customRpcUrls?: Record<string, string | string[]>;
11
+ }
12
+
13
+ export class NyxoraSigner {
14
+ private vaultPrivateKey: `0x${string}` | null = null;
15
+ private vaultAddress: string | null = null;
16
+ private account: PrivateKeyAccount | null = null;
17
+ private nonceLocks: Record<number, Promise<void>> = {};
18
+ private nonceCache: Record<number, number> = {};
19
+ private options: NyxoraSignerOptions;
20
+
21
+ constructor(options?: NyxoraSignerOptions) {
22
+ this.options = options || {};
23
+ }
24
+
25
+ public async unlock(): Promise<string | null> {
26
+ // 1. Try OS Keyring
27
+ try {
28
+ const entry = new Entry('nyxora', 'wallet');
29
+ const pk = await entry.getPassword();
30
+ if (pk) {
31
+ this.setPrivateKey(pk);
32
+ console.log(`✅ [Signer SDK] Vault unlocked securely from OS Keyring. Agent Address: ${this.vaultAddress}`);
33
+ return this.vaultAddress;
34
+ }
35
+ } catch (e) {
36
+ console.warn(`⚠️ [Signer SDK] OS Keyring failed (module mismatch or headless). Using fallback.`);
37
+ }
38
+
39
+ // 2. Fallback to vault.key
40
+ const vaultPath = path.join(os.homedir(), '.nyxora', 'auth', 'vault.key');
41
+ if (fs.existsSync(vaultPath)) {
42
+ const stats = fs.statSync(vaultPath);
43
+ const mode = stats.mode & 0o777;
44
+ if (os.platform() !== 'win32' && mode !== 0o600) {
45
+ throw new Error(`FATAL: Insecure permissions detected on vault.key. File permissions must be strictly 0600 (-rw-------). Current permissions: 0${mode.toString(8)}. Refusing to start.`);
46
+ }
47
+
48
+ const content = fs.readFileSync(vaultPath, 'utf8');
49
+ const match = content.match(/PRIVATE_KEY=(.+)/);
50
+ if (match && match[1]) {
51
+ this.setPrivateKey(match[1].trim());
52
+ console.log(`✅ [Signer SDK] Vault unlocked from vault.key fallback. Agent Address: ${this.vaultAddress}`);
53
+ return this.vaultAddress;
54
+ }
55
+ }
56
+
57
+ console.log(`❌ [Signer SDK] No Private Key found in OS Keyring or vault.key. Web3 features will fail.`);
58
+ return null;
59
+ }
60
+
61
+ public lock(): void {
62
+ console.log('[Signer SDK] Locking vault...');
63
+ this.vaultPrivateKey = null;
64
+ this.account = null;
65
+ this.vaultAddress = null;
66
+ }
67
+
68
+ public getAddress(): string | null {
69
+ return this.vaultAddress;
70
+ }
71
+
72
+ public isUnlocked(): boolean {
73
+ return this.vaultPrivateKey !== null;
74
+ }
75
+
76
+ private setPrivateKey(pk: string) {
77
+ this.vaultPrivateKey = pk.startsWith('0x') ? (pk as `0x${string}`) : (`0x${pk}` as `0x${string}`);
78
+ this.account = privateKeyToAccount(this.vaultPrivateKey);
79
+ this.vaultAddress = this.account.address;
80
+ }
81
+
82
+ private getChain(chainName: string) {
83
+ const normalized = chainName.toLowerCase().replace(/_/g, '-');
84
+ const normalizedSpace = chainName.toLowerCase().replace(/_/g, ' ');
85
+ // @ts-ignore
86
+ return Object.values(chains).find(c => c.name.toLowerCase() === normalizedSpace || c.name.toLowerCase() === normalized || (c as any).network === normalized) || chains.mainnet;
87
+ }
88
+
89
+ public async signTransaction(txPayload: any): Promise<string> {
90
+ if (!this.account || !this.vaultPrivateKey) {
91
+ throw new Error('Vault is locked. Unlock first.');
92
+ }
93
+ if (!txPayload || !txPayload.chainName) {
94
+ throw new Error('Invalid payload');
95
+ }
96
+
97
+ const chain = this.getChain(txPayload.chainName);
98
+
99
+ // Resolve Custom RPC
100
+ const customRpcRaw = this.options.customRpcUrls?.[txPayload.chainName.toLowerCase()];
101
+ let customRpc: string | undefined = undefined;
102
+ if (customRpcRaw) {
103
+ if (Array.isArray(customRpcRaw) && customRpcRaw.length > 0) customRpc = customRpcRaw[0];
104
+ else if (typeof customRpcRaw === 'string' && customRpcRaw.trim()) customRpc = customRpcRaw.trim();
105
+ }
106
+
107
+ const client = createWalletClient({
108
+ account: this.account,
109
+ chain,
110
+ transport: http(customRpc, { timeout: 15000 })
111
+ }).extend(publicActions);
112
+
113
+ const chainId = chain.id;
114
+
115
+ // Mutex lock for nonce management
116
+ if (!this.nonceLocks[chainId]) this.nonceLocks[chainId] = Promise.resolve();
117
+
118
+ return new Promise((resolve, reject) => {
119
+ this.nonceLocks[chainId] = this.nonceLocks[chainId].then(async () => {
120
+ try {
121
+ const rpcNonce = await client.getTransactionCount({ address: this.account!.address, blockTag: 'pending' });
122
+ let nextNonce = Math.max(rpcNonce, this.nonceCache[chainId] || 0);
123
+
124
+ const txRequest = txPayload.details?.txRequest || txPayload.details?.txData || txPayload;
125
+ const toAddress = txRequest.to || txRequest.target;
126
+ const txDataStr = txRequest.data || txRequest.calldata;
127
+ const txValue = txRequest.value ? BigInt(txRequest.value) : 0n;
128
+
129
+ // Phase 2: Transaction Simulation (Dry-Run / Anti-Fail)
130
+ try {
131
+ await client.estimateGas({
132
+ account: this.account!,
133
+ to: toAddress,
134
+ data: txDataStr,
135
+ value: txValue
136
+ });
137
+ } catch (simError: any) {
138
+ throw new Error(`Simulation failed: ${simError.shortMessage || simError.message}`);
139
+ }
140
+
141
+ // @ts-ignore
142
+ const hash = await client.sendTransaction({
143
+ account: this.account!,
144
+ to: toAddress,
145
+ data: txDataStr,
146
+ value: txValue,
147
+ nonce: nextNonce,
148
+ gas: txRequest.gas ? BigInt(txRequest.gas) : undefined,
149
+ maxFeePerGas: txRequest.maxFeePerGas ? BigInt(txRequest.maxFeePerGas) : undefined,
150
+ maxPriorityFeePerGas: txRequest.maxPriorityFeePerGas ? BigInt(txRequest.maxPriorityFeePerGas) : undefined,
151
+ });
152
+
153
+ this.nonceCache[chainId] = nextNonce + 1;
154
+ resolve(hash);
155
+ } catch (err: any) {
156
+ reject(err);
157
+ }
158
+ }).catch(reject);
159
+ });
160
+ }
161
+ }
@@ -0,0 +1 @@
1
+ export * from './NyxoraSigner';
@@ -1,15 +1,11 @@
1
- import { initSafeLogger } from '../../core/src/utils/safeLogger';
2
- import { loadConfig } from '../../core/src/config/parser';
3
- initSafeLogger();
1
+ // Removed safeLogger for standalone SDK server wrapper
4
2
 
5
3
  import express from 'express';
6
4
  import fs from 'fs';
7
5
  import path from 'path';
8
6
  import os from 'os';
9
7
  import jwt from 'jsonwebtoken';
10
- import { privateKeyToAccount } from 'viem/accounts';
11
- import { createWalletClient, http, publicActions } from 'viem';
12
- import * as chains from 'viem/chains';
8
+ import { NyxoraSigner } from './NyxoraSigner';
13
9
 
14
10
  process.on('unhandledRejection', (reason, promise) => {
15
11
  console.error('[Anti-Crash] Unhandled Rejection at:', promise, 'reason:', reason);
@@ -33,69 +29,25 @@ try {
33
29
  const app = express();
34
30
  app.use(express.json());
35
31
 
36
- import { Entry } from '@napi-rs/keyring';
37
-
38
- let vaultPrivateKey: `0x${string}` | null = null;
39
- let vaultAddress: string | null = null;
40
-
41
- // Auto-unlock from OS Keyring or fallback .env
42
- async function loadPrivateKey() {
32
+ // Simple local config parser to avoid depending on @nyxora/core
33
+ function getLocalConfig() {
43
34
  try {
44
- const entry = new Entry('nyxora', 'wallet');
45
- const pk = await entry.getPassword();
46
- if (pk) {
47
- vaultPrivateKey = pk.startsWith('0x') ? (pk as `0x${string}`) : (`0x${pk}` as `0x${string}`);
48
- const account = privateKeyToAccount(vaultPrivateKey);
49
- vaultAddress = account.address;
50
- console.log(`✅ [Signer] Vault unlocked securely from OS Keyring. Agent Address: ${vaultAddress}`);
51
- return;
52
- }
53
- } catch (e) {
54
- console.warn(`⚠️ [Signer] OS Keyring failed (module mismatch or headless). Using fallback.`);
55
- }
56
-
57
- // Fallback to vault.key
58
- const vaultPath = path.join(os.homedir(), '.nyxora', 'auth', 'vault.key');
59
- if (fs.existsSync(vaultPath)) {
60
- const stats = fs.statSync(vaultPath);
61
- const mode = stats.mode & 0o777;
62
- if (os.platform() !== 'win32' && mode !== 0o600) {
63
- console.error(`\n======================================================`);
64
- console.error(`FATAL: Insecure permissions detected on vault.key`);
65
- console.error(`File permissions must be strictly 0600 (-rw-------)`);
66
- console.error(`Current permissions: 0${mode.toString(8)}`);
67
- console.error(`Refusing to start. Please run: chmod 600 ${vaultPath}`);
68
- console.error(`======================================================\n`);
69
- process.exit(1);
70
- }
71
-
72
- const content = fs.readFileSync(vaultPath, 'utf8');
73
- const match = content.match(/PRIVATE_KEY=(.+)/);
74
- if (match && match[1]) {
75
- const pk = match[1].trim();
76
- vaultPrivateKey = pk.startsWith('0x') ? (pk as `0x${string}`) : (`0x${pk}` as `0x${string}`);
77
- const account = privateKeyToAccount(vaultPrivateKey);
78
- vaultAddress = account.address;
79
- console.log(`✅ [Signer] Vault unlocked from vault.key fallback. Agent Address: ${vaultAddress}`);
35
+ const p = path.join(os.homedir(), '.nyxora', 'config.json');
36
+ if (fs.existsSync(p)) {
37
+ return JSON.parse(fs.readFileSync(p, 'utf8'));
80
38
  }
81
- } else {
82
- console.log(`❌ [Signer] No Private Key found in OS Keyring or vault.key. Web3 features will fail.`);
83
- }
39
+ } catch (e) {}
40
+ return {};
84
41
  }
85
42
 
86
- // Load it immediately
87
- loadPrivateKey();
88
-
89
- // Nonce Management
90
- const nonceLocks: Record<number, Promise<void>> = {};
91
- const nonceCache: Record<number, number> = {};
43
+ // Initialize the SDK
44
+ const config = getLocalConfig();
45
+ const signer = new NyxoraSigner({
46
+ customRpcUrls: config.web3?.rpc_urls as Record<string, string | string[]>
47
+ });
92
48
 
93
- function getChain(chainName: string) {
94
- const normalized = chainName.toLowerCase().replace(/_/g, '-');
95
- const normalizedSpace = chainName.toLowerCase().replace(/_/g, ' ');
96
- // @ts-ignore
97
- return Object.values(chains).find(c => c.name.toLowerCase() === normalizedSpace || c.name.toLowerCase() === normalized || (c as any).network === normalized) || chains.mainnet;
98
- }
49
+ // Unlock on startup
50
+ signer.unlock().catch(console.error);
99
51
 
100
52
  app.use((req, res, next) => {
101
53
  const authHeader = req.headers['authorization'];
@@ -111,82 +63,22 @@ app.use((req, res, next) => {
111
63
  });
112
64
 
113
65
  app.get('/address', (req, res) => {
114
- if (!vaultAddress) return res.status(403).json({ error: 'Vault is locked' });
115
- res.json({ address: vaultAddress });
66
+ const address = signer.getAddress();
67
+ if (!address) return res.status(403).json({ error: 'Vault is locked' });
68
+ res.json({ address });
116
69
  });
117
70
 
118
71
  app.post('/sign-transaction', async (req, res) => {
119
72
  const { txPayload } = req.body;
120
- if (!vaultPrivateKey) return res.status(403).json({ error: 'Vault is locked. Unlock first.' });
121
- if (!txPayload || !txPayload.chainName) return res.status(400).json({ error: 'Invalid payload' });
122
-
123
73
  try {
124
- const account = privateKeyToAccount(vaultPrivateKey);
125
- const chain = getChain(txPayload.chainName);
126
-
127
- const config = loadConfig();
128
- const customRpcRaw = config.web3?.rpc_urls?.[txPayload.chainName.toLowerCase()];
129
- let customRpc = undefined;
130
- if (customRpcRaw) {
131
- if (Array.isArray(customRpcRaw) && customRpcRaw.length > 0) customRpc = customRpcRaw[0];
132
- else if (typeof customRpcRaw === 'string' && customRpcRaw.trim()) customRpc = customRpcRaw.trim();
133
- }
134
-
135
- const client = createWalletClient({ account, chain, transport: http(customRpc, { timeout: 15000 }) }).extend(publicActions);
136
- const chainId = chain.id;
137
-
138
- // Mutex lock for nonce management
139
- if (!nonceLocks[chainId]) nonceLocks[chainId] = Promise.resolve();
140
-
141
- const result = await new Promise((resolve, reject) => {
142
- nonceLocks[chainId] = nonceLocks[chainId].then(async () => {
143
- try {
144
- const rpcNonce = await client.getTransactionCount({ address: account.address, blockTag: 'pending' });
145
- let nextNonce = Math.max(rpcNonce, nonceCache[chainId] || 0);
146
-
147
- const txRequest = txPayload.details?.txRequest || txPayload.details?.txData || txPayload;
148
- const toAddress = txRequest.to || txRequest.target;
149
- const txDataStr = txRequest.data || txRequest.calldata;
150
-
151
- // Phase 2: Transaction Simulation (Dry-Run / Anti-Fail)
152
- try {
153
- await client.estimateGas({
154
- account,
155
- to: toAddress,
156
- data: txDataStr,
157
- value: txRequest.value ? BigInt(txRequest.value) : 0n
158
- });
159
- } catch (simError: any) {
160
- throw new Error(`Simulation failed: ${simError.shortMessage || simError.message}`);
161
- }
162
-
163
- // @ts-ignore
164
- const hash = await client.sendTransaction({
165
- account,
166
- to: toAddress,
167
- data: txDataStr,
168
- value: txRequest.value ? BigInt(txRequest.value) : 0n,
169
- nonce: nextNonce,
170
- gas: txRequest.gas ? BigInt(txRequest.gas) : undefined,
171
- maxFeePerGas: txRequest.maxFeePerGas ? BigInt(txRequest.maxFeePerGas) : undefined,
172
- maxPriorityFeePerGas: txRequest.maxPriorityFeePerGas ? BigInt(txRequest.maxPriorityFeePerGas) : undefined,
173
- });
174
- nonceCache[chainId] = nextNonce + 1;
175
- resolve(hash);
176
- } catch (err: any) {
177
- reject(err);
178
- }
179
- }).catch(reject);
180
- });
181
-
182
- res.json({ hash: result });
74
+ const hash = await signer.signTransaction(txPayload);
75
+ res.json({ hash });
183
76
  } catch (e: any) {
184
- res.status(500).json({ error: e.message });
77
+ const status = e.message.includes('locked') ? 403 : (e.message.includes('Invalid payload') ? 400 : 500);
78
+ res.status(status).json({ error: e.message });
185
79
  }
186
80
  });
187
81
 
188
-
189
-
190
82
  if (fs.existsSync(SOCKET_PATH)) {
191
83
  try {
192
84
  fs.unlinkSync(SOCKET_PATH);
@@ -204,11 +96,9 @@ app.listen(SOCKET_PATH, () => {
204
96
  }
205
97
  });
206
98
 
207
- // Phase 3: Graceful Shutdown (Local Keyring Security)
99
+ // Graceful Shutdown
208
100
  const gracefulShutdown = () => {
209
- console.log('[Signer Vault] Received shutdown signal. Locking vault...');
210
- // @ts-ignore
211
- if (typeof vaultPrivateKey !== 'undefined') vaultPrivateKey = null; // Zero out memory reference
101
+ signer.lock();
212
102
  try {
213
103
  if (fs.existsSync(SOCKET_PATH)) fs.unlinkSync(SOCKET_PATH);
214
104
  } catch {}