auramaxx 1.0.0-alpha.4

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 (363) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +112 -0
  3. package/bin/aurawallet.js +121 -0
  4. package/docs/ADAPTERS.md +467 -0
  5. package/docs/API.md +2679 -0
  6. package/docs/APPS.md +198 -0
  7. package/docs/ARCHITECTURE.md +350 -0
  8. package/docs/AUTH.md +698 -0
  9. package/docs/BEST-PRACTICES.md +121 -0
  10. package/docs/CLI.md +61 -0
  11. package/docs/DEVELOPING-APPS.md +452 -0
  12. package/docs/EXTENSION.md +97 -0
  13. package/docs/JOBS.md +33 -0
  14. package/docs/MCP.md +76 -0
  15. package/docs/PROTOCOL.md +142 -0
  16. package/docs/SETUP.md +219 -0
  17. package/docs/WORKSPACE.md +672 -0
  18. package/docs/agent-auth.md +63 -0
  19. package/docs/aura-file.md +48 -0
  20. package/docs/credentials.md +53 -0
  21. package/docs/external/getting-started.md +65 -0
  22. package/docs/external/overview.md +45 -0
  23. package/docs/external/use-cases.md +48 -0
  24. package/docs/external/why-aura.md +35 -0
  25. package/docs/jobs/connect-agent.md +77 -0
  26. package/docs/jobs/migrate-from-dotenv.md +79 -0
  27. package/docs/jobs/recover-from-lockout.md +72 -0
  28. package/docs/jobs/secure-ci.md +63 -0
  29. package/docs/oauth2.md +42 -0
  30. package/docs/passkeys.md +60 -0
  31. package/docs/security.md +540 -0
  32. package/docs/specs/aura-open-protocol.md +61 -0
  33. package/docs/specs/aura-provider-plugin.md +24 -0
  34. package/docs/specs/aura-registry-model.md +31 -0
  35. package/docs/specs/fixtures/invalid-bad-key.aura +1 -0
  36. package/docs/specs/fixtures/invalid-bad-unicode-escape.aura +1 -0
  37. package/docs/specs/fixtures/invalid-duplicate-key.aura +2 -0
  38. package/docs/specs/fixtures/valid-basic.aura +4 -0
  39. package/docs/specs/fixtures/valid-provider-ref.aura +1 -0
  40. package/docs/specs/fixtures/valid-quoted-escapes.aura +2 -0
  41. package/docs/templates/RELEASE_NOTES_TEMPLATE.md +22 -0
  42. package/docs/totp.md +40 -0
  43. package/docs/wallet/AI.md +508 -0
  44. package/docs/wallet/DEVELOPING-STRATEGIES.md +713 -0
  45. package/docs/wallet/README.md +47 -0
  46. package/docs/wallet/STRATEGY.md +89 -0
  47. package/next.config.ts +21 -0
  48. package/package.json +151 -0
  49. package/postcss.config.mjs +8 -0
  50. package/prisma/migrations/20260214170000_baseline/migration.sql +511 -0
  51. package/prisma/migrations/20260216214537_add_passkey_model/migration.sql +18 -0
  52. package/prisma/migrations/20260217150500_add_credential_access_audit/migration.sql +31 -0
  53. package/prisma/migrations/migration_lock.toml +3 -0
  54. package/prisma/schema.prisma +447 -0
  55. package/public/logo-chevron.svg +31 -0
  56. package/public/logo-concentric.svg +31 -0
  57. package/public/logo-crosshatch.svg +39 -0
  58. package/public/logo-dashed.svg +39 -0
  59. package/public/logo-horizontal.svg +31 -0
  60. package/public/logo-m56.svg +64 -0
  61. package/public/logo.webp +0 -0
  62. package/scripts/add-app.js +245 -0
  63. package/scripts/init.sh +57 -0
  64. package/scripts/migrate-apikeys-to-credentials.ts +35 -0
  65. package/scripts/sandbox-agent-flow.sh +235 -0
  66. package/scripts/sandbox.sh +175 -0
  67. package/scripts/validate-job-docs.mjs +125 -0
  68. package/server/abi/SwapHelper.json +438 -0
  69. package/server/cli/approval.ts +447 -0
  70. package/server/cli/commands/app.ts +204 -0
  71. package/server/cli/commands/cron.ts +24 -0
  72. package/server/cli/commands/doctor.ts +1007 -0
  73. package/server/cli/commands/env.ts +456 -0
  74. package/server/cli/commands/init.ts +752 -0
  75. package/server/cli/commands/mcp.ts +125 -0
  76. package/server/cli/commands/restore.ts +314 -0
  77. package/server/cli/commands/shell-hook.ts +468 -0
  78. package/server/cli/commands/start.ts +62 -0
  79. package/server/cli/commands/status.ts +59 -0
  80. package/server/cli/commands/stop.ts +14 -0
  81. package/server/cli/commands/token.ts +180 -0
  82. package/server/cli/commands/unlock.ts +49 -0
  83. package/server/cli/commands/vault.ts +417 -0
  84. package/server/cli/index.ts +328 -0
  85. package/server/cli/lib/aura-parser.ts +64 -0
  86. package/server/cli/lib/credential-create.ts +74 -0
  87. package/server/cli/lib/credential-resolve.ts +254 -0
  88. package/server/cli/lib/dotenv-migrate.ts +116 -0
  89. package/server/cli/lib/dotenv-parser.ts +146 -0
  90. package/server/cli/lib/http.ts +91 -0
  91. package/server/cli/lib/init-steps.ts +76 -0
  92. package/server/cli/lib/local-agent-trust.ts +45 -0
  93. package/server/cli/lib/process.ts +136 -0
  94. package/server/cli/lib/prompt.ts +85 -0
  95. package/server/cli/lib/theme.ts +240 -0
  96. package/server/cli/socket.ts +570 -0
  97. package/server/cli/transport-client.ts +50 -0
  98. package/server/cron/index.ts +137 -0
  99. package/server/cron/job.ts +31 -0
  100. package/server/cron/jobs/balance-sync.ts +436 -0
  101. package/server/cron/jobs/incoming-scan.ts +506 -0
  102. package/server/cron/jobs/native-price.ts +70 -0
  103. package/server/cron/jobs/orphan-cleanup.ts +40 -0
  104. package/server/cron/jobs/strategy-runner.ts +175 -0
  105. package/server/cron/scheduler.ts +125 -0
  106. package/server/index.ts +406 -0
  107. package/server/lib/adapters/factory.ts +110 -0
  108. package/server/lib/adapters/index.ts +19 -0
  109. package/server/lib/adapters/router.ts +297 -0
  110. package/server/lib/adapters/telegram.ts +645 -0
  111. package/server/lib/adapters/types.ts +89 -0
  112. package/server/lib/adapters/webhook.ts +95 -0
  113. package/server/lib/address.ts +49 -0
  114. package/server/lib/agent-auth/contracts.ts +1194 -0
  115. package/server/lib/agent-profiles.ts +328 -0
  116. package/server/lib/ai.ts +285 -0
  117. package/server/lib/api-registry/contracts.ts +86 -0
  118. package/server/lib/api-registry/validation.ts +172 -0
  119. package/server/lib/apikey-migration.ts +189 -0
  120. package/server/lib/app-installer.ts +505 -0
  121. package/server/lib/app-tokens.ts +247 -0
  122. package/server/lib/auth.ts +314 -0
  123. package/server/lib/batch.ts +242 -0
  124. package/server/lib/cold.ts +874 -0
  125. package/server/lib/config.ts +381 -0
  126. package/server/lib/credential-access-audit.ts +85 -0
  127. package/server/lib/credential-access-policy.ts +110 -0
  128. package/server/lib/credential-health.ts +343 -0
  129. package/server/lib/credential-import.ts +487 -0
  130. package/server/lib/credential-scope.ts +87 -0
  131. package/server/lib/credential-shares.ts +190 -0
  132. package/server/lib/credential-transport.ts +342 -0
  133. package/server/lib/credential-vault.ts +77 -0
  134. package/server/lib/credentials.ts +333 -0
  135. package/server/lib/crypto.ts +8 -0
  136. package/server/lib/db.ts +15 -0
  137. package/server/lib/defaults.ts +366 -0
  138. package/server/lib/dex/index.ts +80 -0
  139. package/server/lib/dex/relay.ts +235 -0
  140. package/server/lib/dex/types.ts +59 -0
  141. package/server/lib/dex/uniswap.ts +370 -0
  142. package/server/lib/e2e-agent/artifacts.ts +36 -0
  143. package/server/lib/e2e-agent/contracts.ts +112 -0
  144. package/server/lib/e2e-agent/validation.ts +135 -0
  145. package/server/lib/encrypt.ts +128 -0
  146. package/server/lib/error.ts +20 -0
  147. package/server/lib/events.ts +205 -0
  148. package/server/lib/hot.ts +357 -0
  149. package/server/lib/key-fingerprint.ts +28 -0
  150. package/server/lib/logger.ts +331 -0
  151. package/server/lib/network.ts +137 -0
  152. package/server/lib/notifications.ts +219 -0
  153. package/server/lib/oauth2-refresh.ts +241 -0
  154. package/server/lib/oursecret.ts +54 -0
  155. package/server/lib/passkey-credential.ts +360 -0
  156. package/server/lib/passkey.ts +68 -0
  157. package/server/lib/permissions.ts +248 -0
  158. package/server/lib/pino.ts +24 -0
  159. package/server/lib/policy-preview.ts +138 -0
  160. package/server/lib/price.ts +338 -0
  161. package/server/lib/prices.ts +34 -0
  162. package/server/lib/project-scope.ts +239 -0
  163. package/server/lib/resolve-action.ts +427 -0
  164. package/server/lib/resolve.ts +36 -0
  165. package/server/lib/sessions.ts +632 -0
  166. package/server/lib/solana/connection.ts +26 -0
  167. package/server/lib/solana/jupiter.ts +128 -0
  168. package/server/lib/solana/transfer.ts +108 -0
  169. package/server/lib/solana/wallet.ts +136 -0
  170. package/server/lib/strategy/emits.ts +21 -0
  171. package/server/lib/strategy/engine.ts +1305 -0
  172. package/server/lib/strategy/executor.ts +115 -0
  173. package/server/lib/strategy/hook-context.ts +158 -0
  174. package/server/lib/strategy/hooks.ts +990 -0
  175. package/server/lib/strategy/index.ts +28 -0
  176. package/server/lib/strategy/installer.ts +305 -0
  177. package/server/lib/strategy/loader.ts +256 -0
  178. package/server/lib/strategy/message.ts +235 -0
  179. package/server/lib/strategy/repository.ts +218 -0
  180. package/server/lib/strategy/session-logger.ts +693 -0
  181. package/server/lib/strategy/sources.ts +288 -0
  182. package/server/lib/strategy/state.ts +189 -0
  183. package/server/lib/strategy/templates.ts +403 -0
  184. package/server/lib/strategy/tick.ts +404 -0
  185. package/server/lib/strategy/types.ts +230 -0
  186. package/server/lib/swap.ts +3 -0
  187. package/server/lib/temp.ts +86 -0
  188. package/server/lib/token-metadata.ts +86 -0
  189. package/server/lib/token-safety.ts +200 -0
  190. package/server/lib/token-search.ts +444 -0
  191. package/server/lib/totp.ts +194 -0
  192. package/server/lib/transactions.ts +123 -0
  193. package/server/lib/transport.ts +75 -0
  194. package/server/lib/txhistory/decoder.ts +262 -0
  195. package/server/lib/txhistory/enricher.ts +652 -0
  196. package/server/lib/txhistory/index.ts +391 -0
  197. package/server/lib/txhistory/signatures.ts +59 -0
  198. package/server/lib/verified-summary.ts +421 -0
  199. package/server/mcp/profile-policy.ts +30 -0
  200. package/server/mcp/server.ts +619 -0
  201. package/server/mcp/tools.ts +523 -0
  202. package/server/middleware/auth.ts +119 -0
  203. package/server/middleware/requestLogger.ts +84 -0
  204. package/server/routes/actions.ts +459 -0
  205. package/server/routes/adapters.ts +703 -0
  206. package/server/routes/addressbook.ts +113 -0
  207. package/server/routes/ai.ts +34 -0
  208. package/server/routes/apikeys.ts +295 -0
  209. package/server/routes/apps.ts +601 -0
  210. package/server/routes/auth.ts +457 -0
  211. package/server/routes/backup.ts +340 -0
  212. package/server/routes/batch.ts +270 -0
  213. package/server/routes/bookmarks.ts +162 -0
  214. package/server/routes/credential-shares.ts +198 -0
  215. package/server/routes/credential-vaults.ts +154 -0
  216. package/server/routes/credentials.ts +1290 -0
  217. package/server/routes/dashboard.ts +71 -0
  218. package/server/routes/defaults.ts +124 -0
  219. package/server/routes/fund.ts +229 -0
  220. package/server/routes/import.ts +352 -0
  221. package/server/routes/launch.ts +665 -0
  222. package/server/routes/lock.ts +54 -0
  223. package/server/routes/logs.ts +68 -0
  224. package/server/routes/nuke.ts +111 -0
  225. package/server/routes/passkey-credentials.ts +99 -0
  226. package/server/routes/passkey.ts +346 -0
  227. package/server/routes/portfolio.ts +217 -0
  228. package/server/routes/price.ts +63 -0
  229. package/server/routes/resolve.ts +31 -0
  230. package/server/routes/security.ts +45 -0
  231. package/server/routes/send-evm.ts +241 -0
  232. package/server/routes/send-solana.ts +281 -0
  233. package/server/routes/send.ts +178 -0
  234. package/server/routes/setup.ts +210 -0
  235. package/server/routes/strategy.ts +894 -0
  236. package/server/routes/swap-evm.ts +353 -0
  237. package/server/routes/swap-solana.ts +177 -0
  238. package/server/routes/swap.ts +356 -0
  239. package/server/routes/token.ts +247 -0
  240. package/server/routes/unlock.ts +403 -0
  241. package/server/routes/wallet-assets.ts +361 -0
  242. package/server/routes/wallet-transactions.ts +515 -0
  243. package/server/routes/wallet.ts +710 -0
  244. package/server/types.ts +146 -0
  245. package/skills/aurawallet/SKILL.md +739 -0
  246. package/skills/aurawallet-setup/SKILL.md +74 -0
  247. package/skills/security-review/SKILL.md +148 -0
  248. package/src/app/api/agent-requests/route.ts +30 -0
  249. package/src/app/api/apps/install/route.ts +126 -0
  250. package/src/app/api/apps/manifests/route.ts +16 -0
  251. package/src/app/api/apps/static/[...path]/route.ts +57 -0
  252. package/src/app/api/events/route.ts +92 -0
  253. package/src/app/api/page.tsx +212 -0
  254. package/src/app/api/workspace/[id]/apps/[wid]/route.ts +119 -0
  255. package/src/app/api/workspace/[id]/apps/route.ts +81 -0
  256. package/src/app/api/workspace/[id]/export/route.ts +67 -0
  257. package/src/app/api/workspace/[id]/route.ts +168 -0
  258. package/src/app/api/workspace/auth.ts +34 -0
  259. package/src/app/api/workspace/config/route.ts +106 -0
  260. package/src/app/api/workspace/import/route.ts +127 -0
  261. package/src/app/api/workspace/route.ts +116 -0
  262. package/src/app/app/page.tsx +2122 -0
  263. package/src/app/apple-icon.png +0 -0
  264. package/src/app/docs/page.tsx +178 -0
  265. package/src/app/favicon.ico +0 -0
  266. package/src/app/globals.css +572 -0
  267. package/src/app/health/page.tsx +5 -0
  268. package/src/app/hello/page.tsx +15 -0
  269. package/src/app/icon.png +0 -0
  270. package/src/app/layout.tsx +34 -0
  271. package/src/app/page.tsx +986 -0
  272. package/src/app/providers.tsx +90 -0
  273. package/src/app/share/[token]/page.tsx +295 -0
  274. package/src/components/ChainSelector.tsx +144 -0
  275. package/src/components/HumanActionBar.tsx +695 -0
  276. package/src/components/NotificationDrawer.tsx +129 -0
  277. package/src/components/apps/AgentKeysApp.tsx +490 -0
  278. package/src/components/apps/App.tsx +153 -0
  279. package/src/components/apps/AppGrid.tsx +15 -0
  280. package/src/components/apps/DetailedAddressDrawer.tsx +325 -0
  281. package/src/components/apps/DraggableApp.tsx +562 -0
  282. package/src/components/apps/IFrameApp.tsx +73 -0
  283. package/src/components/apps/LogsApp.tsx +360 -0
  284. package/src/components/apps/SendApp.tsx +394 -0
  285. package/src/components/apps/SetupWizardApp.tsx +1004 -0
  286. package/src/components/apps/SystemDefaultsApp.tsx +845 -0
  287. package/src/components/apps/ThirdPartyApp.tsx +428 -0
  288. package/src/components/apps/TokenApp.tsx +319 -0
  289. package/src/components/apps/TransactionsApp.tsx +438 -0
  290. package/src/components/apps/WalletDetailApp.tsx +1505 -0
  291. package/src/components/apps/index.ts +13 -0
  292. package/src/components/design-system/Button.tsx +53 -0
  293. package/src/components/design-system/ChainIndicator.tsx +65 -0
  294. package/src/components/design-system/ChainSelector.tsx +137 -0
  295. package/src/components/design-system/ConfirmationModal.tsx +106 -0
  296. package/src/components/design-system/ConfirmationPopover.tsx +81 -0
  297. package/src/components/design-system/Drawer.tsx +123 -0
  298. package/src/components/design-system/FilterDropdown.tsx +72 -0
  299. package/src/components/design-system/Modal.tsx +206 -0
  300. package/src/components/design-system/Popover.tsx +142 -0
  301. package/src/components/design-system/TextInput.tsx +85 -0
  302. package/src/components/design-system/Toggle.tsx +58 -0
  303. package/src/components/design-system/index.ts +11 -0
  304. package/src/components/docs/DocsThemeToggle.tsx +49 -0
  305. package/src/components/health/CredentialHealthDashboard.tsx +214 -0
  306. package/src/components/icons/ChainIcons.tsx +72 -0
  307. package/src/components/layout/AppStoreDrawer.tsx +369 -0
  308. package/src/components/layout/ContentArea.tsx +21 -0
  309. package/src/components/layout/TabBar.tsx +278 -0
  310. package/src/components/layout/WalletSidebar.tsx +1033 -0
  311. package/src/components/layout/index.ts +4 -0
  312. package/src/components/marketing/AuraWalletSpecOverlay.tsx +635 -0
  313. package/src/components/marketing/DeviceMorphExperience.tsx +216 -0
  314. package/src/components/vault/ApiKeysConsole.tsx +1080 -0
  315. package/src/components/vault/AuditConsole.tsx +584 -0
  316. package/src/components/vault/CredentialDetail.tsx +455 -0
  317. package/src/components/vault/CredentialEmpty.tsx +55 -0
  318. package/src/components/vault/CredentialField.tsx +361 -0
  319. package/src/components/vault/CredentialForm.tsx +1212 -0
  320. package/src/components/vault/CredentialList.tsx +165 -0
  321. package/src/components/vault/CredentialRow.tsx +97 -0
  322. package/src/components/vault/CredentialShareModal.tsx +178 -0
  323. package/src/components/vault/CredentialVault.tsx +754 -0
  324. package/src/components/vault/CredentialWalletWidget.tsx +103 -0
  325. package/src/components/vault/ImportCredentialsModal.tsx +515 -0
  326. package/src/components/vault/LargeTypeModal.tsx +64 -0
  327. package/src/components/vault/PasswordGenerator.tsx +224 -0
  328. package/src/components/vault/TOTPDisplay.tsx +123 -0
  329. package/src/components/vault/VaultSidebar.tsx +413 -0
  330. package/src/components/vault/types.ts +54 -0
  331. package/src/context/AuthContext.tsx +337 -0
  332. package/src/context/PriceContext.tsx +113 -0
  333. package/src/context/ThemeContext.tsx +164 -0
  334. package/src/context/WebSocketContext.tsx +269 -0
  335. package/src/context/WorkspaceContext.tsx +668 -0
  336. package/src/hooks/index.ts +3 -0
  337. package/src/hooks/useAgentActions.ts +368 -0
  338. package/src/hooks/useBalance.ts +103 -0
  339. package/src/hooks/useBalances.ts +129 -0
  340. package/src/instrumentation.ts +12 -0
  341. package/src/lib/api.ts +449 -0
  342. package/src/lib/app-loader.ts +148 -0
  343. package/src/lib/app-registry.ts +178 -0
  344. package/src/lib/app-sdk.ts +157 -0
  345. package/src/lib/audit-console-adapter.ts +151 -0
  346. package/src/lib/auth-client.ts +75 -0
  347. package/src/lib/config.ts +74 -0
  348. package/src/lib/crypto.ts +112 -0
  349. package/src/lib/db.ts +21 -0
  350. package/src/lib/docs.ts +390 -0
  351. package/src/lib/events.ts +361 -0
  352. package/src/lib/pino.ts +24 -0
  353. package/src/lib/theme-handlers.ts +168 -0
  354. package/src/lib/theme.ts +351 -0
  355. package/src/lib/tokenData.ts +378 -0
  356. package/src/lib/vault-crypto.ts +129 -0
  357. package/src/lib/websocket-server.ts +302 -0
  358. package/src/lib/websocket-setup.ts +79 -0
  359. package/src/lib/wordlist.ts +2050 -0
  360. package/src/lib/workspace-handlers.ts +285 -0
  361. package/start.sh +80 -0
  362. package/tailwind.config.ts +99 -0
  363. package/tsconfig.json +42 -0
