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,421 @@
1
+ /**
2
+ * Server-generated verified summaries for human action approval.
3
+ *
4
+ * Agents control the `summary` text shown to humans, but the server has the actual
5
+ * action parameters (endpoint, body, amounts, recipients). This module generates
6
+ * a trustworthy summary from the pre-computed action, detects discrepancies between
7
+ * the agent's claim and the actual action, and flags mismatches.
8
+ */
9
+
10
+ import { ethers } from 'ethers';
11
+ import { isSolanaChain, getNativeCurrency } from './address';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Interfaces
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export interface VerifiedFact {
18
+ label: string;
19
+ value: string;
20
+ /** Raw value for programmatic use (e.g., BigInt amount string) */
21
+ raw?: string;
22
+ }
23
+
24
+ export interface SummaryDiscrepancy {
25
+ field: string;
26
+ agentClaim: string;
27
+ actual: string;
28
+ severity: 'info' | 'warning' | 'critical';
29
+ }
30
+
31
+ export interface VerifiedSummary {
32
+ /** Endpoint being called, e.g. "/swap" */
33
+ action: string;
34
+ /** Human-readable one-liner generated from actual action params */
35
+ oneLiner: string;
36
+ /** Structured facts extracted from the action body */
37
+ facts: VerifiedFact[];
38
+ /** Human-readable permission labels */
39
+ permissionLabels: string[];
40
+ /** Human-readable limit labels */
41
+ limitLabels: string[];
42
+ /** Human-readable wallet access labels */
43
+ walletAccessLabels: string[];
44
+ /** TTL label */
45
+ ttlLabel: string;
46
+ /** Agent ID that requested this action */
47
+ agentId: string;
48
+ /** Discrepancies between agent summary and actual action */
49
+ discrepancies: SummaryDiscrepancy[];
50
+ /** True if no critical discrepancies found */
51
+ verified: boolean;
52
+ /** ISO timestamp of when this summary was generated */
53
+ generatedAt: string;
54
+ }
55
+
56
+ // ---------------------------------------------------------------------------
57
+ // Permission labels
58
+ // ---------------------------------------------------------------------------
59
+
60
+ export const PERMISSION_LABELS: Record<string, string> = {
61
+ 'swap': 'Can swap tokens via DEX',
62
+ 'send:hot': 'Can send from hot wallets',
63
+ 'send:temp': 'Can send from temp wallets',
64
+ 'fund': 'Can transfer cold → hot',
65
+ 'launch': 'Can launch tokens',
66
+ 'wallet:create:hot': 'Can create hot wallets',
67
+ 'wallet:create:temp': 'Can create temp wallets',
68
+ 'wallet:export': 'Can export private keys',
69
+ 'wallet:list': 'Can list wallets',
70
+ 'wallet:rename': 'Can rename wallets',
71
+ };
72
+
73
+ // ---------------------------------------------------------------------------
74
+ // Helpers
75
+ // ---------------------------------------------------------------------------
76
+
77
+ function shortAddr(addr: string): string {
78
+ if (!addr || addr.length < 10) return addr || 'unknown';
79
+ return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
80
+ }
81
+
82
+ function formatAmount(amountRaw: string | undefined, chain: string | undefined): { display: string; ethValue: number } {
83
+ if (!amountRaw) return { display: 'unknown', ethValue: 0 };
84
+
85
+ const isSol = chain ? isSolanaChain(chain) : false;
86
+ const symbol = chain ? getNativeCurrency(chain) : 'ETH';
87
+
88
+ try {
89
+ if (isSol) {
90
+ // Lamports → SOL (1 SOL = 1e9 lamports)
91
+ const solValue = Number(BigInt(amountRaw)) / 1e9;
92
+ return { display: `${solValue} ${symbol}`, ethValue: solValue };
93
+ }
94
+
95
+ // EVM amounts are always in wei
96
+ const amt = BigInt(amountRaw);
97
+ const ethValue = parseFloat(ethers.formatEther(amt));
98
+ return { display: `${ethers.formatEther(amt)} ${symbol}`, ethValue };
99
+ } catch {
100
+ // Fall through
101
+ }
102
+
103
+ return { display: `${amountRaw}`, ethValue: 0 };
104
+ }
105
+
106
+ function formatPermissionLabel(perm: string): string {
107
+ return PERMISSION_LABELS[perm] || perm;
108
+ }
109
+
110
+ function formatTtl(ttl: number | undefined): string {
111
+ if (!ttl) return 'Default';
112
+ if (ttl < 60) return `${ttl}s`;
113
+ if (ttl < 3600) return `${Math.floor(ttl / 60)}m`;
114
+ return `${Math.floor(ttl / 3600)}h`;
115
+ }
116
+
117
+ // ---------------------------------------------------------------------------
118
+ // Per-endpoint fact extraction
119
+ // ---------------------------------------------------------------------------
120
+
121
+ interface ActionInput {
122
+ endpoint?: string;
123
+ method?: string;
124
+ body?: Record<string, unknown>;
125
+ }
126
+
127
+ function extractSwapFacts(body: Record<string, unknown>): { facts: VerifiedFact[]; oneLiner: string } {
128
+ const from = body.from as string | undefined;
129
+ const token = body.token as string | undefined;
130
+ const direction = (body.direction as string) || 'buy';
131
+ const amount = body.amount as string | undefined;
132
+ const slippage = body.slippage as number | undefined;
133
+ const chain = (body.chain as string) || 'base';
134
+ const dex = body.dex as string | undefined;
135
+
136
+ const { display: amountDisplay } = formatAmount(amount, chain);
137
+ const symbol = getNativeCurrency(chain);
138
+
139
+ const facts: VerifiedFact[] = [];
140
+ if (from) facts.push({ label: 'From wallet', value: shortAddr(from), raw: from });
141
+ if (token) facts.push({ label: 'Token', value: shortAddr(token), raw: token });
142
+ facts.push({ label: 'Direction', value: direction });
143
+ if (amount) facts.push({ label: 'Amount', value: amountDisplay, raw: amount });
144
+ if (slippage !== undefined) facts.push({ label: 'Slippage', value: `${slippage}%` });
145
+ facts.push({ label: 'Chain', value: chain });
146
+ if (dex) facts.push({ label: 'DEX', value: dex });
147
+
148
+ const tokenDisplay = token ? shortAddr(token) : 'token';
149
+ const oneLiner = direction === 'sell'
150
+ ? `Sell ${tokenDisplay} for ${amountDisplay} on ${chain}`
151
+ : `Buy ${tokenDisplay} with ${amountDisplay} on ${chain}`;
152
+
153
+ return { facts, oneLiner };
154
+ }
155
+
156
+ function extractSendFacts(body: Record<string, unknown>): { facts: VerifiedFact[]; oneLiner: string } {
157
+ const from = body.from as string | undefined;
158
+ const to = body.to as string | undefined;
159
+ const amount = body.amount as string | undefined;
160
+ const chain = (body.chain as string) || 'base';
161
+ const hasRawTx = !!body.transaction;
162
+
163
+ const { display: amountDisplay } = formatAmount(amount, chain);
164
+
165
+ const facts: VerifiedFact[] = [];
166
+ if (from) facts.push({ label: 'From', value: shortAddr(from), raw: from });
167
+ if (to) facts.push({ label: 'To', value: shortAddr(to), raw: to });
168
+ if (amount) facts.push({ label: 'Amount', value: amountDisplay, raw: amount });
169
+ facts.push({ label: 'Chain', value: chain });
170
+ if (hasRawTx) facts.push({ label: 'Raw transaction', value: 'Yes (Solana)' });
171
+
172
+ const toDisplay = to ? shortAddr(to) : 'unknown';
173
+ const oneLiner = hasRawTx
174
+ ? `Send raw transaction to ${toDisplay} on ${chain}`
175
+ : `Send ${amountDisplay} to ${toDisplay} on ${chain}`;
176
+
177
+ return { facts, oneLiner };
178
+ }
179
+
180
+ function extractFundFacts(body: Record<string, unknown>): { facts: VerifiedFact[]; oneLiner: string } {
181
+ const to = body.to as string | undefined;
182
+ const amount = body.amount as string | undefined;
183
+ const chain = (body.chain as string) || 'base';
184
+
185
+ const { display: amountDisplay } = formatAmount(amount, chain);
186
+
187
+ const facts: VerifiedFact[] = [];
188
+ if (to) facts.push({ label: 'To wallet', value: shortAddr(to), raw: to });
189
+ if (amount) facts.push({ label: 'Amount', value: amountDisplay, raw: amount });
190
+ facts.push({ label: 'Chain', value: chain });
191
+
192
+ const toDisplay = to ? shortAddr(to) : 'unknown';
193
+ const oneLiner = `Fund ${toDisplay} with ${amountDisplay} from cold`;
194
+
195
+ return { facts, oneLiner };
196
+ }
197
+
198
+ function extractLaunchFacts(body: Record<string, unknown>): { facts: VerifiedFact[]; oneLiner: string } {
199
+ const from = body.from as string | undefined;
200
+ const name = body.name as string | undefined;
201
+ const symbol = body.symbol as string | undefined;
202
+ const type = body.type as string | undefined;
203
+ const chain = (body.chain as string) || 'base';
204
+
205
+ const facts: VerifiedFact[] = [];
206
+ if (from) facts.push({ label: 'From wallet', value: shortAddr(from), raw: from });
207
+ if (name) facts.push({ label: 'Token name', value: name });
208
+ if (symbol) facts.push({ label: 'Symbol', value: symbol });
209
+ if (type) facts.push({ label: 'Launch type', value: type });
210
+ facts.push({ label: 'Chain', value: chain });
211
+
212
+ const tokenName = symbol || name || 'token';
213
+ const launchType = type || 'standard';
214
+ const oneLiner = `Launch ${tokenName} via ${launchType} on ${chain}`;
215
+
216
+ return { facts, oneLiner };
217
+ }
218
+
219
+ function extractWalletCreateFacts(body: Record<string, unknown>): { facts: VerifiedFact[]; oneLiner: string } {
220
+ const tier = (body.tier as string) || 'hot';
221
+ const chain = (body.chain as string) || 'base';
222
+ const name = body.name as string | undefined;
223
+
224
+ const facts: VerifiedFact[] = [];
225
+ facts.push({ label: 'Tier', value: tier });
226
+ facts.push({ label: 'Chain', value: chain });
227
+ if (name) facts.push({ label: 'Name', value: name });
228
+
229
+ const oneLiner = `Create ${tier} wallet on ${chain}`;
230
+
231
+ return { facts, oneLiner };
232
+ }
233
+
234
+ function extractFacts(action: ActionInput | undefined): { facts: VerifiedFact[]; oneLiner: string; endpoint: string } {
235
+ if (!action?.endpoint) {
236
+ return { facts: [], oneLiner: 'Action (no endpoint specified)', endpoint: 'unknown' };
237
+ }
238
+
239
+ const endpoint = action.endpoint;
240
+ const body = action.body || {};
241
+
242
+ if (endpoint.startsWith('/swap')) {
243
+ const result = extractSwapFacts(body);
244
+ return { ...result, endpoint };
245
+ }
246
+ if (endpoint.startsWith('/send')) {
247
+ const result = extractSendFacts(body);
248
+ return { ...result, endpoint };
249
+ }
250
+ if (endpoint.startsWith('/fund')) {
251
+ const result = extractFundFacts(body);
252
+ return { ...result, endpoint };
253
+ }
254
+ if (endpoint.startsWith('/launch')) {
255
+ const result = extractLaunchFacts(body);
256
+ return { ...result, endpoint };
257
+ }
258
+ if (endpoint.startsWith('/wallet/create')) {
259
+ const result = extractWalletCreateFacts(body);
260
+ return { ...result, endpoint };
261
+ }
262
+
263
+ // Unknown endpoint
264
+ const method = action.method || 'POST';
265
+ return {
266
+ facts: [{ label: 'Endpoint', value: `${method} ${endpoint}` }],
267
+ oneLiner: `${method} ${endpoint} (unverified)`,
268
+ endpoint,
269
+ };
270
+ }
271
+
272
+ // ---------------------------------------------------------------------------
273
+ // Discrepancy detection
274
+ // ---------------------------------------------------------------------------
275
+
276
+ const AMOUNT_REGEX = /(\d+\.?\d*)\s*(ETH|SOL|eth|sol)/;
277
+ const ACTION_WORDS: Record<string, string[]> = {
278
+ '/swap': ['swap', 'buy', 'sell', 'trade', 'exchange'],
279
+ '/send': ['send', 'transfer'],
280
+ '/fund': ['fund', 'deposit'],
281
+ '/launch': ['launch', 'deploy', 'create token', 'mint'],
282
+ '/wallet/create': ['create wallet', 'new wallet'],
283
+ };
284
+
285
+ export function detectDiscrepancies(
286
+ agentSummary: string,
287
+ action: ActionInput | undefined,
288
+ permissions: string[] | undefined,
289
+ ): SummaryDiscrepancy[] {
290
+ const discrepancies: SummaryDiscrepancy[] = [];
291
+
292
+ if (!action?.endpoint) return discrepancies;
293
+
294
+ const body = action.body || {};
295
+ const endpoint = action.endpoint;
296
+ const summaryLower = agentSummary.toLowerCase();
297
+
298
+ // 1. Amount mismatch
299
+ const amountMatch = AMOUNT_REGEX.exec(agentSummary);
300
+ if (amountMatch && body.amount) {
301
+ const claimedAmount = parseFloat(amountMatch[1]);
302
+ const chain = (body.chain as string) || 'base';
303
+ const { ethValue: actualAmount } = formatAmount(body.amount as string, chain);
304
+
305
+ if (actualAmount > 0 && claimedAmount > 0) {
306
+ const ratio = Math.abs(actualAmount - claimedAmount) / Math.max(actualAmount, claimedAmount);
307
+ if (ratio > 0.1) {
308
+ discrepancies.push({
309
+ field: 'amount',
310
+ agentClaim: `${claimedAmount} ${amountMatch[2]}`,
311
+ actual: formatAmount(body.amount as string, chain).display,
312
+ severity: 'critical',
313
+ });
314
+ }
315
+ }
316
+ }
317
+
318
+ // 2. Action word mismatch (e.g., summary says "swap" but endpoint is /send)
319
+ for (const [ep, words] of Object.entries(ACTION_WORDS)) {
320
+ if (endpoint.startsWith(ep)) continue; // This IS the endpoint — skip
321
+ const mentionsAction = words.some(w => summaryLower.includes(w));
322
+ if (mentionsAction) {
323
+ // Agent summary mentions an action that doesn't match the endpoint
324
+ const matchedWord = words.find(w => summaryLower.includes(w))!;
325
+ discrepancies.push({
326
+ field: 'endpoint',
327
+ agentClaim: matchedWord,
328
+ actual: endpoint,
329
+ severity: 'critical',
330
+ });
331
+ break; // One endpoint mismatch is enough
332
+ }
333
+ }
334
+
335
+ // 3. Raw Solana transaction — amount unverifiable
336
+ if (body.transaction) {
337
+ discrepancies.push({
338
+ field: 'transaction',
339
+ agentClaim: 'amount specified in summary',
340
+ actual: 'Raw Solana transaction — amount unverifiable from body',
341
+ severity: 'info',
342
+ });
343
+ }
344
+
345
+ // 4. Dangerous permissions
346
+ if (permissions?.includes('wallet:export')) {
347
+ discrepancies.push({
348
+ field: 'permissions',
349
+ agentClaim: 'standard permissions',
350
+ actual: 'Includes wallet:export (can export private keys)',
351
+ severity: 'warning',
352
+ });
353
+ }
354
+
355
+ // 5. Unknown endpoint
356
+ const knownPrefixes = ['/swap', '/send', '/fund', '/launch', '/wallet/create'];
357
+ if (!knownPrefixes.some(p => endpoint.startsWith(p))) {
358
+ discrepancies.push({
359
+ field: 'endpoint',
360
+ agentClaim: 'known action',
361
+ actual: `Unknown endpoint: ${endpoint}`,
362
+ severity: 'warning',
363
+ });
364
+ }
365
+
366
+ return discrepancies;
367
+ }
368
+
369
+ // ---------------------------------------------------------------------------
370
+ // Main entry point
371
+ // ---------------------------------------------------------------------------
372
+
373
+ interface GenerateVerifiedSummaryInput {
374
+ agentId: string;
375
+ summary: string;
376
+ permissions?: string[];
377
+ limits?: Record<string, number>;
378
+ walletAccess?: string[];
379
+ ttl?: number;
380
+ action?: ActionInput;
381
+ }
382
+
383
+ export function generateVerifiedSummary(input: GenerateVerifiedSummaryInput): VerifiedSummary {
384
+ const { agentId, summary, permissions, limits, walletAccess, ttl, action } = input;
385
+
386
+ // Extract facts from the action
387
+ const { facts, oneLiner, endpoint } = extractFacts(action);
388
+
389
+ // Generate labels
390
+ const permissionLabels = (permissions || []).map(formatPermissionLabel);
391
+
392
+ const limitLabels: string[] = [];
393
+ if (limits) {
394
+ for (const [perm, cap] of Object.entries(limits)) {
395
+ if (typeof cap === 'number' && cap > 0) {
396
+ limitLabels.push(`${perm}: ${cap} ETH`);
397
+ }
398
+ }
399
+ }
400
+
401
+ const walletAccessLabels = (walletAccess || []).map(shortAddr);
402
+ const ttlLabel = formatTtl(ttl);
403
+
404
+ // Detect discrepancies
405
+ const discrepancies = detectDiscrepancies(summary, action, permissions);
406
+ const verified = discrepancies.filter(d => d.severity === 'critical').length === 0;
407
+
408
+ return {
409
+ action: endpoint,
410
+ oneLiner,
411
+ facts,
412
+ permissionLabels,
413
+ limitLabels,
414
+ walletAccessLabels,
415
+ ttlLabel,
416
+ agentId,
417
+ discrepancies,
418
+ verified,
419
+ generatedAt: new Date().toISOString(),
420
+ };
421
+ }
@@ -0,0 +1,30 @@
1
+ import type { ProfileIssuanceSelection } from '../lib/credential-transport';
2
+
3
+ function parseOverrides(raw: string | undefined): ProfileIssuanceSelection['profileOverrides'] | undefined {
4
+ if (!raw) return undefined;
5
+ try {
6
+ const parsed = JSON.parse(raw) as ProfileIssuanceSelection['profileOverrides'];
7
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined;
8
+ return parsed;
9
+ } catch {
10
+ return undefined;
11
+ }
12
+ }
13
+
14
+ export function resolveMcpIssuanceProfile(
15
+ kind: 'read' | 'write',
16
+ env: NodeJS.ProcessEnv = process.env,
17
+ ): ProfileIssuanceSelection | undefined {
18
+ const prefix = kind === 'read' ? 'AURA_MCP_READ_PROFILE' : 'AURA_MCP_WRITE_PROFILE';
19
+ const profile = env[prefix];
20
+ if (!profile || !profile.trim()) return undefined;
21
+
22
+ const version = env[`${prefix}_VERSION`];
23
+ const overrides = parseOverrides(env[`${prefix}_OVERRIDES_JSON`]);
24
+
25
+ return {
26
+ profile,
27
+ ...(version ? { profileVersion: version } : {}),
28
+ ...(overrides ? { profileOverrides: overrides } : {}),
29
+ };
30
+ }