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,153 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import { Minus, X, MoreHorizontal, LucideIcon } from 'lucide-react';
5
+
6
+ interface AppAction {
7
+ label: string;
8
+ icon?: LucideIcon;
9
+ onClick: () => void;
10
+ variant?: 'primary' | 'secondary' | 'danger';
11
+ }
12
+
13
+ interface AppProps {
14
+ title: string;
15
+ icon?: LucideIcon;
16
+ size?: 'compact' | 'small' | 'medium' | 'large' | 'wide' | 'full';
17
+ dismissable?: boolean;
18
+ collapsible?: boolean;
19
+ onDismiss?: () => void;
20
+ actions?: AppAction[];
21
+ children: React.ReactNode;
22
+ className?: string;
23
+ status?: 'normal' | 'alert' | 'success';
24
+ }
25
+
26
+ const sizeClasses = {
27
+ compact: 'col-span-3',
28
+ small: 'col-span-4',
29
+ medium: 'col-span-6',
30
+ large: 'col-span-8',
31
+ wide: 'col-span-9',
32
+ full: 'col-span-12',
33
+ };
34
+
35
+ export const App: React.FC<AppProps> = ({
36
+ title,
37
+ icon: Icon,
38
+ size = 'small',
39
+ dismissable = false,
40
+ collapsible = false,
41
+ onDismiss,
42
+ actions,
43
+ children,
44
+ className = '',
45
+ status = 'normal',
46
+ }) => {
47
+ const [collapsed, setCollapsed] = React.useState(false);
48
+
49
+ const statusBorders: Record<string, string> = {
50
+ normal: 'var(--color-border, #e5e5e5)',
51
+ alert: 'var(--color-warning, #ff4d00)',
52
+ success: 'var(--color-accent, #ccff00)',
53
+ };
54
+
55
+ return (
56
+ <div className={`${sizeClasses[size]} ${className}`}>
57
+ <div
58
+ className="relative overflow-hidden group"
59
+ style={{
60
+ background: 'var(--color-surface, #ffffff)',
61
+ border: `1px solid ${statusBorders[status]}`,
62
+ }}
63
+ >
64
+ {/* Corner Brackets */}
65
+ <div className="absolute top-1 left-1 w-2 h-2 opacity-50" style={{ borderLeft: '1px solid var(--color-border, #e5e5e5)', borderTop: '1px solid var(--color-border, #e5e5e5)' }} />
66
+ <div className="absolute top-1 right-1 w-2 h-2 opacity-50" style={{ borderRight: '1px solid var(--color-border, #e5e5e5)', borderTop: '1px solid var(--color-border, #e5e5e5)' }} />
67
+ <div className="absolute bottom-1 left-1 w-2 h-2 opacity-50" style={{ borderLeft: '1px solid var(--color-border, #e5e5e5)', borderBottom: '1px solid var(--color-border, #e5e5e5)' }} />
68
+ <div className="absolute bottom-1 right-1 w-2 h-2 opacity-50" style={{ borderRight: '1px solid var(--color-border, #e5e5e5)', borderBottom: '1px solid var(--color-border, #e5e5e5)' }} />
69
+
70
+ {/* Noise Texture */}
71
+ <div className="absolute inset-0 opacity-[0.02] pointer-events-none bg-[radial-gradient(var(--color-text,#000)_1px,transparent_1px)] bg-[size:3px_3px]" />
72
+
73
+ {/* Header */}
74
+ <div
75
+ className="px-3 py-2 flex items-center justify-between relative z-10"
76
+ style={{ borderBottom: '1px solid var(--color-border-muted, #eee)' }}
77
+ >
78
+ <div className="flex items-center gap-2">
79
+ {Icon && <Icon size={12} style={{ color: 'var(--color-text-muted, #888)' }} />}
80
+ <span className="font-mono text-[10px] font-bold tracking-widest uppercase" style={{ color: 'var(--color-text, #0a0a0a)' }}>{title}</span>
81
+ </div>
82
+ <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
83
+ {collapsible && (
84
+ <button
85
+ onClick={() => setCollapsed(!collapsed)}
86
+ className="p-1 transition-colors"
87
+ >
88
+ <Minus size={10} style={{ color: 'var(--color-text-muted, #888)' }} />
89
+ </button>
90
+ )}
91
+ {dismissable && (
92
+ <button
93
+ onClick={onDismiss}
94
+ className="p-1 transition-colors"
95
+ >
96
+ <X size={10} style={{ color: 'var(--color-text-muted, #888)' }} />
97
+ </button>
98
+ )}
99
+ </div>
100
+ </div>
101
+
102
+ {/* Content */}
103
+ {!collapsed && (
104
+ <div className="p-3 relative z-10">
105
+ {children}
106
+ </div>
107
+ )}
108
+
109
+ {/* Footer Actions */}
110
+ {!collapsed && actions && actions.length > 0 && (
111
+ <div
112
+ className="px-3 py-2 flex items-center gap-2 relative z-10"
113
+ style={{ borderTop: '1px solid var(--color-border-muted, #eee)' }}
114
+ >
115
+ {actions.slice(0, 2).map((action, i) => {
116
+ const ActionIcon = action.icon;
117
+ const variantStyles: Record<string, React.CSSProperties> = {
118
+ primary: {
119
+ background: 'var(--color-text, #0a0a0a)',
120
+ color: 'var(--color-surface, #ffffff)',
121
+ },
122
+ secondary: {
123
+ border: '1px solid var(--color-border, #e5e5e5)',
124
+ color: 'var(--color-text-muted, #888)',
125
+ },
126
+ danger: {
127
+ border: '1px solid var(--color-warning, #ff4d00)',
128
+ color: 'var(--color-warning, #ff4d00)',
129
+ },
130
+ };
131
+ return (
132
+ <button
133
+ key={i}
134
+ onClick={action.onClick}
135
+ className="px-3 py-1.5 font-mono text-[9px] tracking-widest flex items-center gap-1.5 transition-colors"
136
+ style={variantStyles[action.variant || 'secondary']}
137
+ >
138
+ {ActionIcon && <ActionIcon size={10} />}
139
+ {action.label}
140
+ </button>
141
+ );
142
+ })}
143
+ {actions.length > 2 && (
144
+ <button className="ml-auto p-1 transition-colors">
145
+ <MoreHorizontal size={12} style={{ color: 'var(--color-text-muted, #888)' }} />
146
+ </button>
147
+ )}
148
+ </div>
149
+ )}
150
+ </div>
151
+ </div>
152
+ );
153
+ };
@@ -0,0 +1,15 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+
5
+ interface AppGridProps {
6
+ children: React.ReactNode;
7
+ }
8
+
9
+ export const AppGrid: React.FC<AppGridProps> = ({ children }) => {
10
+ return (
11
+ <div className="grid grid-cols-12 gap-4 auto-rows-max">
12
+ {children}
13
+ </div>
14
+ );
15
+ };
@@ -0,0 +1,325 @@
1
+ 'use client';
2
+
3
+ import React, { useState, useEffect } from 'react';
4
+ import { Copy, Edit2, Save, EyeOff, Eye, Flame } from 'lucide-react';
5
+ import { Drawer } from '@/components/design-system';
6
+
7
+ interface WalletData {
8
+ address: string;
9
+ tier: 'cold' | 'hot' | 'temp';
10
+ chain: string;
11
+ balance?: string;
12
+ name?: string;
13
+ color?: string;
14
+ emoji?: string;
15
+ description?: string;
16
+ hidden?: boolean;
17
+ tokenHash?: string;
18
+ createdAt?: string;
19
+ }
20
+
21
+ interface DetailedAddressDrawerProps {
22
+ isOpen: boolean;
23
+ onClose: () => void;
24
+ wallet: WalletData | null;
25
+ onUpdate: (address: string, updates: { name?: string; color?: string; emoji?: string; description?: string; hidden?: boolean }) => Promise<void>;
26
+ onCopyAddress: (address: string) => void;
27
+ copiedAddress: string | null;
28
+ }
29
+
30
+ const EMOJI_OPTIONS = ['🔥', '💎', '🚀', '⚡', '🌙', '🌟', '💰', '🎯', '🔮', '🌈'];
31
+ const COLOR_OPTIONS = ['#ff4d00', '#0047ff', '#00c853', '#ffab00', '#9c27b0', '#00bcd4', '#e91e63', '#607d8b'];
32
+
33
+ export const DetailedAddressDrawer: React.FC<DetailedAddressDrawerProps> = ({
34
+ isOpen,
35
+ onClose,
36
+ wallet,
37
+ onUpdate,
38
+ onCopyAddress,
39
+ copiedAddress,
40
+ }) => {
41
+ const [isEditMode, setIsEditMode] = useState(false);
42
+ const [saving, setSaving] = useState(false);
43
+
44
+ // Edit form state
45
+ const [editName, setEditName] = useState('');
46
+ const [editDescription, setEditDescription] = useState('');
47
+ const [editEmoji, setEditEmoji] = useState('');
48
+ const [editColor, setEditColor] = useState('');
49
+ const [editHidden, setEditHidden] = useState(false);
50
+
51
+ // Reset edit state when wallet changes
52
+ useEffect(() => {
53
+ if (wallet) {
54
+ setEditName(wallet.name || '');
55
+ setEditDescription(wallet.description || '');
56
+ setEditEmoji(wallet.emoji || '');
57
+ setEditColor(wallet.color || '');
58
+ setEditHidden(wallet.hidden || false);
59
+ }
60
+ setIsEditMode(false);
61
+ }, [wallet]);
62
+
63
+ const handleSave = async () => {
64
+ if (!wallet) return;
65
+ setSaving(true);
66
+ try {
67
+ await onUpdate(wallet.address, {
68
+ name: editName || undefined,
69
+ description: editDescription || undefined,
70
+ emoji: editEmoji || undefined,
71
+ color: editColor || undefined,
72
+ hidden: editHidden,
73
+ });
74
+ setIsEditMode(false);
75
+ } finally {
76
+ setSaving(false);
77
+ }
78
+ };
79
+
80
+ if (!wallet) return null;
81
+
82
+ const shortAddress = (addr: string) => `${addr.slice(0, 6)}...${addr.slice(-4)}`;
83
+
84
+ return (
85
+ <Drawer
86
+ isOpen={isOpen}
87
+ onClose={onClose}
88
+ title={isEditMode ? 'EDIT WALLET' : 'WALLET DETAILS'}
89
+ subtitle={shortAddress(wallet.address)}
90
+ width="md"
91
+ >
92
+ <div className="space-y-5">
93
+ {/* QR Code & Address */}
94
+ <div className="bg-[var(--color-surface,#ffffff)] border border-[var(--color-border,#e5e5e5)] p-4">
95
+ <div className="flex justify-center mb-4">
96
+ <div className="p-2 bg-[var(--color-surface,#ffffff)] border border-[var(--color-border,#e5e5e5)] relative">
97
+ <div className="absolute top-1 left-1 w-2 h-2 border-l border-t border-[var(--color-border-focus,#0a0a0a)]" />
98
+ <div className="absolute top-1 right-1 w-2 h-2 border-r border-t border-[var(--color-border-focus,#0a0a0a)]" />
99
+ <div className="absolute bottom-1 left-1 w-2 h-2 border-l border-b border-[var(--color-border-focus,#0a0a0a)]" />
100
+ <div className="absolute bottom-1 right-1 w-2 h-2 border-r border-b border-[var(--color-border-focus,#0a0a0a)]" />
101
+ <img
102
+ src={`https://api.qrserver.com/v1/create-qr-code/?size=120x120&data=${wallet.address}&bgcolor=ffffff&color=0a0a0a&margin=0`}
103
+ alt="Wallet QR Code"
104
+ className="w-28 h-28"
105
+ />
106
+ </div>
107
+ </div>
108
+
109
+ <div className="p-2 bg-[var(--color-text,#0a0a0a)] border border-[var(--color-border-focus,#0a0a0a)] mb-3">
110
+ <code className="font-mono text-[10px] text-[var(--color-accent,#ccff00)] break-all select-all block text-center leading-relaxed">
111
+ {wallet.address}
112
+ </code>
113
+ </div>
114
+
115
+ <button
116
+ onClick={() => onCopyAddress(wallet.address)}
117
+ className="w-full py-2 bg-[var(--color-text,#0a0a0a)] text-[var(--color-surface,#ffffff)] font-mono text-[9px] tracking-widest flex items-center justify-center gap-2 hover:text-[var(--color-accent,#ccff00)] transition-colors"
118
+ >
119
+ <Copy size={10} />
120
+ {copiedAddress === wallet.address ? 'COPIED!' : 'COPY ADDRESS'}
121
+ </button>
122
+ </div>
123
+
124
+ {/* Wallet Metadata */}
125
+ <div className="bg-[var(--color-surface,#ffffff)] border border-[var(--color-border,#e5e5e5)] p-4">
126
+ <div className="flex items-center justify-between mb-3">
127
+ <div className="font-mono text-[9px] text-[var(--color-text-muted,#6b7280)] tracking-widest">METADATA</div>
128
+ <button
129
+ onClick={() => isEditMode ? handleSave() : setIsEditMode(true)}
130
+ disabled={saving}
131
+ className="flex items-center gap-1 px-2 py-1 border border-[var(--color-border,#e5e5e5)] font-mono text-[9px] text-[var(--color-text-muted,#6b7280)] hover:border-[var(--color-border-focus,#0a0a0a)] hover:text-[var(--color-text-hover,#0a0a0a)] transition-colors disabled:opacity-50"
132
+ >
133
+ {isEditMode ? (
134
+ <>
135
+ <Save size={10} />
136
+ {saving ? 'SAVING...' : 'SAVE'}
137
+ </>
138
+ ) : (
139
+ <>
140
+ <Edit2 size={10} />
141
+ EDIT
142
+ </>
143
+ )}
144
+ </button>
145
+ </div>
146
+
147
+ {isEditMode ? (
148
+ <div className="space-y-4">
149
+ {/* Name */}
150
+ <div>
151
+ <label className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest block mb-1">NAME</label>
152
+ <input
153
+ type="text"
154
+ value={editName}
155
+ onChange={(e) => setEditName(e.target.value)}
156
+ placeholder="Wallet name..."
157
+ className="w-full px-3 py-2 border border-[var(--color-border,#e5e5e5)] font-mono text-xs focus:outline-none focus:border-[var(--color-border-focus,#0a0a0a)] bg-[var(--color-surface,#ffffff)]"
158
+ />
159
+ </div>
160
+
161
+ {/* Description */}
162
+ <div>
163
+ <label className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest block mb-1">DESCRIPTION</label>
164
+ <textarea
165
+ value={editDescription}
166
+ onChange={(e) => setEditDescription(e.target.value)}
167
+ placeholder="Add a description..."
168
+ rows={2}
169
+ className="w-full px-3 py-2 border border-[var(--color-border,#e5e5e5)] font-mono text-xs focus:outline-none focus:border-[var(--color-border-focus,#0a0a0a)] bg-[var(--color-surface,#ffffff)] resize-none"
170
+ />
171
+ </div>
172
+
173
+ {/* Emoji Picker */}
174
+ <div>
175
+ <label className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest block mb-1">EMOJI</label>
176
+ <div className="flex flex-wrap gap-1">
177
+ <button
178
+ onClick={() => setEditEmoji('')}
179
+ className={`w-8 h-8 border flex items-center justify-center transition-colors ${
180
+ !editEmoji ? 'border-[var(--color-border-focus,#0a0a0a)] bg-[var(--color-background-alt,#f4f4f5)]' : 'border-[var(--color-border,#e5e5e5)] hover:border-[var(--color-border-hover,#d4d4d4)]'
181
+ }`}
182
+ >
183
+ <Flame size={12} className="text-[var(--color-warning,#ff4d00)]" />
184
+ </button>
185
+ {EMOJI_OPTIONS.map((emoji) => (
186
+ <button
187
+ key={emoji}
188
+ onClick={() => setEditEmoji(emoji)}
189
+ className={`w-8 h-8 border flex items-center justify-center text-sm transition-colors ${
190
+ editEmoji === emoji ? 'border-[var(--color-border-focus,#0a0a0a)] bg-[var(--color-background-alt,#f4f4f5)]' : 'border-[var(--color-border,#e5e5e5)] hover:border-[var(--color-border-hover,#d4d4d4)]'
191
+ }`}
192
+ >
193
+ {emoji}
194
+ </button>
195
+ ))}
196
+ </div>
197
+ </div>
198
+
199
+ {/* Color Picker */}
200
+ <div>
201
+ <label className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest block mb-1">COLOR</label>
202
+ <div className="flex flex-wrap gap-1">
203
+ <button
204
+ onClick={() => setEditColor('')}
205
+ className={`w-8 h-8 border flex items-center justify-center transition-colors ${
206
+ !editColor ? 'border-[var(--color-border-focus,#0a0a0a)]' : 'border-[var(--color-border,#e5e5e5)] hover:border-[var(--color-border-hover,#d4d4d4)]'
207
+ }`}
208
+ >
209
+ <div className="w-4 h-4 bg-[var(--color-border,#e5e5e5)] rounded-full" />
210
+ </button>
211
+ {COLOR_OPTIONS.map((color) => (
212
+ <button
213
+ key={color}
214
+ onClick={() => setEditColor(color)}
215
+ className={`w-8 h-8 border flex items-center justify-center transition-colors ${
216
+ editColor === color ? 'border-[var(--color-border-focus,#0a0a0a)]' : 'border-[var(--color-border,#e5e5e5)] hover:border-[var(--color-border-hover,#d4d4d4)]'
217
+ }`}
218
+ >
219
+ <div className="w-4 h-4 rounded-full" style={{ backgroundColor: color }} />
220
+ </button>
221
+ ))}
222
+ </div>
223
+ </div>
224
+
225
+ {/* Hidden Toggle */}
226
+ <div>
227
+ <label className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest block mb-1">VISIBILITY</label>
228
+ <button
229
+ onClick={() => setEditHidden(!editHidden)}
230
+ className={`flex items-center gap-2 px-3 py-2 border transition-colors w-full ${
231
+ editHidden
232
+ ? 'border-[var(--color-warning,#ff4d00)] bg-[var(--color-warning,#ff4d00)]/5 text-[var(--color-warning,#ff4d00)]'
233
+ : 'border-[var(--color-border,#e5e5e5)] hover:border-[var(--color-border-hover,#d4d4d4)]'
234
+ }`}
235
+ >
236
+ {editHidden ? <EyeOff size={12} /> : <Eye size={12} />}
237
+ <span className="font-mono text-[10px]">
238
+ {editHidden ? 'HIDDEN - Excluded from totals' : 'VISIBLE - Included in totals'}
239
+ </span>
240
+ </button>
241
+ </div>
242
+ </div>
243
+ ) : (
244
+ <div className="space-y-3">
245
+ {/* Display View */}
246
+ <div className="flex items-center gap-3">
247
+ {wallet.emoji ? (
248
+ <div className="w-10 h-10 border border-[var(--color-border,#e5e5e5)] flex items-center justify-center text-xl">
249
+ {wallet.emoji}
250
+ </div>
251
+ ) : (
252
+ <div className="w-10 h-10 border border-[var(--color-warning,#ff4d00)]/30 flex items-center justify-center">
253
+ <Flame size={16} className="text-[var(--color-warning,#ff4d00)]" />
254
+ </div>
255
+ )}
256
+ <div className="flex-1">
257
+ <div className="font-bold text-sm text-[var(--color-text,#0a0a0a)]">
258
+ {wallet.name || 'Unnamed Wallet'}
259
+ </div>
260
+ {wallet.description && (
261
+ <div className="font-mono text-[9px] text-[var(--color-text-muted,#6b7280)] mt-0.5">{wallet.description}</div>
262
+ )}
263
+ </div>
264
+ {wallet.color && (
265
+ <div
266
+ className="w-4 h-4 rounded-full border border-[var(--color-border,#e5e5e5)]"
267
+ style={{ backgroundColor: wallet.color }}
268
+ />
269
+ )}
270
+ </div>
271
+
272
+ {wallet.hidden && (
273
+ <div className="flex items-center gap-2 px-2 py-1.5 bg-[var(--color-warning,#ff4d00)]/10 border border-[var(--color-warning,#ff4d00)]/30">
274
+ <EyeOff size={10} className="text-[var(--color-warning,#ff4d00)]" />
275
+ <span className="font-mono text-[9px] text-[var(--color-warning,#ff4d00)]">HIDDEN</span>
276
+ </div>
277
+ )}
278
+ </div>
279
+ )}
280
+ </div>
281
+
282
+ {/* Details Grid */}
283
+ <div className="bg-[var(--color-surface,#ffffff)] border border-[var(--color-border,#e5e5e5)] p-4">
284
+ <div className="font-mono text-[9px] text-[var(--color-text-muted,#6b7280)] tracking-widest mb-3">DETAILS</div>
285
+ <div className="grid grid-cols-2 gap-3">
286
+ <div>
287
+ <div className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest">CREATED</div>
288
+ <div className="font-mono text-[10px] text-[var(--color-text,#0a0a0a)] mt-0.5">
289
+ {wallet.createdAt
290
+ ? new Date(wallet.createdAt).toLocaleDateString()
291
+ : 'Unknown'}
292
+ </div>
293
+ </div>
294
+ <div>
295
+ <div className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest">BALANCE</div>
296
+ <div className="font-mono text-[10px] text-[var(--color-text,#0a0a0a)] mt-0.5 font-bold">
297
+ {wallet.balance || '0 ETH'}
298
+ </div>
299
+ </div>
300
+ <div>
301
+ <div className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest">CHAIN</div>
302
+ <div className="font-mono text-[10px] text-[var(--color-text,#0a0a0a)] mt-0.5 uppercase">
303
+ {wallet.chain}
304
+ </div>
305
+ </div>
306
+ <div>
307
+ <div className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest">TIER</div>
308
+ <div className="font-mono text-[10px] text-[var(--color-warning,#ff4d00)] mt-0.5 uppercase font-bold">
309
+ {wallet.tier}
310
+ </div>
311
+ </div>
312
+ {wallet.tokenHash && (
313
+ <div className="col-span-2">
314
+ <div className="font-mono text-[8px] text-[var(--color-text-faint,#9ca3af)] tracking-widest">CREATED BY</div>
315
+ <div className="font-mono text-[9px] text-[var(--color-text-muted,#6b7280)] mt-0.5 truncate">
316
+ {wallet.tokenHash.slice(0, 16)}...
317
+ </div>
318
+ </div>
319
+ )}
320
+ </div>
321
+ </div>
322
+ </div>
323
+ </Drawer>
324
+ );
325
+ };