@@ -0,0 +1,467 @@
1
+ # Approval Adapters
2
+
3
+ External approval channels for agent actions. Adapters forward `action:created` events to external services (Telegram, Discord, webhooks, etc.) and relay human decisions back to `POST /actions/:id/resolve`.
4
+
5
+ ---
6
+
7
+ ## How It Works
8
+
9
+ ```
10
+ Agent requests token
11
+
12
+
13
+ POST /actions/:id/resolve ◄─── Dashboard UI
14
+ ▲ ◄─── CLI terminal
15
+ │ ◄─── Adapter (Telegram, webhook, etc.)
16
+
17
+ All channels converge on the same endpoint
18
+ ```
19
+
20
+ Adapters don't change the resolve endpoint or any existing code paths. They simply:
21
+ 1. Receive the `action:created` WebSocket event
22
+ 2. Present it to a human in some external medium
23
+ 3. POST back to resolve when the human responds
24
+
25
+ ---
26
+
27
+ ## Configuration
28
+
29
+ Adapter config is stored in the database, not in config files. This keeps secrets out of plain-text JSON and aligns with how API keys (Alchemy, etc.) are already managed.
30
+
31
+ **Two pieces:**
32
+ - **Secrets** (bot tokens, HMAC keys) → `POST /apikeys` with `service: "adapter:<type>"`
33
+ - **Settings** (enabled flags, non-secret config) → `POST /adapters`
34
+
35
+ ### 1. Store secrets via `/apikeys`
36
+
37
+ ```bash
38
+ # Telegram bot token
39
+ curl -X POST http://localhost:4242/apikeys \
40
+ -H "Authorization: Bearer <admin-token>" \
41
+ -H "Content-Type: application/json" \
42
+ -d '{"service": "adapter:telegram", "name": "botToken", "key": "123456:ABC-DEF..."}'
43
+
44
+ # Webhook HMAC secret
45
+ curl -X POST http://localhost:4242/apikeys \
46
+ -H "Authorization: Bearer <admin-token>" \
47
+ -H "Content-Type: application/json" \
48
+ -d '{"service": "adapter:webhook", "name": "secret", "key": "my-hmac-secret"}'
49
+ ```
50
+
51
+ ### 2. Configure adapter settings via `/adapters`
52
+
53
+ ```bash
54
+ # Enable Telegram adapter (chatId is non-secret, stored in AppConfig)
55
+ curl -X POST http://localhost:4242/adapters \
56
+ -H "Authorization: Bearer <admin-token>" \
57
+ -H "Content-Type: application/json" \
58
+ -d '{"type": "telegram", "enabled": true, "config": {"chatId": "987654321"}}'
59
+
60
+ # Enable webhook adapter
61
+ curl -X POST http://localhost:4242/adapters \
62
+ -H "Authorization: Bearer <admin-token>" \
63
+ -H "Content-Type: application/json" \
64
+ -d '{"type": "webhook", "enabled": true, "config": {"url": "https://hooks.slack.com/services/T.../B.../xxx"}}'
65
+ ```
66
+
67
+ ### 3. Restart the adapter router
68
+
69
+ After changing config, restart to pick up changes:
70
+
71
+ ```bash
72
+ curl -X POST http://localhost:4242/adapters/restart \
73
+ -H "Authorization: Bearer <admin-token>"
74
+ ```
75
+
76
+ ### Adapter Management Endpoints
77
+
78
+ | Method | Route | Description |
79
+ |--------|-------|-------------|
80
+ | `GET` | `/adapters` | List configured adapters (with secret status) |
81
+ | `POST` | `/adapters` | Add/update adapter config `{ type, enabled, config, chat? }` |
82
+ | `POST` | `/adapters/chat` | Set top-level chat config (defaultApp) |
83
+ | `POST` | `/adapters/:type/message` | Inbound chat from adapter webhook (HMAC auth) |
84
+ | `DELETE` | `/adapters/:type` | Remove adapter config |
85
+ | `POST` | `/adapters/restart` | Restart approval router with current DB config |
86
+
87
+ All adapter endpoints require `adapter:manage` permission (or `admin:*` which includes it).
88
+
89
+ Adapters are opt-in. If no adapters are configured, the approval router doesn't start.
90
+
91
+ ---
92
+
93
+ ## Built-in Adapters
94
+
95
+ ### Webhook (notification-only)
96
+
97
+ POSTs action events to a URL. Useful for Slack/Discord incoming webhooks, ntfy, or any HTTP endpoint.
98
+
99
+ **Config (`POST /adapters`):**
100
+
101
+ | Field | Type | Storage | Description |
102
+ |-------|------|---------|-------------|
103
+ | `url` | string | `POST /adapters` config | URL to POST to |
104
+ | `secret` | string | `POST /apikeys` | HMAC-SHA256 secret for `X-Signature-256` header |
105
+ | `headers` | object | `POST /adapters` config | Custom headers to include |
106
+
107
+ **Setup:**
108
+ ```bash
109
+ # 1. Store HMAC secret (optional)
110
+ curl -X POST http://localhost:4242/apikeys \
111
+ -H "Authorization: Bearer <admin-token>" \
112
+ -H "Content-Type: application/json" \
113
+ -d '{"service": "adapter:webhook", "name": "secret", "key": "my-hmac-secret"}'
114
+
115
+ # 2. Configure webhook URL and custom headers
116
+ curl -X POST http://localhost:4242/adapters \
117
+ -H "Authorization: Bearer <admin-token>" \
118
+ -H "Content-Type: application/json" \
119
+ -d '{"type": "webhook", "enabled": true, "config": {"url": "https://hooks.slack.com/services/...", "headers": {"X-Custom": "value"}}}'
120
+
121
+ # 3. Restart
122
+ curl -X POST http://localhost:4242/adapters/restart \
123
+ -H "Authorization: Bearer <admin-token>"
124
+ ```
125
+
126
+ **Payload format:**
127
+
128
+ ```json
129
+ {
130
+ "type": "action:created",
131
+ "data": {
132
+ "id": "abc-123",
133
+ "type": "action",
134
+ "source": "agent:my-agent",
135
+ "summary": "Swap 0.01 ETH for USDC",
136
+ "expiresAt": null,
137
+ "metadata": {
138
+ "agentId": "my-agent",
139
+ "permissions": ["swap"],
140
+ "verifiedSummary": {
141
+ "action": "/swap",
142
+ "oneLiner": "Buy 0xABC...DEF with 0.01 ETH on base",
143
+ "facts": [{ "label": "Amount", "value": "0.01 ETH" }],
144
+ "discrepancies": [],
145
+ "verified": true,
146
+ "generatedAt": "2026-02-11T..."
147
+ }
148
+ }
149
+ },
150
+ "timestamp": 1738599000000
151
+ }
152
+ ```
153
+
154
+ **HMAC verification (if secret configured):**
155
+
156
+ ```javascript
157
+ const crypto = require('crypto');
158
+ const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
159
+ const valid = req.headers['x-signature-256'] === `sha256=${expected}`;
160
+ ```
161
+
162
+ The webhook adapter is notification-only — it doesn't handle responses. To approve/reject from a webhook target, have your service POST directly to `/actions/:id/resolve` with an admin token, or build a bidirectional adapter.
163
+
164
+ ### Telegram (bidirectional)
165
+
166
+ Full approval flow via Telegram Bot API. Sends inline keyboard buttons, handles callbacks.
167
+
168
+ **Config:**
169
+
170
+ | Field | Type | Storage | Description |
171
+ |-------|------|---------|-------------|
172
+ | `botToken` | string | `POST /apikeys` | Bot API token from @BotFather |
173
+ | `chatId` | string/number | `POST /adapters` config | Chat ID for notifications and callbacks |
174
+
175
+ **Setup:**
176
+ 1. Create a bot via [@BotFather](https://t.me/BotFather)
177
+ 2. Get your chat ID (message the bot, check `getUpdates`)
178
+ 3. Store the bot token as an API key and configure the adapter:
179
+
180
+ ```bash
181
+ # Store bot token
182
+ curl -X POST http://localhost:4242/apikeys \
183
+ -H "Authorization: Bearer <admin-token>" \
184
+ -H "Content-Type: application/json" \
185
+ -d '{"service": "adapter:telegram", "name": "botToken", "key": "123456:ABC-DEF..."}'
186
+
187
+ # Configure adapter
188
+ curl -X POST http://localhost:4242/adapters \
189
+ -H "Authorization: Bearer <admin-token>" \
190
+ -H "Content-Type: application/json" \
191
+ -d '{"type": "telegram", "enabled": true, "config": {"chatId": "987654321"}}'
192
+
193
+ # Restart to apply
194
+ curl -X POST http://localhost:4242/adapters/restart \
195
+ -H "Authorization: Bearer <admin-token>"
196
+ ```
197
+
198
+ **How it works:**
199
+ - `action:created` → sends message with Approve/Reject inline keyboard
200
+ - `action:created` with `type: 'notify'` → sends plain info message (no buttons, no resolution)
201
+ - Human taps Approve/Reject → adapter calls `POST /actions/:id/resolve`
202
+ - `action:resolved` → edits original message to show result, removes keyboard
203
+ - Only responds to callbacks from the configured `chatId` (security)
204
+ - When a `verifiedSummary` is present, the Telegram message shows the server-generated one-liner as primary action text and displays discrepancy warnings with severity icons
205
+
206
+ **Notification metadata:** When `type: 'notify'`, the Telegram adapter renders known metadata fields if present: `contractAddress` (DexScreener link), `symbol`, `marketCap`, `risk`, `socialLinks` (clickable links), and `evaluation` (full AI analysis text).
207
+
208
+ **No npm dependencies** — uses raw `fetch` calls to `api.telegram.org` and long-polling via `getUpdates`.
209
+
210
+ #### Agent Chat
211
+
212
+ The Telegram adapter supports opt-in agent chat — send text messages in Telegram and your AI agent replies.
213
+
214
+ **Enable chat:**
215
+
216
+ ```bash
217
+ curl -X POST http://localhost:4242/adapters \
218
+ -H "Authorization: Bearer <admin-token>" \
219
+ -H "Content-Type: application/json" \
220
+ -d '{"type": "telegram", "enabled": true, "config": {"chatId": "987654321"}, "chat": {"enabled": true}}'
221
+ ```
222
+
223
+ **Set default app** (which app's AI handles messages):
224
+
225
+ ```bash
226
+ curl -X POST http://localhost:4242/adapters/chat \
227
+ -H "Authorization: Bearer <admin-token>" \
228
+ -H "Content-Type: application/json" \
229
+ -d '{"defaultApp": "swap-chat"}'
230
+ ```
231
+
232
+ **How it works:**
233
+ - Human sends text in Telegram → adapter routes to app's `message` hook
234
+ - AI processes with full tool-use (wallet_api, request_human_action)
235
+ - Reply sent back as Telegram message
236
+ - Long replies (>4096 chars) are split into multiple messages
237
+ - Same rate limiting as dashboard chat (10 messages / 60 seconds per app)
238
+ - Chat is **off by default** — must be explicitly enabled with `chat: { enabled: true }`
239
+ - Approval callbacks (Approve/Reject buttons) continue to work alongside chat
240
+
241
+ ---
242
+
243
+ ## Agent Chat
244
+
245
+ Adapters can route text messages to app AI agents via the strategy engine's `handleAppMessage()`. This reuses existing message hooks, tool-use, rate limiting, and conversation memory — no new AI infrastructure.
246
+
247
+ ### How It Works
248
+
249
+ ```
250
+ Human sends text via adapter
251
+
252
+
253
+ AdapterContext.resolveApp() → find target app
254
+
255
+
256
+ AdapterContext.sendMessage() → handleAppMessage()
257
+ │ │
258
+ │ processMessage()
259
+ │ │
260
+ │ AI hook + tool-use
261
+ │ │
262
+ ▼ ▼
263
+ Adapter sends reply { reply, error }
264
+ ```
265
+
266
+ ### Configuration
267
+
268
+ Chat config is stored in `AppConfig.adapterConfig`:
269
+
270
+ ```json
271
+ {
272
+ "enabled": true,
273
+ "chat": {
274
+ "defaultApp": "swap-chat"
275
+ },
276
+ "adapters": [
277
+ {
278
+ "type": "telegram",
279
+ "enabled": true,
280
+ "config": { "chatId": "123456789" },
281
+ "chat": { "enabled": true }
282
+ }
283
+ ]
284
+ }
285
+ ```
286
+
287
+ **Two levels of config:**
288
+ - **Top-level `chat.defaultApp`**: Which app receives messages (system-wide)
289
+ - **Per-adapter `chat.enabled`**: Whether that adapter accepts chat messages (default: false)
290
+
291
+ ### Webhook Chat Endpoint
292
+
293
+ For adapters that use HTTP callbacks (webhooks, Slack, Discord):
294
+
295
+ ```bash
296
+ POST /adapters/:type/message
297
+ Content-Type: application/json
298
+ X-Signature-256: sha256=<hmac>
299
+
300
+ {
301
+ "text": "What is my balance?",
302
+ "senderId": "user-123",
303
+ "targetApp": "swap-chat"
304
+ }
305
+ ```
306
+
307
+ **Response:**
308
+ ```json
309
+ {
310
+ "success": true,
311
+ "reply": "You have 1.5 ETH in your hot wallet.",
312
+ "error": null
313
+ }
314
+ ```
315
+
316
+ **Authentication:** HMAC-SHA256 signature required if the adapter has a secret configured (same `X-Signature-256` header pattern as webhook notifications).
317
+
318
+ ### Security
319
+
320
+ - **Same auth model**: Chat messages use the app's existing token + permissions
321
+ - **Rate limiting**: Existing 10 msg/60s per app applies to adapter messages
322
+ - **Sender validation**: Telegram validates chatId; webhooks validate HMAC
323
+ - **App scoping**: The app's token determines what the AI can do
324
+ - **No new attack surface**: Messages flow through the same `handleAppMessage()` as dashboard chat
325
+
326
+ ---
327
+
328
+ ## Security Model
329
+
330
+ ### Secrets in Database, Not Config Files
331
+
332
+ Adapter secrets (bot tokens, HMAC keys) are stored in the `ApiKey` database table with `service: "adapter:<type>"`. This is the same pattern used for Alchemy API keys and other service credentials. Non-secret settings (enabled flags, chat IDs, URLs) are stored in the `AppConfig.adapterConfig` JSON field.
333
+
334
+ ### Direct In-Process Calls
335
+
336
+ The adapter router is an in-process trusted component that calls `resolveAction()` and `handleAppMessage()` directly — no admin tokens, no HTTP round-trips. This eliminates token management overhead and retry logic.
337
+
338
+ **Key properties:**
339
+ - `resolve()` calls `resolveAction()` from `server/lib/resolve-action.ts` directly
340
+ - `sendMessage()` calls `handleAppMessage()` / `enqueueAppMessage()` from the strategy engine directly
341
+ - `fetchPendingActions()` queries prisma directly (same query as `GET /actions/pending`)
342
+ - If the wallet is locked when resolving an `auth`/`agent_access` action, `resolveAction()` returns a 401-equivalent error
343
+
344
+ ### Adapter Isolation
345
+
346
+ - Each adapter runs independently — one failing adapter doesn't affect others
347
+ - Adapter errors are caught and logged per-adapter
348
+ - The router catches all adapter exceptions in `notify()` and `resolved()` calls
349
+
350
+ ### Webhook Security
351
+
352
+ - HMAC-SHA256 signatures (optional but recommended) verify payload authenticity
353
+ - Custom headers can be used for additional authentication
354
+ - Webhook URLs should use HTTPS
355
+
356
+ ### Telegram Security
357
+
358
+ - Only callbacks from the configured `chatId` are processed
359
+ - The bot token should be kept secret (treat it like a password)
360
+ - Long-polling means no publicly accessible webhook endpoint is needed
361
+
362
+ ---
363
+
364
+ ## Building Custom Adapters
365
+
366
+ Implement the `ApprovalAdapter` interface:
367
+
368
+ ```typescript
369
+ import type { ApprovalAdapter, AdapterContext, ActionNotification, ActionResolution } from './types';
370
+
371
+ class MyAdapter implements ApprovalAdapter {
372
+ readonly name = 'my-adapter';
373
+
374
+ async start(ctx: AdapterContext): Promise<void> {
375
+ // ctx.resolve(actionId, approved, opts?) — call this to resolve actions
376
+ // ctx.serverUrl — base URL of the wallet server
377
+ // ctx.sendMessage(appId, text) — route chat messages to app AI
378
+ // ctx.resolveApp(target?) — resolve which app handles chat
379
+ }
380
+
381
+ async notify(action: ActionNotification): Promise<void> {
382
+ // Present action to human: action.id, action.type, action.summary, etc.
383
+ // action.verifiedSummary contains server-generated facts and discrepancy warnings
384
+ // action.metadata?.verifiedSummary is also available (from WebSocket events)
385
+ }
386
+
387
+ async resolved(resolution: ActionResolution): Promise<void> {
388
+ // Clean up UI: resolution.id, resolution.approved, resolution.resolvedBy
389
+ }
390
+
391
+ async stop(): Promise<void> {
392
+ // Clean up resources
393
+ }
394
+ }
395
+ ```
396
+
397
+ Register it before server start:
398
+
399
+ ```typescript
400
+ import { registerAdapterType } from './server/lib/adapters';
401
+
402
+ registerAdapterType('my-adapter', (config) => new MyAdapter(config));
403
+ ```
404
+
405
+ Then configure via API:
406
+
407
+ ```bash
408
+ # Store any secrets
409
+ curl -X POST http://localhost:4242/apikeys \
410
+ -H "Authorization: Bearer <admin-token>" \
411
+ -H "Content-Type: application/json" \
412
+ -d '{"service": "adapter:my-adapter", "name": "apiKey", "key": "secret-value"}'
413
+
414
+ # Configure adapter
415
+ curl -X POST http://localhost:4242/adapters \
416
+ -H "Authorization: Bearer <admin-token>" \
417
+ -H "Content-Type: application/json" \
418
+ -d '{"type": "my-adapter", "enabled": true, "config": {"myOption": "value"}}'
419
+
420
+ # Restart
421
+ curl -X POST http://localhost:4242/adapters/restart \
422
+ -H "Authorization: Bearer <admin-token>"
423
+ ```
424
+
425
+ ---
426
+
427
+ ## Architecture
428
+
429
+ ```
430
+ ┌──────────────────────────────────────────────────────────────┐
431
+ │ ApprovalRouter │
432
+ │ ┌─────────┐ ┌─────────────┐ ┌──────────────────────────┐ │
433
+ │ │WebSocket │ │ Admin Token │ │ Adapters │ │
434
+ │ │Listener │──│ (lazy-init) │ │ ├── WebhookAdapter │ │
435
+ │ │ │ │ │ │ ├── TelegramAdapter │ │
436
+ │ └────┬─────┘ └──────┬──────┘ │ └── CustomAdapter... │ │
437
+ │ │ │ └──────────────────────────┘ │
438
+ │ │ │ │
439
+ │ action:created ──────┼──► adapter.notify() │
440
+ │ action:resolved ─────┼──► adapter.resolved() │
441
+ │ action:executed ─────┼──► (app-scoped, not adapter) │
442
+ │ │ │
443
+ │ adapter calls ───────┤──► POST /actions/:id/resolve │
444
+ │ │ │
445
+ │ chat message ────────┼──► sendMessage() → engine │
446
+ │ resolveApp() ─────┼──► DB lookup (cached) │
447
+ └──────────────────────────────────────────────────────────────┘
448
+ ```
449
+
450
+ **Storage:**
451
+
452
+ | Data | Storage | Key |
453
+ |------|---------|-----|
454
+ | Secrets (bot tokens, HMAC keys) | `ApiKey` table | `service: "adapter:<type>"` |
455
+ | Settings (enabled, chatId, URL) | `AppConfig.adapterConfig` | JSON field |
456
+
457
+ **Files:**
458
+
459
+ | File | Description |
460
+ |------|-------------|
461
+ | `server/lib/adapters/types.ts` | Core interfaces |
462
+ | `server/lib/adapters/router.ts` | WebSocket listener + resolve proxy |
463
+ | `server/lib/adapters/webhook.ts` | Webhook adapter |
464
+ | `server/lib/adapters/telegram.ts` | Telegram adapter |
465
+ | `server/lib/adapters/factory.ts` | Registry + factory + `loadAdaptersFromDb` |
466
+ | `server/lib/adapters/index.ts` | Public exports |
467
+ | `server/routes/adapters.ts` | Admin REST endpoints |