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,128 @@
1
+ import { Connection, VersionedTransaction, PublicKey } from '@solana/web3.js';
2
+
3
+ const JUPITER_API = 'https://quote-api.jup.ag/v6';
4
+
5
+ export interface JupiterQuote {
6
+ inputMint: string;
7
+ outputMint: string;
8
+ inAmount: string;
9
+ outAmount: string;
10
+ otherAmountThreshold: string;
11
+ swapMode: string;
12
+ slippageBps: number;
13
+ priceImpactPct: string;
14
+ routePlan: Array<{
15
+ swapInfo: {
16
+ ammKey: string;
17
+ label: string;
18
+ inputMint: string;
19
+ outputMint: string;
20
+ inAmount: string;
21
+ outAmount: string;
22
+ feeAmount: string;
23
+ feeMint: string;
24
+ };
25
+ percent: number;
26
+ }>;
27
+ }
28
+
29
+ export interface JupiterSwapResult {
30
+ swapTransaction: string; // base64-encoded VersionedTransaction
31
+ lastValidBlockHeight: number;
32
+ }
33
+
34
+ /**
35
+ * Get a swap quote from Jupiter.
36
+ */
37
+ export async function getJupiterQuote(
38
+ inputMint: string,
39
+ outputMint: string,
40
+ amount: string,
41
+ slippageBps: number
42
+ ): Promise<JupiterQuote> {
43
+ const params = new URLSearchParams({
44
+ inputMint,
45
+ outputMint,
46
+ amount,
47
+ slippageBps: slippageBps.toString(),
48
+ });
49
+
50
+ const response = await fetch(`${JUPITER_API}/quote?${params}`);
51
+ if (!response.ok) {
52
+ const text = await response.text();
53
+ throw new Error(`Jupiter quote failed: ${response.status} ${text}`);
54
+ }
55
+
56
+ return response.json();
57
+ }
58
+
59
+ /**
60
+ * Get a swap transaction from Jupiter.
61
+ * Returns a serialized VersionedTransaction ready to sign.
62
+ */
63
+ export async function getJupiterSwapTransaction(
64
+ quote: JupiterQuote,
65
+ userPublicKey: string
66
+ ): Promise<JupiterSwapResult> {
67
+ const response = await fetch(`${JUPITER_API}/swap`, {
68
+ method: 'POST',
69
+ headers: { 'Content-Type': 'application/json' },
70
+ body: JSON.stringify({
71
+ quoteResponse: quote,
72
+ userPublicKey,
73
+ wrapAndUnwrapSol: true,
74
+ }),
75
+ });
76
+
77
+ if (!response.ok) {
78
+ const text = await response.text();
79
+ throw new Error(`Jupiter swap failed: ${response.status} ${text}`);
80
+ }
81
+
82
+ return response.json();
83
+ }
84
+
85
+ /**
86
+ * Deserialize a Jupiter swap transaction.
87
+ */
88
+ export function deserializeJupiterTransaction(swapTransaction: string): VersionedTransaction {
89
+ const txBuf = Buffer.from(swapTransaction, 'base64');
90
+ return VersionedTransaction.deserialize(txBuf);
91
+ }
92
+
93
+ /**
94
+ * Execute a full Jupiter swap: quote → swap tx → sign → send.
95
+ */
96
+ export async function executeJupiterSwap(
97
+ connection: Connection,
98
+ inputMint: string,
99
+ outputMint: string,
100
+ amount: string,
101
+ slippageBps: number,
102
+ userPublicKey: PublicKey,
103
+ signTransaction: (tx: VersionedTransaction) => Promise<VersionedTransaction>
104
+ ): Promise<{ signature: string; quote: JupiterQuote }> {
105
+ // Get quote
106
+ const quote = await getJupiterQuote(inputMint, outputMint, amount, slippageBps);
107
+
108
+ // Get swap transaction
109
+ const { swapTransaction } = await getJupiterSwapTransaction(
110
+ quote,
111
+ userPublicKey.toBase58()
112
+ );
113
+
114
+ // Deserialize and sign
115
+ const tx = deserializeJupiterTransaction(swapTransaction);
116
+ const signedTx = await signTransaction(tx);
117
+
118
+ // Send
119
+ const signature = await connection.sendRawTransaction(signedTx.serialize(), {
120
+ skipPreflight: false,
121
+ maxRetries: 2,
122
+ });
123
+
124
+ // Confirm
125
+ await connection.confirmTransaction(signature, 'confirmed');
126
+
127
+ return { signature, quote };
128
+ }
@@ -0,0 +1,108 @@
1
+ import {
2
+ Connection,
3
+ Keypair,
4
+ PublicKey,
5
+ SystemProgram,
6
+ Transaction,
7
+ } from '@solana/web3.js';
8
+ import {
9
+ createTransferInstruction,
10
+ getAssociatedTokenAddress,
11
+ createAssociatedTokenAccountInstruction,
12
+ getAccount,
13
+ TokenAccountNotFoundError,
14
+ } from '@solana/spl-token';
15
+
16
+ /**
17
+ * Build a native SOL transfer transaction.
18
+ * @param amountLamports - Amount in lamports (1 SOL = 1e9 lamports)
19
+ */
20
+ export async function buildSolTransfer(
21
+ connection: Connection,
22
+ from: PublicKey,
23
+ to: PublicKey,
24
+ amountLamports: number | bigint
25
+ ): Promise<Transaction> {
26
+ const lamports = Number(amountLamports);
27
+
28
+ const tx = new Transaction().add(
29
+ SystemProgram.transfer({
30
+ fromPubkey: from,
31
+ toPubkey: to,
32
+ lamports,
33
+ })
34
+ );
35
+
36
+ tx.feePayer = from;
37
+ const { blockhash } = await connection.getLatestBlockhash();
38
+ tx.recentBlockhash = blockhash;
39
+
40
+ return tx;
41
+ }
42
+
43
+ /**
44
+ * Build an SPL token transfer transaction.
45
+ * Creates the recipient's associated token account if it doesn't exist.
46
+ */
47
+ export async function buildSplTransfer(
48
+ connection: Connection,
49
+ from: PublicKey,
50
+ to: PublicKey,
51
+ mint: PublicKey,
52
+ amount: bigint,
53
+ decimals: number
54
+ ): Promise<Transaction> {
55
+ const tx = new Transaction();
56
+
57
+ // Get associated token accounts
58
+ const fromAta = await getAssociatedTokenAddress(mint, from);
59
+ const toAta = await getAssociatedTokenAddress(mint, to);
60
+
61
+ // Check if recipient's ATA exists, create if not
62
+ try {
63
+ await getAccount(connection, toAta);
64
+ } catch (err) {
65
+ if (err instanceof TokenAccountNotFoundError) {
66
+ tx.add(
67
+ createAssociatedTokenAccountInstruction(
68
+ from, // payer
69
+ toAta,
70
+ to,
71
+ mint
72
+ )
73
+ );
74
+ } else {
75
+ throw err;
76
+ }
77
+ }
78
+
79
+ tx.add(
80
+ createTransferInstruction(
81
+ fromAta,
82
+ toAta,
83
+ from,
84
+ amount
85
+ )
86
+ );
87
+
88
+ tx.feePayer = from;
89
+ const { blockhash } = await connection.getLatestBlockhash();
90
+ tx.recentBlockhash = blockhash;
91
+
92
+ return tx;
93
+ }
94
+
95
+ /**
96
+ * Sign and send a Solana transaction.
97
+ * Returns the transaction signature.
98
+ */
99
+ export async function sendSolanaTransaction(
100
+ connection: Connection,
101
+ tx: Transaction,
102
+ signer: Keypair
103
+ ): Promise<string> {
104
+ tx.sign(signer);
105
+ const signature = await connection.sendRawTransaction(tx.serialize());
106
+ await connection.confirmTransaction(signature, 'confirmed');
107
+ return signature;
108
+ }
@@ -0,0 +1,136 @@
1
+ import { Keypair, Transaction, VersionedTransaction } from '@solana/web3.js';
2
+ import { derivePath } from 'ed25519-hd-key';
3
+ import * as bip39 from 'bip39';
4
+ import { EncryptedData } from '../../types';
5
+ import { encryptWithSeed, decryptWithSeed } from '../encrypt';
6
+ import { getMnemonic, getVaultMnemonic } from '../cold';
7
+ import { prisma } from '../db';
8
+
9
+ /**
10
+ * Derive a Solana keypair from a mnemonic using SLIP-0010.
11
+ * Path: m/44'/501'/{index}'/0'
12
+ */
13
+ export function deriveSolanaKeypair(mnemonic: string, index: number = 0): Keypair {
14
+ const seed = bip39.mnemonicToSeedSync(mnemonic);
15
+ const path = `m/44'/501'/${index}'/0'`;
16
+ const derived = derivePath(path, seed.toString('hex'));
17
+ return Keypair.fromSeed(derived.key);
18
+ }
19
+
20
+ /**
21
+ * Derive the cold (master) Solana keypair.
22
+ * Path: m/44'/501'/0'/0'
23
+ */
24
+ export function deriveSolanaColdKeypair(mnemonic: string): Keypair {
25
+ return deriveSolanaKeypair(mnemonic, 0);
26
+ }
27
+
28
+ export interface CreateSolanaHotWalletOptions {
29
+ tokenHash: string;
30
+ chain?: string;
31
+ name?: string;
32
+ color?: string;
33
+ description?: string;
34
+ emoji?: string;
35
+ hidden?: boolean;
36
+ coldWalletId?: string; // Which vault to encrypt with (null = primary)
37
+ }
38
+
39
+ /**
40
+ * Create a new Solana hot wallet with a random keypair.
41
+ * The secret key is encrypted with the cold wallet mnemonic.
42
+ */
43
+ export async function createSolanaHotWallet(options: CreateSolanaHotWalletOptions) {
44
+ const { coldWalletId } = options;
45
+ const mnemonic = coldWalletId ? getVaultMnemonic(coldWalletId) : getMnemonic();
46
+ if (!mnemonic) {
47
+ const target = coldWalletId ? `Vault ${coldWalletId}` : 'Cold wallet';
48
+ throw new Error(`${target} must be unlocked to create Solana hot wallets`);
49
+ }
50
+
51
+ const { tokenHash, chain = 'solana', name, color, description, emoji, hidden = false } = options;
52
+
53
+ // Generate random Solana keypair
54
+ const keypair = Keypair.generate();
55
+ const address = keypair.publicKey.toBase58();
56
+
57
+ // Encrypt secret key with mnemonic
58
+ const secretKeyHex = Buffer.from(keypair.secretKey).toString('hex');
59
+ const encrypted = encryptWithSeed(secretKeyHex, mnemonic);
60
+
61
+ // Store in DB (with coldWalletId reference)
62
+ const hotWallet = await prisma.hotWallet.create({
63
+ data: {
64
+ address, // Solana addresses are case-sensitive, no toLowerCase
65
+ encryptedPrivateKey: JSON.stringify(encrypted),
66
+ tokenHash,
67
+ coldWalletId: coldWalletId || null,
68
+ name,
69
+ color,
70
+ description,
71
+ emoji,
72
+ hidden,
73
+ chain,
74
+ },
75
+ });
76
+
77
+ return {
78
+ address: hotWallet.address,
79
+ tier: 'hot' as const,
80
+ chain: hotWallet.chain,
81
+ createdAt: hotWallet.createdAt.toISOString(),
82
+ name: hotWallet.name || undefined,
83
+ color: hotWallet.color || undefined,
84
+ description: hotWallet.description || undefined,
85
+ emoji: hotWallet.emoji || undefined,
86
+ hidden: hotWallet.hidden,
87
+ tokenHash: hotWallet.tokenHash,
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Get a Solana keypair from a stored hot wallet.
93
+ * Requires cold wallet to be unlocked for decryption.
94
+ */
95
+ export async function getSolanaKeypair(address: string): Promise<Keypair> {
96
+ const wallet = await prisma.hotWallet.findUnique({
97
+ where: { address },
98
+ });
99
+
100
+ if (!wallet) {
101
+ throw new Error(`Solana hot wallet not found: ${address}`);
102
+ }
103
+
104
+ // Get mnemonic from the vault this hot wallet belongs to
105
+ const mnemonic = wallet.coldWalletId
106
+ ? getVaultMnemonic(wallet.coldWalletId)
107
+ : getMnemonic();
108
+ if (!mnemonic) {
109
+ const target = wallet.coldWalletId ? `Vault ${wallet.coldWalletId}` : 'Cold wallet';
110
+ throw new Error(`${target} must be unlocked to access Solana hot wallet`);
111
+ }
112
+
113
+ const encrypted: EncryptedData = JSON.parse(wallet.encryptedPrivateKey);
114
+ const secretKeyHex = decryptWithSeed(encrypted, mnemonic);
115
+ const secretKey = Uint8Array.from(Buffer.from(secretKeyHex, 'hex'));
116
+ return Keypair.fromSecretKey(secretKey);
117
+ }
118
+
119
+ /**
120
+ * Sign a Solana transaction with a hot wallet keypair.
121
+ * Returns the transaction signature (base58).
122
+ */
123
+ export async function signSolanaTransaction(
124
+ address: string,
125
+ tx: Transaction | VersionedTransaction
126
+ ): Promise<Uint8Array> {
127
+ const keypair = await getSolanaKeypair(address);
128
+
129
+ if (tx instanceof VersionedTransaction) {
130
+ tx.sign([keypair]);
131
+ } else {
132
+ tx.partialSign(keypair);
133
+ }
134
+
135
+ return tx.serialize();
136
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Hook Emit Processor
3
+ * ===================
4
+ * Broadcasts hook emit events as app:emit WS events so the dashboard
5
+ * can forward them to the correct app iframe via postMessage.
6
+ */
7
+
8
+ import { HookResult, HookEmit } from './types';
9
+ import { emitWalletEvent } from '../events';
10
+
11
+ /**
12
+ * Broadcast hook emit(s) as app:emit events.
13
+ * Called after tick, result, and message hooks.
14
+ */
15
+ export function processEmits(strategyId: string, hookResult: HookResult): void {
16
+ if (!hookResult.emit) return;
17
+ const emits: HookEmit[] = Array.isArray(hookResult.emit) ? hookResult.emit : [hookResult.emit];
18
+ for (const e of emits) {
19
+ emitWalletEvent('app:emit', { strategyId, channel: e.channel, data: e.data });
20
+ }
21
+ }