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.
- package/CHANGELOG.md +95 -47
- package/README.md +23 -19
- package/bin/nyxora.mjs +4 -6
- package/dist/launcher.js +44 -8
- package/dist/packages/core/src/agent/bridgeWatcher.js +3 -2
- package/dist/packages/core/src/agent/cronManager.js +2 -2
- package/dist/packages/core/src/agent/llmProvider.js +242 -0
- package/dist/packages/core/src/agent/nyxDaemon.js +97 -0
- package/dist/packages/core/src/agent/osAgent.js +203 -29
- package/dist/packages/core/src/agent/reasoning.js +353 -60
- package/dist/packages/core/src/agent/reasoningScratchpad.js +47 -0
- package/dist/packages/core/src/agent/transactionManager.js +36 -31
- package/dist/packages/core/src/agent/web3Agent.js +263 -37
- package/dist/packages/core/src/cognitive/cognitiveManager.js +63 -10
- package/dist/packages/core/src/config/parser.js +10 -4
- package/dist/packages/core/src/gateway/chat.js +56 -13
- package/dist/packages/core/src/gateway/cli.js +3 -0
- package/dist/packages/core/src/gateway/discordAdapter.js +81 -0
- package/dist/packages/core/src/gateway/server.js +58 -9
- package/dist/packages/core/src/gateway/setup-ml.js +64 -0
- package/dist/packages/core/src/gateway/setup.js +39 -3
- package/dist/packages/core/src/gateway/telegram.js +120 -24
- package/dist/packages/core/src/memory/episodic.js +47 -3
- package/dist/packages/core/src/memory/logger.js +120 -2
- package/dist/packages/core/src/memory/promotionEngine.js +18 -5
- package/dist/packages/core/src/system/agentskills.js +10 -0
- package/dist/packages/core/src/system/plugins/GoogleWorkspacePlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemCorePlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemExternalPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemPluginInstallerPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemSocialPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemWebPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +3 -3
- package/dist/packages/core/src/system/plugins/createSkill.js +1 -1
- package/dist/packages/core/src/system/skillExtractor.js +16 -5
- package/dist/packages/core/src/system/skills/forgetMemory.js +6 -4
- package/dist/packages/core/src/system/skills/scheduleTask.js +7 -2
- package/dist/packages/core/src/test_mainnet.js +45 -0
- package/dist/packages/core/src/utils/contextSummarizer.js +82 -0
- package/dist/packages/core/src/utils/skillManager.js +1 -1
- package/dist/packages/core/src/utils/streamSimulator.js +85 -0
- package/dist/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.js +28 -11
- package/dist/packages/core/src/web3/aggregator/providers/OpBridgeProvider.js +41 -27
- package/dist/packages/core/src/web3/aggregator/providers/TestnetSwapProvider.js +65 -0
- package/dist/packages/core/src/web3/aggregator/routeSelector.js +7 -1
- package/dist/packages/core/src/web3/plugins/Web3DefiPlugin.js +1 -1
- package/dist/packages/core/src/web3/plugins/Web3MarketPlugin.js +5 -125
- package/dist/packages/core/src/web3/plugins/Web3SecurityPlugin.js +1 -1
- package/dist/packages/core/src/web3/plugins/Web3WalletPlugin.js +1 -1
- package/dist/packages/core/src/web3/skills/bridgeToken.js +19 -4
- package/dist/packages/core/src/web3/skills/checkAddress.js +2 -0
- package/dist/packages/core/src/web3/skills/checkPortfolio.js +22 -2
- package/dist/packages/core/src/web3/skills/checkSecurity.js +2 -0
- package/dist/packages/core/src/web3/skills/confirmPendingTx.js +1 -1
- package/dist/packages/core/src/web3/skills/createLimitOrder.js +15 -1
- package/dist/packages/core/src/web3/skills/customTx.js +3 -0
- package/dist/packages/core/src/web3/skills/defiLending.js +2 -0
- package/dist/packages/core/src/web3/skills/getBalance.js +2 -0
- package/dist/packages/core/src/web3/skills/getPrice.js +134 -27
- package/dist/packages/core/src/web3/skills/getTxHistory.js +2 -0
- package/dist/packages/core/src/web3/skills/marketAnalysis.js +28 -191
- package/dist/packages/core/src/web3/skills/mintNft.js +3 -0
- package/dist/packages/core/src/web3/skills/provideLiquidity.js +16 -12
- package/dist/packages/core/src/web3/skills/revokeApprovals.js +2 -0
- package/dist/packages/core/src/web3/skills/swapToken.js +20 -2
- package/dist/packages/core/src/web3/skills/transfer.js +2 -0
- package/dist/packages/core/src/web3/skills/yieldVault.js +2 -0
- package/dist/packages/core/src/web3/utils/chains.js +19 -0
- package/dist/packages/core/src/web3/utils/marketEngine.js +26 -33
- package/dist/packages/signer/src/NyxoraSigner.js +181 -0
- package/dist/packages/signer/src/index.js +17 -0
- package/dist/packages/signer/src/server.js +25 -161
- package/launcher.ts +38 -9
- package/package.json +6 -2
- package/packages/core/package.json +21 -10
- package/packages/core/src/agent/bridgeWatcher.ts +3 -2
- package/packages/core/src/agent/cronManager.ts +2 -2
- package/packages/core/src/agent/llmProvider.ts +219 -0
- package/packages/core/src/agent/nyxDaemon.ts +104 -0
- package/packages/core/src/agent/osAgent.ts +230 -32
- package/packages/core/src/agent/reasoning.ts +376 -64
- package/packages/core/src/agent/reasoningScratchpad.ts +45 -0
- package/packages/core/src/agent/transactionManager.ts +36 -28
- package/packages/core/src/agent/web3Agent.ts +291 -40
- package/packages/core/src/cognitive/cognitiveManager.ts +65 -10
- package/packages/core/src/cognitive/prompts/web3/market-analysis.md +24 -0
- package/packages/core/src/cognitive/prompts/web3/portfolio-review.md +29 -0
- package/packages/core/src/cognitive/prompts/web3/risk-assessment.md +28 -0
- package/packages/core/src/cognitive/prompts/web3/trade-planning.md +30 -0
- package/packages/core/src/config/parser.ts +15 -4
- package/packages/core/src/gateway/chat.ts +57 -15
- package/packages/core/src/gateway/cli.ts +4 -0
- package/packages/core/src/gateway/discordAdapter.ts +87 -0
- package/packages/core/src/gateway/server.ts +66 -10
- package/packages/core/src/gateway/setup-ml.ts +68 -0
- package/packages/core/src/gateway/setup.ts +41 -3
- package/packages/core/src/gateway/telegram.ts +138 -27
- package/packages/core/src/memory/episodic.ts +64 -3
- package/packages/core/src/memory/logger.ts +142 -2
- package/packages/core/src/memory/promotionEngine.ts +19 -5
- package/packages/core/src/system/agentskills.ts +10 -0
- package/packages/core/src/system/plugins/GoogleWorkspacePlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemCorePlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemExternalPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemPluginInstallerPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemSocialPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemWebPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +3 -3
- package/packages/core/src/system/plugins/createSkill.ts +1 -1
- package/packages/core/src/system/skillExtractor.ts +16 -5
- package/packages/core/src/system/skills/forgetMemory.ts +7 -4
- package/packages/core/src/system/skills/scheduleTask.ts +7 -2
- package/packages/core/src/utils/contextSummarizer.ts +100 -0
- package/packages/core/src/utils/skillManager.ts +1 -1
- package/packages/core/src/utils/streamSimulator.ts +88 -0
- package/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.ts +30 -11
- package/packages/core/src/web3/aggregator/providers/OpBridgeProvider.ts +43 -29
- package/packages/core/src/web3/aggregator/routeSelector.ts +6 -1
- package/packages/core/src/web3/plugins/Web3DefiPlugin.ts +1 -1
- package/packages/core/src/web3/plugins/Web3MarketPlugin.ts +6 -125
- package/packages/core/src/web3/plugins/Web3SecurityPlugin.ts +1 -1
- package/packages/core/src/web3/plugins/Web3WalletPlugin.ts +1 -1
- package/packages/core/src/web3/skills/bridgeToken.ts +21 -7
- package/packages/core/src/web3/skills/checkAddress.ts +2 -0
- package/packages/core/src/web3/skills/checkPortfolio.ts +23 -2
- package/packages/core/src/web3/skills/checkSecurity.ts +2 -0
- package/packages/core/src/web3/skills/confirmPendingTx.ts +1 -1
- package/packages/core/src/web3/skills/createLimitOrder.ts +17 -2
- package/packages/core/src/web3/skills/customTx.ts +3 -0
- package/packages/core/src/web3/skills/defiLending.ts +2 -0
- package/packages/core/src/web3/skills/getBalance.ts +2 -0
- package/packages/core/src/web3/skills/getPrice.ts +134 -30
- package/packages/core/src/web3/skills/getTxHistory.ts +2 -0
- package/packages/core/src/web3/skills/marketAnalysis.ts +45 -188
- package/packages/core/src/web3/skills/mintNft.ts +3 -0
- package/packages/core/src/web3/skills/provideLiquidity.ts +16 -10
- package/packages/core/src/web3/skills/revokeApprovals.ts +2 -0
- package/packages/core/src/web3/skills/swapToken.ts +20 -3
- package/packages/core/src/web3/skills/transfer.ts +2 -0
- package/packages/core/src/web3/skills/yieldVault.ts +2 -0
- package/packages/core/src/web3/utils/chains.ts +12 -0
- package/packages/core/src/web3/utils/marketEngine.ts +27 -33
- package/packages/dashboard/dist/assets/index-BTfp141V.js +18 -0
- package/packages/dashboard/dist/assets/index-DK2sTU47.css +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package.json +10 -10
- package/packages/mcp-server/dist/server.js +5 -1
- package/packages/mcp-server/package.json +6 -6
- package/packages/mcp-server/src/server.ts +11 -7
- package/packages/policy/package.json +3 -3
- package/packages/signer/package.json +16 -6
- package/packages/signer/src/NyxoraSigner.ts +161 -0
- package/packages/signer/src/index.ts +1 -0
- package/packages/signer/src/server.ts +25 -135
- package/dist/packages/core/src/agent/honchoDaemon.js +0 -91
- package/dist/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -54
- package/dist/packages/core/src/gateway/test.js +0 -15
- package/dist/packages/core/src/web3/Web3DefiPlugin.js +0 -28
- package/dist/packages/core/src/web3/aggregator/aggregatorMainnet.js +0 -260
- package/dist/packages/core/src/web3/aggregator/aggregatorTestnet.js +0 -119
- package/dist/packages/core/src/web3/skills/nativeOpBridge.js +0 -71
- package/packages/core/src/agent/honchoDaemon.ts +0 -96
- package/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -41
- package/packages/core/src/plugin/registry.test.ts +0 -46
- package/packages/core/src/utils/formatter.test.ts +0 -41
- package/packages/dashboard/dist/assets/index-CSoNa5cx.css +0 -1
- 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-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
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.
|
|
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": "^
|
|
12
|
+
"lucide-react": "^1.22.0",
|
|
13
13
|
"react": "^18.3.1",
|
|
14
14
|
"react-dom": "^18.3.1",
|
|
15
|
-
"viem": "^2.
|
|
15
|
+
"viem": "^2.53.1"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@types/node": "^
|
|
19
|
-
"@types/react": "^18.3.
|
|
20
|
-
"@types/react-dom": "^18.3.
|
|
21
|
-
"@vitejs/plugin-react": "^6.0.
|
|
22
|
-
"globals": "^17.
|
|
23
|
-
"typescript": "~6.0.
|
|
24
|
-
"vite": "^8.0
|
|
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.
|
|
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.
|
|
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.
|
|
14
|
-
"zod": "^
|
|
13
|
+
"jsonwebtoken": "^9.0.3",
|
|
14
|
+
"zod": "^4.4.3"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@types/jsonwebtoken": "^9.0.
|
|
18
|
-
"@types/node": "^
|
|
19
|
-
"typescript": "^
|
|
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.
|
|
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.
|
|
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.
|
|
10
|
+
"jsonwebtoken": "^9.0.3",
|
|
11
11
|
"yaml": "^2.9.0",
|
|
12
|
-
"zod": "^
|
|
12
|
+
"zod": "^4.4.3"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "nyxora-signer",
|
|
3
|
-
"version": "26.7.
|
|
4
|
-
"
|
|
5
|
-
|
|
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.
|
|
10
|
-
"viem": "^2.
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
}
|
|
82
|
-
|
|
83
|
-
}
|
|
39
|
+
} catch (e) {}
|
|
40
|
+
return {};
|
|
84
41
|
}
|
|
85
42
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
94
|
-
|
|
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
|
-
|
|
115
|
-
res.json({
|
|
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
|
|
125
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
99
|
+
// Graceful Shutdown
|
|
208
100
|
const gracefulShutdown = () => {
|
|
209
|
-
|
|
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 {}
|