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,121 @@
1
+ # Best Practices
2
+
3
+ Guidance for humans, agents, and developers working with AuraWallet.
4
+
5
+ ---
6
+
7
+ ## For Humans
8
+
9
+ ### Password Management
10
+
11
+ - Use a strong, unique password for each vault (min 8 characters, passphrase recommended)
12
+ - Never store your vault password digitally — treat it like a seed phrase
13
+ - If you forget your password, the seed phrase is your only recovery path
14
+
15
+ ### Spending Limit Strategy
16
+
17
+ - Start with low limits (`fund: 0.1`) and increase as you build trust with an agent's behavior
18
+ - Set per-type limits: `fund` controls cold wallet exposure, `send` and `swap` control hot wallet activity
19
+ - Review token spending in the dashboard regularly — spending resets on server restart
20
+
21
+ ### Multi-Vault Usage
22
+
23
+ - Use separate vaults for separate purposes (e.g., trading vault, savings vault)
24
+ - Each vault has its own password — unlocking one does not unlock others
25
+ - Hot wallets are bound to their vault and cannot be moved between vaults
26
+
27
+ ### Backup Schedule
28
+
29
+ - Back up your seed phrase on paper immediately after vault creation
30
+ - Store it offline in a secure location (safe, safety deposit box)
31
+ - Never photograph, screenshot, or digitally copy your seed phrase
32
+ - Test your backup by verifying the cold wallet address matches
33
+
34
+ ### Token Hygiene
35
+
36
+ - Revoke tokens you're no longer using — don't leave stale tokens active
37
+ - Each agent should have its own token with its own limits
38
+ - Review active tokens periodically in the dashboard
39
+ - Server restart invalidates all tokens — this is intentional security, not a bug
40
+
41
+ ---
42
+
43
+ ## For Agents
44
+
45
+ ### Permission Scoping
46
+
47
+ - Request the minimum permissions needed for your task
48
+ - Use `trade:all` for trading operations instead of listing individual permissions
49
+ - `trade:all` does NOT include `apikey:set` or `adapter:manage` — request those explicitly if needed for onboarding
50
+ - Never request `admin:*` unless you genuinely need full access
51
+
52
+ ### Token Lifecycle
53
+
54
+ - Tokens live only in server memory — expect them to vanish on restart
55
+ - Always implement re-authentication logic: catch 401 → re-request via `POST /auth`
56
+ - Don't persist tokens to disk — request fresh ones each session
57
+ - The token from `GET /auth/:id?secret=...` can only be read once — save it immediately
58
+
59
+ ### Error Handling Patterns
60
+
61
+ | Error | Pattern |
62
+ |-------|---------|
63
+ | 401 `Invalid or expired token` | Re-request token via `POST /auth`, wait for human approval |
64
+ | 401 `Cold wallet must be unlocked` | Tell human to unlock at dashboard or `http://localhost:4242/unlock` |
65
+ | 403 `Insufficient permissions` | Use `request_human_action` for one-time approval, or `POST /auth/request-permissions` for permanent upgrade |
66
+ | 403 `Amount exceeds spending limit` | Use `request_human_action` with the specific amount needed |
67
+ | Connection refused | Server not running — tell human to run `npx aurawallet start` |
68
+
69
+ ### Spending Budget Management
70
+
71
+ - Track your remaining budget by remembering cumulative spend per type
72
+ - When approaching a limit, use `request_human_action` to request approval for the specific operation
73
+ - Budget resets on server restart (new token required anyway)
74
+ - For ongoing operations, request higher initial limits rather than repeatedly escalating
75
+
76
+ ### Multi-Step Operations
77
+
78
+ - Check `GET /setup` before starting any workflow — know what's configured
79
+ - For operations that require multiple endpoints (e.g., create wallet → fund → swap), verify each step succeeded before proceeding
80
+ - If a multi-step operation fails partway through, report what completed and what didn't — don't silently retry
81
+
82
+ ---
83
+
84
+ ## For Developers
85
+
86
+ ### Route Auth Patterns
87
+
88
+ Every route follows one of these patterns:
89
+
90
+ | Pattern | Example | How |
91
+ |---------|---------|-----|
92
+ | Public | `GET /health` | No auth check |
93
+ | Any valid token | `GET /wallets` | `requireAuth` middleware |
94
+ | Specific permission | `POST /swap` | `requireAuth` + `requirePermission('swap')` |
95
+ | Admin only | `POST /nuke` | `requireAuth` + `requirePermission('admin:*')` |
96
+ | Wallet access | `POST /send` | Auth + permission + `tokenCanAccessWallet()` |
97
+
98
+ ### Adding New Permissions Checklist
99
+
100
+ 1. Add the permission string to the relevant route in `server/routes/`
101
+ 2. Add the permission to the reference table in `docs/AUTH.md`
102
+ 3. If it belongs in a compound permission (`trade:all`, `wallet:write`), update the expansion in `server/lib/auth.ts`
103
+ 4. Add the route → permission mapping to the Route → Permission table in `docs/AUTH.md`
104
+ 5. Update `docs/security.md` if the permission affects the security model
105
+
106
+ ### Security Checklist
107
+
108
+ - [ ] Auth decisions use memory only (SIGNING_KEY, sessions Map) — never the database
109
+ - [ ] Wallet ownership checked via `tokenCanAccessWallet()` before any wallet operation
110
+ - [ ] Spending limits checked and updated atomically in the sessions Map
111
+ - [ ] Cold wallet operations require the vault to be unlocked (mnemonic in memory)
112
+ - [ ] New endpoints have appropriate rate limiting tier
113
+ - [ ] Input validation on all user-supplied data (amounts, addresses, strings)
114
+ - [ ] No secrets logged or returned in error messages
115
+
116
+ ### Testing Patterns
117
+
118
+ - Auth tests should verify both positive (has permission) and negative (lacks permission) cases
119
+ - Spending limit tests should verify enforcement, accumulation, and the boundary case (exact limit)
120
+ - Wallet ownership tests should verify both tokenHash-based and walletAccess-based access
121
+ - Server restart tests should verify all tokens are invalidated and sessions cleared
package/docs/CLI.md ADDED
@@ -0,0 +1,61 @@
1
+ # CLI (`aura` / `aurawallet`)
2
+
3
+ Binary aliases:
4
+
5
+ - `npx aurawallet ...`
6
+ - `npx aura ...` (same binary)
7
+
8
+ ## Core commands
9
+
10
+ - `init` — first-time setup
11
+ - `start` / `stop` / `status` / `unlock`
12
+ - `restore` — backup restore
13
+ - `mcp` — run MCP server
14
+ - `vault` — credential retrieval
15
+ - `env` — `.aura`-based env loading
16
+ - `shell-hook` — auto-load env on `cd`
17
+
18
+ ## `vault` examples
19
+
20
+ ```bash
21
+ npx aurawallet vault list
22
+ npx aurawallet vault get openai-prod --field api_key
23
+ npx aurawallet vault get github-admin --totp
24
+ npx aurawallet vault get stripe --json
25
+ ```
26
+
27
+ Auth behavior:
28
+
29
+ - default: Unix socket bootstrap (`/tmp/aura-cli-{uid}.sock`)
30
+ - headless/CI: set `AURA_TOKEN`
31
+
32
+ ## `env` examples
33
+
34
+ ```bash
35
+ npx aurawallet env init --from .env
36
+ npx aurawallet env check
37
+ npx aurawallet env list
38
+ npx aurawallet env -- npm run dev
39
+ npx aurawallet env inject
40
+ ```
41
+
42
+ ## `shell-hook`
43
+
44
+ ```bash
45
+ npx aurawallet shell-hook install
46
+ cd my-project
47
+ npx aurawallet shell-hook allow
48
+ ```
49
+
50
+ - Requires whitelist (`shell-allowed.json`)
51
+ - Caches resolved vars with encrypted-at-rest cache blobs
52
+
53
+ ## `restore`
54
+
55
+ ```bash
56
+ npx aurawallet restore --list
57
+ npx aurawallet restore --latest
58
+ npx aurawallet restore --dry-run --latest
59
+ ```
60
+
61
+ Restores DB + credential files, then runs Prisma migrations.
@@ -0,0 +1,452 @@
1
+ # Developing Apps
2
+
3
+ Detailed reference for building AuraWallet UI apps — manifest format, SDK API, theming, security, and storage.
4
+
5
+ For a high-level overview and installation guide, see [APPS.md](./APPS.md). For building strategy apps (tick-based and message-based), see [DEVELOPING-STRATEGIES.md](./wallet/DEVELOPING-STRATEGIES.md). For AI engine internals, see [AI.md](./wallet/AI.md).
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [File Structure](#file-structure)
10
+ 2. [App SDK API (window.AuraApp)](#app-sdk-api-windowauraapp)
11
+ 3. [Theming](#theming)
12
+ 4. [Manifest Reference](#manifest-reference)
13
+ 5. [Security Model](#security-model)
14
+ 6. [Storage API (REST)](#storage-api-rest)
15
+ 7. [Example: Annotated Kanban App](#example-annotated-kanban-app)
16
+
17
+ ---
18
+
19
+ ## File Structure
20
+
21
+ ```
22
+ apps/
23
+ my-app/
24
+ app.md # Manifest (YAML frontmatter + description)
25
+ index.html # UI entry point (HTML + inline JS/CSS)
26
+ ```
27
+
28
+ - `app.md` is required. The engine discovers apps by scanning `apps/*/app.md`.
29
+ - `index.html` is optional. Apps without it show a default placeholder on the dashboard. Strategy-only (headless) apps commonly omit it.
30
+ - The folder name becomes the app `id`.
31
+
32
+ ---
33
+
34
+ ## App SDK API (`window.AuraApp`)
35
+
36
+ The SDK is automatically injected into every installed app iframe. It is available as `window.AuraApp` (or just `AuraApp`). Storage methods and `fetch()` use direct HTTP calls with an injected Bearer token; `send()` uses direct HTTP; `on()` uses postMessage to communicate with the host.
37
+
38
+ ### `AuraApp.storage.get(key)`
39
+
40
+ Read a value from persistent storage.
41
+
42
+ ```javascript
43
+ var data = await AuraApp.storage.get('myKey');
44
+ // data is the parsed JSON value, or null if not found
45
+ ```
46
+
47
+ - **Parameters:** `key` (string) -- the storage key
48
+ - **Returns:** `Promise<any>` -- the stored value, or `null` if the key does not exist
49
+
50
+ ### `AuraApp.storage.set(key, value)`
51
+
52
+ Write a value to persistent storage. Values are JSON-serialized.
53
+
54
+ ```javascript
55
+ await AuraApp.storage.set('myKey', { count: 42, items: ['a', 'b'] });
56
+ ```
57
+
58
+ - **Parameters:** `key` (string), `value` (any JSON-serializable value)
59
+ - **Returns:** `Promise<any>` -- the stored value on success
60
+ - **Behavior:** Upserts -- creates the key if it does not exist, updates if it does
61
+
62
+ ### `AuraApp.storage.delete(key)`
63
+
64
+ Delete a key from persistent storage.
65
+
66
+ ```javascript
67
+ var ok = await AuraApp.storage.delete('myKey');
68
+ ```
69
+
70
+ - **Parameters:** `key` (string)
71
+ - **Returns:** `Promise<boolean>` -- `true` on success
72
+ - **Error:** Rejects if the key does not exist
73
+
74
+ ### `AuraApp.send(message)`
75
+
76
+ Send a natural language message to the app's AI and receive a reply.
77
+
78
+ ```javascript
79
+ var reply = await AuraApp.send('Check the ETH balance on my hot wallet');
80
+ console.log(reply); // "Your hot wallet has 2.5 ETH"
81
+ ```
82
+
83
+ - **Parameters:** `message` (string) -- natural language instruction
84
+ - **Returns:** `Promise<string | null>` -- the AI's text reply, or `null` if no reply was generated
85
+ - **Rate limit:** 10 messages per 60 seconds per app
86
+ - **Requires:** App must have a `hooks.message` field in its manifest
87
+
88
+ ### `AuraApp.fetch(url, options)`
89
+
90
+ Fetch an external URL via the server-side proxy. Apps run in sandboxed `blob:` iframes with an opaque origin, so direct `fetch()` calls to external APIs will fail with CORS errors. This method proxies the request through the wallet server.
91
+
92
+ ```javascript
93
+ // Simple GET
94
+ var data = await AuraApp.fetch('https://api.example.com/prices');
95
+
96
+ // POST with headers
97
+ var result = await AuraApp.fetch('https://api.example.com/submit', {
98
+ method: 'POST',
99
+ headers: { 'Content-Type': 'application/json' },
100
+ body: JSON.stringify({ token: '0xABC' })
101
+ });
102
+ ```
103
+
104
+ - **Parameters:**
105
+ - `url` (string) -- the external URL to fetch (must be HTTP or HTTPS)
106
+ - `options` (object, optional): `method`, `headers`, `body`
107
+ - **Returns:** `Promise<any>` -- parsed JSON or text string
108
+ - **Rate limit:** 60 requests per 60 seconds per app
109
+ - **Restrictions:** Only HTTP/HTTPS; private IPs blocked (SSRF prevention); 10s timeout
110
+
111
+ ### `AuraApp.action(params)`
112
+
113
+ Request human approval for a privileged operation. Creates a pending action request. On approval, a temporary scoped token is created and the action auto-executes.
114
+
115
+ ```javascript
116
+ var result = await AuraApp.action({
117
+ summary: 'Buy $DOGE2 for 0.005 ETH',
118
+ permissions: ['swap'],
119
+ limits: { swap: 0.005 },
120
+ walletAccess: ['0x...'],
121
+ ttl: 60
122
+ });
123
+ // result = { success: true, requestId: '...', secret: '...' }
124
+ ```
125
+
126
+ - **Parameters:** `params` (object): `summary` (string, required), `permissions` (string[], required), `limits` (object), `walletAccess` (string[]), `ttl` (number)
127
+ - **Returns:** `Promise<{ success, requestId, secret }>`
128
+ - **Requires:** `action:create` permission in the manifest
129
+
130
+ **Event sequence on approval:** `action:resolved` → `action:executed` → `agent:message`
131
+
132
+ ### `AuraApp.on(channel, callback)`
133
+
134
+ Subscribe to a real-time event channel. Events are forwarded from the WebSocket to your iframe via postMessage.
135
+
136
+ ```javascript
137
+ var unsub = AuraApp.on('tx:created', function(data) {
138
+ console.log('New transaction:', data);
139
+ });
140
+ unsub(); // unsubscribe
141
+ ```
142
+
143
+ - **Parameters:** `channel` (string), `callback` (function)
144
+ - **Returns:** unsubscribe function
145
+
146
+ #### Common Event Channels
147
+
148
+ | Channel | Data | Description |
149
+ |---------|------|-------------|
150
+ | `tx:created` | `{walletAddress, id, type, txHash, amount}` | New transaction |
151
+ | `asset:changed` | `{walletAddress, tokenAddress, symbol}` | Asset added/removed |
152
+ | `wallet:created` | `{address, tier, chain}` | New wallet created |
153
+ | `strategy:tick` | `{strategyId, intents, duration, state}` | Strategy tick completed |
154
+ | `strategy:error` | `{strategyId, error, phase}` | Strategy error |
155
+ | `action:executed` | `{requestId, approved, status, result}` | Action auto-executed (app-scoped) |
156
+ | `agent:message` | `{message}` | AI follow-up after action (app-scoped) |
157
+
158
+ Strategy hooks can emit custom app-scoped events via the `emit` field in hook responses:
159
+
160
+ ```json
161
+ { "emit": { "channel": "price-update", "data": { "price": 42 } } }
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Theming
167
+
168
+ The host injects CSS variables from the current theme into every app iframe. Use these to match the dashboard in both light and dark modes.
169
+
170
+ ### CSS Variables
171
+
172
+ | Variable | Purpose | Fallback |
173
+ |----------|---------|----------|
174
+ | `--color-background` | Page background | `#fafafa` |
175
+ | `--color-background-alt` | Alternate background | `#f4f4f5` |
176
+ | `--color-surface` | App/card background | `#ffffff` |
177
+ | `--color-surface-alt` | Alternate surface | `#f9fafb` |
178
+ | `--color-text` | Primary text | `#0a0a0a` |
179
+ | `--color-text-muted` | Secondary text | `#6b7280` |
180
+ | `--color-text-faint` | Tertiary text | `#9ca3af` |
181
+ | `--color-border` | Standard borders | `#d4d4d8` |
182
+ | `--color-border-muted` | Subtle borders | `#e4e4e7` |
183
+ | `--color-border-focus` | Focused borders | `#0a0a0a` |
184
+ | `--color-accent` | Accent/highlight | `#ccff00` |
185
+ | `--color-info` | Info accent | `#0047ff` |
186
+ | `--color-success` | Success state | `#22c55e` |
187
+ | `--color-warning` | Warning state | `#ff4d00` |
188
+
189
+ Always provide fallback values:
190
+
191
+ ```css
192
+ body {
193
+ background: var(--color-surface, #fff);
194
+ color: var(--color-text, #0a0a0a);
195
+ font-family: ui-monospace, monospace;
196
+ }
197
+ ```
198
+
199
+ ### Injected Base Styles
200
+
201
+ The host injects a base reset into every app:
202
+
203
+ ```css
204
+ * { margin: 0; padding: 0; box-sizing: border-box; }
205
+ body {
206
+ font-family: ui-monospace, monospace;
207
+ overflow: auto;
208
+ background: var(--color-surface, #fff);
209
+ color: var(--color-text, #0a0a0a);
210
+ }
211
+ ```
212
+
213
+ Your app's own `<style>` blocks are applied after this reset.
214
+
215
+ ---
216
+
217
+ ## Manifest Reference
218
+
219
+ The manifest is a Markdown file with YAML frontmatter. The body text after `---` is the description shown in the App Store.
220
+
221
+ ```markdown
222
+ ---
223
+ name: My App
224
+ icon: Zap
225
+ # ...fields...
226
+ ---
227
+
228
+ Description shown in the App Store listing.
229
+ ```
230
+
231
+ ### All Fields
232
+
233
+ | Field | Type | Required | Default | Description |
234
+ |-------|------|:---:|---------|-------------|
235
+ | `name` | string | yes | folder name | Display name |
236
+ | `icon` | string | no | `Box` | [Lucide](https://lucide.dev) icon name |
237
+ | `category` | string | no | `general` | App Store category filter |
238
+ | `size` | string | no | `1x1` | Default grid size `WxH` (1=320x280, 2=640x560, 3=960x840) |
239
+ | `permissions` | string[] | no | `[]` | Wallet permissions the app needs |
240
+ | `data` | string[] | no | `[]` | Real-time WebSocket channels to subscribe to (informational) |
241
+
242
+ ### Permissions
243
+
244
+ Declare the permissions your app needs. Apps with permissions or limits require human approval before the engine creates auth tokens for them. Zero-permission apps skip approval.
245
+
246
+ Valid permission strings (see [AUTH.md](./AUTH.md) for full details):
247
+
248
+ | Permission | Description |
249
+ |------------|-------------|
250
+ | `wallet:list` | List/view wallets and balances |
251
+ | `wallet:create:hot` | Create hot wallets |
252
+ | `wallet:create:temp` | Create temp wallets |
253
+ | `wallet:rename` | Rename wallets |
254
+ | `wallet:export` | Export private keys |
255
+ | `send:hot` | Send from hot wallets |
256
+ | `send:temp` | Send from temp wallets |
257
+ | `swap` | Execute token swaps |
258
+ | `fund` | Transfer cold to hot |
259
+ | `launch` | Launch tokens via Doppler |
260
+ | `action:create` | Create human action requests |
261
+ | `apikey:get` | Read API keys |
262
+ | `apikey:set` | Manage API keys |
263
+ | `strategy:read` | View strategies |
264
+ | `strategy:manage` | Enable/disable strategies |
265
+ | `trade:all` | Compound: all trading + apikey:get |
266
+ | `wallet:write` | Compound: all wallet write ops |
267
+
268
+ ### Extending Your App with Strategy Fields
269
+
270
+ Any app can become AI-powered by adding strategy fields to its `app.md` manifest. A strategy is just an app that activates the AI engine — there is no separate directory or manifest format.
271
+
272
+ The strategy-specific fields are:
273
+
274
+ | Field | Purpose |
275
+ |-------|---------|
276
+ | `ticker` | Schedule tick interval (`sniper`, `active`, `standard`, `slow`, `maintenance`) |
277
+ | `jobs` | Multi-interval scheduling (alternative to `ticker`) |
278
+ | `hooks` | Natural-language AI instructions (`tick`, `message`, `init`, `execute`, `result`, `shutdown`) |
279
+ | `sources` | External data endpoints fetched each tick |
280
+ | `keys` | API key declarations |
281
+ | `config` | Strategy configuration passed to hooks |
282
+ | `limits` | Spending caps (`fund`, `send`) |
283
+ | `allowedHosts` | Hostnames allowed for external fetches |
284
+
285
+ Adding any of these fields turns your app into a strategy. The base fields (`name`, `icon`, `category`, `size`, `permissions`, `data`) remain the same.
286
+
287
+ See [DEVELOPING-STRATEGIES.md](./wallet/DEVELOPING-STRATEGIES.md) for the full reference on these fields, hook lifecycle, sources, intents, and examples.
288
+
289
+ ---
290
+
291
+ ## Security Model
292
+
293
+ Installed apps run in a strict sandbox with isolation guarantees.
294
+
295
+ ### Sandbox Restrictions
296
+
297
+ The iframe is created with `sandbox="allow-scripts"` **without** `allow-same-origin`:
298
+
299
+ | Capability | Allowed? | Reason |
300
+ |-----------|----------|--------|
301
+ | JavaScript execution | Yes | `allow-scripts` is set |
302
+ | Access parent DOM | No | No `allow-same-origin` |
303
+ | Read/write cookies | No | Opaque origin |
304
+ | Use localStorage/sessionStorage | No | Opaque origin |
305
+ | Submit forms | No | No `allow-forms` |
306
+ | Open popups | No | No `allow-popups` |
307
+ | Navigate top frame | No | No `allow-top-navigation` |
308
+
309
+ Apps are loaded via blob URLs (opaque origin `null`). Each app runs in complete isolation from the parent page and other apps.
310
+
311
+ ### Communication Model
312
+
313
+ ```
314
+ App iframe --fetch()--------> Express :4242/apps/<id>/storage/* (Bearer token)
315
+ App iframe --fetch()--------> Express :4242/apps/<id>/message (Bearer token)
316
+ App iframe --fetch()--------> Express :4242/apps/<id>/fetch (Bearer token, proxied)
317
+ App iframe --postMessage--> Host (subscriptions via on())
318
+ ```
319
+
320
+ The Bearer token is injected as `window.__AURA_TOKEN__` before the SDK loads. Tokens are scoped per-app and carry only `app:storage` permission by default.
321
+
322
+ ### What Apps Cannot Do
323
+
324
+ - Access the parent page's DOM, JavaScript scope, or React state
325
+ - Read admin tokens or wallet credentials (apps get scoped tokens)
326
+ - Access other apps' storage (tokens scoped by app ID)
327
+ - Load external scripts (`<script src="...">` tags are stripped)
328
+ - Fetch private/internal IPs (SSRF prevention)
329
+
330
+ ---
331
+
332
+ ## Storage API (REST)
333
+
334
+ The SDK wraps these endpoints, but they can also be called directly with a Bearer token.
335
+
336
+ ### Endpoints (Express :4242)
337
+
338
+ | Endpoint | Method | Permission | Description |
339
+ |----------|--------|------------|-------------|
340
+ | `/apps/:appId/storage` | GET | `app:storage` | List all keys and values |
341
+ | `/apps/:appId/storage/:key` | GET | `app:storage` | Read a single value |
342
+ | `/apps/:appId/storage/:key` | PUT | `app:storage` | Write a value (upsert) |
343
+ | `/apps/:appId/storage/:key` | DELETE | `app:storage` | Delete a key |
344
+ | `/apps/:appId/apikey/:keyName` | GET | `app:accesskey` | Read an API key |
345
+ | `/apps/:appId/approve` | POST | `strategy:manage` | Approve app permissions |
346
+ | `/apps/:appId/approve` | DELETE | `strategy:manage` | Revoke app approval |
347
+ | `/apps/:appId/token` | GET | admin | Get app's Bearer token |
348
+
349
+ Storage is scoped by `appId`. A token with `app:storage` can only access storage matching its own `agentId`. Use `app:storage:all` for cross-app access.
350
+
351
+ ---
352
+
353
+ ## Example: Annotated Kanban App
354
+
355
+ A complete UI app (`apps/example-kanban/`) demonstrating storage, theming, and vanilla JS patterns.
356
+
357
+ ### Manifest (`app.md`)
358
+
359
+ ```markdown
360
+ ---
361
+ name: Kanban Board
362
+ icon: LayoutGrid
363
+ category: productivity
364
+ size: 2x2
365
+ permissions:
366
+ data:
367
+ ---
368
+
369
+ A simple kanban board for tracking tasks. Demonstrates app storage
370
+ persistence -- your cards survive page reloads.
371
+ ```
372
+
373
+ ### Entry Point (`index.html`)
374
+
375
+ ```html
376
+ <!DOCTYPE html>
377
+ <html>
378
+ <head>
379
+ <style>
380
+ body {
381
+ font-family: ui-monospace, monospace;
382
+ background: var(--color-surface, #fff);
383
+ color: var(--color-text, #0a0a0a);
384
+ padding: 8px;
385
+ font-size: 10px;
386
+ }
387
+ .column {
388
+ border: 1px solid var(--color-border, #d4d4d8);
389
+ background: var(--color-background-alt, #f4f4f5);
390
+ }
391
+ .card {
392
+ background: var(--color-surface, #fff);
393
+ border: 1px solid var(--color-border, #d4d4d8);
394
+ }
395
+ .card:hover {
396
+ border-color: var(--color-border-focus, #0a0a0a);
397
+ }
398
+ </style>
399
+ </head>
400
+ <body>
401
+ <div class="header">
402
+ <span class="title">Kanban</span>
403
+ <button class="add-btn" onclick="showAddForm()">+ ADD</button>
404
+ </div>
405
+ <div class="columns" id="columns"></div>
406
+
407
+ <script>
408
+ var app = window.AuraApp;
409
+ var state = { cards: [] };
410
+
411
+ function save() {
412
+ if (app && app.storage) {
413
+ app.storage.set('kanban', state).catch(function() {});
414
+ }
415
+ }
416
+
417
+ function init() {
418
+ if (app && app.storage) {
419
+ app.storage.get('kanban').then(function(data) {
420
+ if (data && data.cards) { state = data; }
421
+ render();
422
+ }).catch(function() { render(); });
423
+ } else {
424
+ render();
425
+ }
426
+ }
427
+
428
+ function escapeHtml(str) {
429
+ var div = document.createElement('div');
430
+ div.textContent = str;
431
+ return div.innerHTML;
432
+ }
433
+
434
+ function render() {
435
+ // Build columns, cards, drag-and-drop handlers
436
+ // Each state change calls save() then render()
437
+ }
438
+
439
+ init();
440
+ </script>
441
+ </body>
442
+ </html>
443
+ ```
444
+
445
+ ### Key Patterns
446
+
447
+ 1. **Theme integration** -- All colors use `var(--color-*)` with fallbacks
448
+ 2. **Storage persistence** -- `storage.get()` on init, `storage.set()` on every change
449
+ 3. **Graceful degradation** -- Works even if `AuraApp` is not available
450
+ 4. **XSS prevention** -- User input escaped via `textContent`/`innerHTML`
451
+ 5. **Vanilla JS only** -- No build step, no external dependencies
452
+ 6. **Inline everything** -- All CSS and JS in a single file (external `<script src>` tags are stripped)