auramaxx 0.0.1
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.
- package/LICENSE +26 -0
- package/README.md +77 -0
- package/apps/desktop-electron/main.js +428 -0
- package/bin/auramaxx.js +1063 -0
- package/docs/ADAPTERS.md +466 -0
- package/docs/AGENT_SETUP.md +159 -0
- package/docs/API.md +127 -0
- package/docs/APPS.md +199 -0
- package/docs/ARCHITECTURE.md +235 -0
- package/docs/AUTH.md +318 -0
- package/docs/BEST-PRACTICES.md +82 -0
- package/docs/CLI.md +141 -0
- package/docs/DESKTOP_ELECTRON.md +26 -0
- package/docs/DEVELOPING-APPS.md +453 -0
- package/docs/MCP.md +122 -0
- package/docs/PACKAGING_POLICY.md +19 -0
- package/docs/PERMISSION.md +137 -0
- package/docs/PROTOCOL.md +142 -0
- package/docs/README.md +50 -0
- package/docs/SKILLS.md +132 -0
- package/docs/TROUBLESHOOTING.md +376 -0
- package/docs/WORKSPACE.md +673 -0
- package/docs/agent-auth.md +14 -0
- package/docs/api/authentication.md +79 -0
- package/docs/api/secrets/api-keys.md +28 -0
- package/docs/api/secrets/credentials.md +80 -0
- package/docs/api/secrets/sharing.md +48 -0
- package/docs/api/system.md +41 -0
- package/docs/api/wallets/apps-strategies.md +66 -0
- package/docs/api/wallets/core.md +46 -0
- package/docs/api/wallets/data-portfolio.md +42 -0
- package/docs/aura-file.md +48 -0
- package/docs/core-concepts/FEATURES.md +114 -0
- package/docs/credentials.md +120 -0
- package/docs/external/HOW_TO_AURAMAXX/GETTING_SECRETS.md +33 -0
- package/docs/external/HOW_TO_AURAMAXX/README.md +45 -0
- package/docs/external/getting-started.md +10 -0
- package/docs/external/overview.md +19 -0
- package/docs/external/persona-paths.md +7 -0
- package/docs/external/share-secret.md +76 -0
- package/docs/external/why-aura.md +7 -0
- package/docs/security.md +227 -0
- package/docs/templates/RELEASE_NOTES_TEMPLATE.md +22 -0
- package/docs/wallet/AI.md +508 -0
- package/docs/wallet/DEVELOPING-STRATEGIES.md +713 -0
- package/docs/wallet/README.md +47 -0
- package/docs/wallet/STRATEGY.md +89 -0
- package/next.config.ts +28 -0
- package/package.json +167 -0
- package/postcss.config.mjs +8 -0
- package/prisma/migrations/20260214170000_baseline/migration.sql +511 -0
- package/prisma/migrations/20260216214537_add_passkey_model/migration.sql +18 -0
- package/prisma/migrations/20260217150500_add_credential_access_audit/migration.sql +31 -0
- package/prisma/migrations/20260222090000_update_admin_ttl_default/migration.sql +10 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +447 -0
- package/public/logo.webp +0 -0
- package/scripts/add-app.js +245 -0
- package/server/abi/SwapHelper.json +438 -0
- package/server/cli/approval.ts +447 -0
- package/server/cli/commands/actions.ts +474 -0
- package/server/cli/commands/api.ts +220 -0
- package/server/cli/commands/apikey.ts +277 -0
- package/server/cli/commands/app.ts +204 -0
- package/server/cli/commands/auth.ts +464 -0
- package/server/cli/commands/cron.ts +24 -0
- package/server/cli/commands/diary.ts +274 -0
- package/server/cli/commands/doctor.ts +1247 -0
- package/server/cli/commands/env.ts +476 -0
- package/server/cli/commands/experimental.ts +69 -0
- package/server/cli/commands/init.ts +798 -0
- package/server/cli/commands/lock.ts +157 -0
- package/server/cli/commands/mcp.ts +285 -0
- package/server/cli/commands/quickhack.ts +86 -0
- package/server/cli/commands/release-check.ts +231 -0
- package/server/cli/commands/restore.ts +314 -0
- package/server/cli/commands/service.ts +320 -0
- package/server/cli/commands/shell-hook.ts +512 -0
- package/server/cli/commands/skill.ts +216 -0
- package/server/cli/commands/start.ts +139 -0
- package/server/cli/commands/status.ts +59 -0
- package/server/cli/commands/stop.ts +36 -0
- package/server/cli/commands/token.ts +180 -0
- package/server/cli/commands/unlock.ts +50 -0
- package/server/cli/commands/vault.ts +1323 -0
- package/server/cli/commands/wallet.ts +209 -0
- package/server/cli/index.ts +280 -0
- package/server/cli/lib/approval-poll.ts +94 -0
- package/server/cli/lib/aura-parser.ts +64 -0
- package/server/cli/lib/credential-create.ts +74 -0
- package/server/cli/lib/credential-resolve.ts +280 -0
- package/server/cli/lib/dotenv-migrate.ts +116 -0
- package/server/cli/lib/dotenv-parser.ts +146 -0
- package/server/cli/lib/escalation.ts +57 -0
- package/server/cli/lib/http.ts +91 -0
- package/server/cli/lib/init-steps.ts +76 -0
- package/server/cli/lib/local-agent-trust.ts +45 -0
- package/server/cli/lib/lock-unlock-helper.ts +71 -0
- package/server/cli/lib/process.ts +162 -0
- package/server/cli/lib/prompt.ts +294 -0
- package/server/cli/lib/theme.ts +240 -0
- package/server/cli/socket.ts +579 -0
- package/server/cli/transport-client.ts +50 -0
- package/server/cron/index.ts +137 -0
- package/server/cron/job.ts +31 -0
- package/server/cron/jobs/balance-sync.ts +436 -0
- package/server/cron/jobs/incoming-scan.ts +506 -0
- package/server/cron/jobs/native-price.ts +70 -0
- package/server/cron/jobs/orphan-cleanup.ts +40 -0
- package/server/cron/jobs/strategy-runner.ts +175 -0
- package/server/cron/scheduler.ts +125 -0
- package/server/index.ts +420 -0
- package/server/lib/adapters/factory.ts +119 -0
- package/server/lib/adapters/index.ts +19 -0
- package/server/lib/adapters/router.ts +297 -0
- package/server/lib/adapters/telegram.ts +645 -0
- package/server/lib/adapters/types.ts +89 -0
- package/server/lib/adapters/webhook.ts +95 -0
- package/server/lib/address.ts +49 -0
- package/server/lib/agent-auth/contracts.ts +1194 -0
- package/server/lib/agent-profiles.ts +419 -0
- package/server/lib/ai.ts +285 -0
- package/server/lib/api-registry/contracts.ts +86 -0
- package/server/lib/api-registry/validation.ts +172 -0
- package/server/lib/apikey-migration.ts +258 -0
- package/server/lib/app-installer.ts +505 -0
- package/server/lib/app-tokens.ts +247 -0
- package/server/lib/approval-link.ts +27 -0
- package/server/lib/auth.ts +314 -0
- package/server/lib/auto-execute.ts +160 -0
- package/server/lib/batch.ts +242 -0
- package/server/lib/cold.ts +1048 -0
- package/server/lib/config.ts +408 -0
- package/server/lib/credential-access-audit.ts +85 -0
- package/server/lib/credential-access-policy.ts +111 -0
- package/server/lib/credential-health.ts +343 -0
- package/server/lib/credential-import.ts +608 -0
- package/server/lib/credential-scope.ts +102 -0
- package/server/lib/credential-shares.ts +190 -0
- package/server/lib/credential-transport.ts +533 -0
- package/server/lib/credential-vault.ts +77 -0
- package/server/lib/credentials.ts +422 -0
- package/server/lib/crypto.ts +8 -0
- package/server/lib/db.ts +58 -0
- package/server/lib/defaults.ts +386 -0
- package/server/lib/dex/index.ts +80 -0
- package/server/lib/dex/relay.ts +235 -0
- package/server/lib/dex/types.ts +59 -0
- package/server/lib/dex/uniswap.ts +370 -0
- package/server/lib/diary.ts +34 -0
- package/server/lib/dont-ask-again-policy.ts +41 -0
- package/server/lib/e2e-agent/artifacts.ts +36 -0
- package/server/lib/e2e-agent/contracts.ts +112 -0
- package/server/lib/e2e-agent/validation.ts +135 -0
- package/server/lib/encrypt.ts +114 -0
- package/server/lib/error.ts +20 -0
- package/server/lib/events.ts +217 -0
- package/server/lib/feature-flags.ts +93 -0
- package/server/lib/hot.ts +357 -0
- package/server/lib/human-action-summary.ts +80 -0
- package/server/lib/key-fingerprint.ts +28 -0
- package/server/lib/logger.ts +340 -0
- package/server/lib/network.ts +137 -0
- package/server/lib/notifications.ts +230 -0
- package/server/lib/oauth2-refresh.ts +241 -0
- package/server/lib/oursecret.ts +71 -0
- package/server/lib/passkey-credential.ts +360 -0
- package/server/lib/passkey.ts +68 -0
- package/server/lib/permissions.ts +299 -0
- package/server/lib/pino.ts +24 -0
- package/server/lib/policy-preview.ts +138 -0
- package/server/lib/price.ts +338 -0
- package/server/lib/prices.ts +34 -0
- package/server/lib/project-scope.ts +297 -0
- package/server/lib/resolve-action.ts +328 -0
- package/server/lib/resolve.ts +36 -0
- package/server/lib/secret-gist-share.ts +296 -0
- package/server/lib/sessions.ts +634 -0
- package/server/lib/socket-path.ts +56 -0
- package/server/lib/solana/connection.ts +26 -0
- package/server/lib/solana/jupiter.ts +128 -0
- package/server/lib/solana/transfer.ts +108 -0
- package/server/lib/solana/wallet.ts +136 -0
- package/server/lib/strategy/emits.ts +21 -0
- package/server/lib/strategy/engine.ts +1305 -0
- package/server/lib/strategy/executor.ts +115 -0
- package/server/lib/strategy/hook-context.ts +159 -0
- package/server/lib/strategy/hooks.ts +990 -0
- package/server/lib/strategy/index.ts +28 -0
- package/server/lib/strategy/installer.ts +305 -0
- package/server/lib/strategy/loader.ts +256 -0
- package/server/lib/strategy/message.ts +237 -0
- package/server/lib/strategy/repository.ts +218 -0
- package/server/lib/strategy/session-logger.ts +693 -0
- package/server/lib/strategy/sources.ts +288 -0
- package/server/lib/strategy/state.ts +189 -0
- package/server/lib/strategy/templates.ts +403 -0
- package/server/lib/strategy/tick.ts +404 -0
- package/server/lib/strategy/types.ts +230 -0
- package/server/lib/swap.ts +3 -0
- package/server/lib/temp.ts +86 -0
- package/server/lib/token-metadata.ts +86 -0
- package/server/lib/token-safety.ts +200 -0
- package/server/lib/token-search.ts +444 -0
- package/server/lib/totp.ts +194 -0
- package/server/lib/transactions.ts +123 -0
- package/server/lib/transport.ts +84 -0
- package/server/lib/txhistory/decoder.ts +262 -0
- package/server/lib/txhistory/enricher.ts +652 -0
- package/server/lib/txhistory/index.ts +391 -0
- package/server/lib/txhistory/signatures.ts +59 -0
- package/server/lib/update-check.ts +35 -0
- package/server/lib/verified-summary.ts +414 -0
- package/server/lib/view-registry.ts +80 -0
- package/server/mcp/profile-policy.ts +30 -0
- package/server/mcp/server.ts +1589 -0
- package/server/mcp/tools.ts +276 -0
- package/server/middleware/auth.ts +119 -0
- package/server/middleware/requestLogger.ts +84 -0
- package/server/routes/actions.ts +539 -0
- package/server/routes/adapters.ts +711 -0
- package/server/routes/addressbook.ts +113 -0
- package/server/routes/ai.ts +34 -0
- package/server/routes/apikeys.ts +343 -0
- package/server/routes/apps.ts +601 -0
- package/server/routes/auth.ts +406 -0
- package/server/routes/backup.ts +404 -0
- package/server/routes/batch.ts +270 -0
- package/server/routes/bookmarks.ts +162 -0
- package/server/routes/credential-shares.ts +380 -0
- package/server/routes/credential-vaults.ts +159 -0
- package/server/routes/credentials.ts +1782 -0
- package/server/routes/dashboard.ts +97 -0
- package/server/routes/defaults.ts +124 -0
- package/server/routes/flags.ts +11 -0
- package/server/routes/fund.ts +225 -0
- package/server/routes/heartbeat.ts +375 -0
- package/server/routes/import.ts +364 -0
- package/server/routes/launch.ts +665 -0
- package/server/routes/lock.ts +54 -0
- package/server/routes/logs.ts +68 -0
- package/server/routes/nuke.ts +111 -0
- package/server/routes/passkey-credentials.ts +99 -0
- package/server/routes/passkey.ts +366 -0
- package/server/routes/portfolio.ts +217 -0
- package/server/routes/price.ts +63 -0
- package/server/routes/resolve.ts +31 -0
- package/server/routes/security.ts +45 -0
- package/server/routes/send-evm.ts +241 -0
- package/server/routes/send-solana.ts +281 -0
- package/server/routes/send.ts +178 -0
- package/server/routes/setup.ts +210 -0
- package/server/routes/strategy.ts +894 -0
- package/server/routes/swap-evm.ts +352 -0
- package/server/routes/swap-solana.ts +176 -0
- package/server/routes/swap.ts +356 -0
- package/server/routes/token.ts +247 -0
- package/server/routes/unlock.ts +467 -0
- package/server/routes/views.ts +41 -0
- package/server/routes/wallet-assets.ts +361 -0
- package/server/routes/wallet-transactions.ts +515 -0
- package/server/routes/wallet.ts +709 -0
- package/server/types.ts +146 -0
- package/shared/credential-field-schema.ts +248 -0
- package/skills/auramaxx/HEARTBEAT.md +78 -0
- package/skills/auramaxx/SKILL.md +745 -0
- package/skills/auramaxx/docs/AGENT_SETUP.md +155 -0
- package/skills/auramaxx/docs/API.md +127 -0
- package/skills/auramaxx/docs/AUTH.md +318 -0
- package/skills/auramaxx/docs/CLI.md +130 -0
- package/skills/auramaxx/docs/MCP.md +122 -0
- package/skills/auramaxx/docs/TROUBLESHOOTING.md +357 -0
- package/skills/auramaxx/docs/WORKSPACE.md +673 -0
- package/skills/auramaxx/docs/security.md +227 -0
- package/skills/task-lifecycle/SKILL.md +378 -0
- package/src/app/api/[...doc]/page.tsx +36 -0
- package/src/app/api/agent-requests/route.ts +30 -0
- package/src/app/api/apps/install/route.ts +132 -0
- package/src/app/api/apps/manifests/route.ts +16 -0
- package/src/app/api/apps/static/[...path]/route.ts +57 -0
- package/src/app/api/docs/plain/route.ts +74 -0
- package/src/app/api/events/route.ts +92 -0
- package/src/app/api/page.tsx +290 -0
- package/src/app/api/workspace/[id]/apps/[wid]/route.ts +119 -0
- package/src/app/api/workspace/[id]/apps/route.ts +81 -0
- package/src/app/api/workspace/[id]/export/route.ts +67 -0
- package/src/app/api/workspace/[id]/route.ts +168 -0
- package/src/app/api/workspace/auth.ts +40 -0
- package/src/app/api/workspace/config/route.ts +121 -0
- package/src/app/api/workspace/import/route.ts +127 -0
- package/src/app/api/workspace/route.ts +116 -0
- package/src/app/app-legacy-do-not-use/page.tsx +2245 -0
- package/src/app/apple-icon.png +0 -0
- package/src/app/approve/[actionId]/page.tsx +409 -0
- package/src/app/docs/DocsPageContent.tsx +269 -0
- package/src/app/docs/[...doc]/page.tsx +41 -0
- package/src/app/docs/page.tsx +38 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +819 -0
- package/src/app/health/page.tsx +5 -0
- package/src/app/hello/page.tsx +102 -0
- package/src/app/icon.png +0 -0
- package/src/app/layout.tsx +39 -0
- package/src/app/page.tsx +1964 -0
- package/src/app/privacy/page.tsx +63 -0
- package/src/app/providers.tsx +87 -0
- package/src/app/share/[token]/page.tsx +295 -0
- package/src/app/terms/page.tsx +80 -0
- package/src/components/ChainSelector.tsx +44 -0
- package/src/components/HumanActionBar.tsx +697 -0
- package/src/components/NotificationDrawer.tsx +387 -0
- package/src/components/PasskeyEnrollmentPrompt.tsx +235 -0
- package/src/components/apps/AgentKeysApp.tsx +490 -0
- package/src/components/apps/App.tsx +153 -0
- package/src/components/apps/AppGrid.tsx +15 -0
- package/src/components/apps/DetailedAddressDrawer.tsx +325 -0
- package/src/components/apps/DraggableApp.tsx +562 -0
- package/src/components/apps/IFrameApp.tsx +73 -0
- package/src/components/apps/LogsApp.tsx +360 -0
- package/src/components/apps/SendApp.tsx +394 -0
- package/src/components/apps/SetupWizardApp.tsx +1004 -0
- package/src/components/apps/SystemDefaultsApp.tsx +845 -0
- package/src/components/apps/ThirdPartyApp.tsx +428 -0
- package/src/components/apps/TokenApp.tsx +319 -0
- package/src/components/apps/TransactionsApp.tsx +438 -0
- package/src/components/apps/WalletDetailApp.tsx +1505 -0
- package/src/components/apps/index.ts +13 -0
- package/src/components/design-system/Button.tsx +88 -0
- package/src/components/design-system/ChainIndicator.tsx +65 -0
- package/src/components/design-system/ChainSelector.tsx +147 -0
- package/src/components/design-system/ConfirmationModal.tsx +107 -0
- package/src/components/design-system/ConfirmationPopover.tsx +81 -0
- package/src/components/design-system/DownloadButton.tsx +149 -0
- package/src/components/design-system/Drawer.tsx +133 -0
- package/src/components/design-system/FilterDropdown.tsx +183 -0
- package/src/components/design-system/ItemPicker.tsx +157 -0
- package/src/components/design-system/Modal.tsx +296 -0
- package/src/components/design-system/Popover.tsx +142 -0
- package/src/components/design-system/TextInput.tsx +85 -0
- package/src/components/design-system/Toggle.tsx +65 -0
- package/src/components/design-system/TyvekCollapsibleSection.tsx +55 -0
- package/src/components/design-system/index.ts +14 -0
- package/src/components/docs/ClientSideMarkdown.tsx +51 -0
- package/src/components/docs/DocsSearchBar.tsx +118 -0
- package/src/components/docs/DocsThemeToggle.tsx +38 -0
- package/src/components/docs/PersistentDocGroup.tsx +91 -0
- package/src/components/docs/ShareUrlButton.tsx +33 -0
- package/src/components/docs/SidebarScrollMemory.tsx +56 -0
- package/src/components/health/CredentialHealthDashboard.tsx +214 -0
- package/src/components/icons/ChainIcons.tsx +72 -0
- package/src/components/layout/AppStoreDrawer.tsx +369 -0
- package/src/components/layout/ContentArea.tsx +21 -0
- package/src/components/layout/CreateViewModal.tsx +88 -0
- package/src/components/layout/LeftRail.tsx +114 -0
- package/src/components/layout/TabBar.tsx +284 -0
- package/src/components/layout/WalletSidebar.tsx +1030 -0
- package/src/components/layout/index.ts +6 -0
- package/src/components/marketing/AuraMaxxSpecOverlay.tsx +653 -0
- package/src/components/marketing/DeviceMorphExperience.tsx +216 -0
- package/src/components/vault/ApiKeysConsole.tsx +1272 -0
- package/src/components/vault/AuditConsole.tsx +600 -0
- package/src/components/vault/CredentialDetail.tsx +625 -0
- package/src/components/vault/CredentialEmpty.tsx +55 -0
- package/src/components/vault/CredentialField.tsx +583 -0
- package/src/components/vault/CredentialForm.tsx +1484 -0
- package/src/components/vault/CredentialList.tsx +265 -0
- package/src/components/vault/CredentialRow.tsx +130 -0
- package/src/components/vault/CredentialShareModal.tsx +273 -0
- package/src/components/vault/CredentialVault.tsx +1662 -0
- package/src/components/vault/CredentialWalletWidget.tsx +103 -0
- package/src/components/vault/DocsConsole.tsx +113 -0
- package/src/components/vault/ImportCredentialsModal.tsx +578 -0
- package/src/components/vault/LargeTypeModal.tsx +88 -0
- package/src/components/vault/PasswordGenerator.tsx +232 -0
- package/src/components/vault/TOTPDisplay.tsx +108 -0
- package/src/components/vault/TotpSetupPanel.tsx +198 -0
- package/src/components/vault/VaultSidebar.tsx +881 -0
- package/src/components/vault/credentialFormName.ts +91 -0
- package/src/components/vault/hooks/useVaultKeyboardShortcuts.ts +69 -0
- package/src/components/vault/types.ts +56 -0
- package/src/context/AuthContext.tsx +365 -0
- package/src/context/PriceContext.tsx +113 -0
- package/src/context/ThemeContext.tsx +164 -0
- package/src/context/WebSocketContext.tsx +269 -0
- package/src/context/WorkspaceContext.tsx +668 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useAgentActions.ts +552 -0
- package/src/hooks/useBalance.ts +103 -0
- package/src/hooks/useBalances.ts +129 -0
- package/src/hooks/useTheme.ts +156 -0
- package/src/instrumentation.ts +12 -0
- package/src/lib/api-docs.ts +154 -0
- package/src/lib/api.ts +474 -0
- package/src/lib/app-loader.ts +148 -0
- package/src/lib/app-registry.ts +178 -0
- package/src/lib/app-sdk.ts +157 -0
- package/src/lib/audit-console-adapter.ts +151 -0
- package/src/lib/auth-client.ts +75 -0
- package/src/lib/config.ts +74 -0
- package/src/lib/credential-field-schema.ts +11 -0
- package/src/lib/crypto.ts +112 -0
- package/src/lib/db.ts +21 -0
- package/src/lib/docs.ts +544 -0
- package/src/lib/events.ts +363 -0
- package/src/lib/pino.ts +24 -0
- package/src/lib/theme-handlers.ts +168 -0
- package/src/lib/theme.ts +351 -0
- package/src/lib/tokenData.ts +378 -0
- package/src/lib/totp-import.ts +57 -0
- package/src/lib/vault-crypto.ts +129 -0
- package/src/lib/view-registry.ts +57 -0
- package/src/lib/websocket-server.ts +302 -0
- package/src/lib/websocket-setup.ts +79 -0
- package/src/lib/wordlist.ts +2050 -0
- package/src/lib/workspace-handlers.ts +285 -0
- package/start.sh +170 -0
- package/tailwind.config.ts +99 -0
- package/tsconfig.json +42 -0
|
@@ -0,0 +1,713 @@
|
|
|
1
|
+
# Developing Strategies
|
|
2
|
+
|
|
3
|
+
Reference for extending an app with AI-powered automation — strategy manifest fields, hooks, sources, intents, and examples.
|
|
4
|
+
|
|
5
|
+
A strategy is an app with additional manifest fields that activate the AI engine. Start with [DEVELOPING-APPS.md](../DEVELOPING-APPS.md) for the base app manifest, SDK, and security model.
|
|
6
|
+
|
|
7
|
+
For a high-level overview, see [STRATEGY.md](./STRATEGY.md). For AI engine internals (provider selection, tool-use loop, testing), see [AI.md](./AI.md).
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
1. [Strategy Manifest Fields](#strategy-manifest-fields)
|
|
12
|
+
2. [Tick Tiers and Jobs](#tick-tiers-and-jobs)
|
|
13
|
+
3. [Hooks Lifecycle](#hooks-lifecycle)
|
|
14
|
+
4. [Hook Response Format](#hook-response-format)
|
|
15
|
+
5. [Hook Contexts](#hook-contexts)
|
|
16
|
+
6. [Intent Format and Approval Modes](#intent-format-and-approval-modes)
|
|
17
|
+
7. [Pre-Computed Actions](#pre-computed-actions)
|
|
18
|
+
8. [Sources](#sources)
|
|
19
|
+
9. [Config](#config)
|
|
20
|
+
10. [Auto-Granted Permissions](#auto-granted-permissions)
|
|
21
|
+
11. [Budget-Aware Intent Decisions](#budget-aware-intent-decisions)
|
|
22
|
+
12. [State Management](#state-management)
|
|
23
|
+
13. [Error Handling Config](#error-handling-config)
|
|
24
|
+
14. [Validation Rules](#validation-rules)
|
|
25
|
+
15. [Tool-Use in Hooks](#tool-use-in-hooks)
|
|
26
|
+
16. [AI Provider Selection and Tiered Models](#ai-provider-selection-and-tiered-models)
|
|
27
|
+
17. [DB-Backed Template Strategies](#db-backed-template-strategies)
|
|
28
|
+
18. [Example: Tick-Mode Strategy](#example-tick-mode-strategy)
|
|
29
|
+
19. [Example: Message-Mode Chat App](#example-message-mode-chat-app)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Strategy Manifest Fields
|
|
34
|
+
|
|
35
|
+
The manifest is a Markdown file (`app.md`) with YAML frontmatter — the same format used by all apps (see [DEVELOPING-APPS.md](../DEVELOPING-APPS.md#manifest-reference)). The body text after `---` is the description shown in the App Store. A strategy adds the fields below to the base app manifest.
|
|
36
|
+
|
|
37
|
+
### Base Fields (from app manifest)
|
|
38
|
+
|
|
39
|
+
These fields are shared with all apps. See [DEVELOPING-APPS.md](../DEVELOPING-APPS.md#manifest-reference) for full details.
|
|
40
|
+
|
|
41
|
+
| Field | Type | Required | Default | Description |
|
|
42
|
+
|-------|------|:---:|---------|-------------|
|
|
43
|
+
| `name` | string | yes | folder name | Display name |
|
|
44
|
+
| `icon` | string | no | `Box` | [Lucide](https://lucide.dev) icon name |
|
|
45
|
+
| `category` | string | no | `general` | App Store category filter |
|
|
46
|
+
| `size` | string | no | `1x1` | Default grid size `WxH` (1=320x280, 2=640x560, 3=960x840) |
|
|
47
|
+
| `permissions` | string[] | no | `[]` | Wallet permissions the app needs |
|
|
48
|
+
|
|
49
|
+
### Strategy Fields
|
|
50
|
+
|
|
51
|
+
These fields activate the AI engine and are specific to strategies.
|
|
52
|
+
|
|
53
|
+
| Field | Type | Required | Default | Description |
|
|
54
|
+
|-------|------|:---:|---------|-------------|
|
|
55
|
+
| `autoStart` | boolean | no | `false` | Auto-enable on engine startup |
|
|
56
|
+
| `ticker` | string | no | — | Tick tier. One of: `sniper`, `active`, `standard`, `slow`, `maintenance`. Mutually exclusive with `jobs`. |
|
|
57
|
+
| `jobs` | array | no | — | Multi-interval jobs. Mutually exclusive with `ticker`. |
|
|
58
|
+
| `sources` | array | no | `[]` | External data endpoints fetched each tick |
|
|
59
|
+
| `keys` | array | no | — | API key declarations |
|
|
60
|
+
| `hooks` | object | yes* | — | Hook instructions (at least one of `tick` or `message` required) |
|
|
61
|
+
| `config` | object | no | `{}` | Strategy config passed to hooks |
|
|
62
|
+
| `limits` | object | no | — | Spending caps: `{ fund?: number, send?: number }` |
|
|
63
|
+
| `allowedHosts` | string[] | no | `[]` | Hostnames allowed for external fetches (SSRF allowlist) |
|
|
64
|
+
|
|
65
|
+
### Permissions
|
|
66
|
+
|
|
67
|
+
Strategies use the same permission system as all apps. Strategies with permissions or limits require human approval before the engine creates auth tokens.
|
|
68
|
+
|
|
69
|
+
See [DEVELOPING-APPS.md](../DEVELOPING-APPS.md#permissions) for the full permissions table, or [AUTH.md](../AUTH.md) for complete auth details.
|
|
70
|
+
|
|
71
|
+
Note: the `action:create` permission is required for strategies that use the `request_human_action` tool in message hooks.
|
|
72
|
+
|
|
73
|
+
### Limits
|
|
74
|
+
|
|
75
|
+
Spending caps embedded in the strategy's token:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
limits:
|
|
79
|
+
fund: 1.0 # Max 1 ETH cold-to-hot transfer
|
|
80
|
+
send: 0.5 # Max 0.5 ETH sends
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Allowed Hosts
|
|
84
|
+
|
|
85
|
+
Hostnames (no protocol, no path) the strategy engine may fetch. Hosts from `sources[].url` are auto-derived, so you only need to list additional hosts used by templated URLs or external action endpoints.
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
allowedHosts:
|
|
89
|
+
- api.coingecko.com
|
|
90
|
+
- api.dexscreener.com
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Private/reserved hosts (`localhost`, `127.0.0.1`, `10.x`, `192.168.x`, etc.) are always blocked.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Tick Tiers and Jobs
|
|
98
|
+
|
|
99
|
+
### Tick Tiers
|
|
100
|
+
|
|
101
|
+
| Tier | Interval | Use Case |
|
|
102
|
+
|------|----------|----------|
|
|
103
|
+
| `sniper` | 10 seconds | Time-critical sniping, MEV |
|
|
104
|
+
| `active` | 30 seconds | Active trading, price triggers |
|
|
105
|
+
| `standard` | 1 minute | General monitoring |
|
|
106
|
+
| `slow` | 5 minutes | Portfolio tracking, reporting |
|
|
107
|
+
| `maintenance` | 1 hour | Daily buys, maintenance tasks |
|
|
108
|
+
|
|
109
|
+
### Jobs
|
|
110
|
+
|
|
111
|
+
For strategies that need multiple tick intervals, use `jobs` instead of `ticker`:
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
jobs:
|
|
115
|
+
- id: price_check
|
|
116
|
+
ticker: active
|
|
117
|
+
sources:
|
|
118
|
+
- price # Only fetch these sources for this job
|
|
119
|
+
- id: rebalance
|
|
120
|
+
ticker: maintenance
|
|
121
|
+
sources:
|
|
122
|
+
- portfolio
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Field | Type | Required | Description |
|
|
126
|
+
|-------|------|:---:|-------------|
|
|
127
|
+
| `id` | string | yes | Job identifier (passed to tick context) |
|
|
128
|
+
| `ticker` | string | yes | Tick tier for this job |
|
|
129
|
+
| `sources` | string[] | no | Source IDs to fetch (defaults to all) |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Hooks Lifecycle
|
|
134
|
+
|
|
135
|
+
Six lifecycle hooks. Each is a natural-language string instructing the AI what to do. The engine passes structured JSON context and expects a JSON response.
|
|
136
|
+
|
|
137
|
+
| Hook | When Called | Mode |
|
|
138
|
+
|------|-----------|------|
|
|
139
|
+
| `init` | Strategy enabled | Tick |
|
|
140
|
+
| `tick` | Every scheduled interval | Tick |
|
|
141
|
+
| `execute` | Per approved intent (if no pre-computed action) | Tick |
|
|
142
|
+
| `result` | After action execution | Tick |
|
|
143
|
+
| `shutdown` | Strategy disabled | Tick |
|
|
144
|
+
| `message` | Human sends a message | Message |
|
|
145
|
+
|
|
146
|
+
### Tick Mode Flow
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
fetch sources -> tick hook -> intents -> (approve?) -> execute hook -> action -> result hook
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
1. Engine fetches all `sources`
|
|
153
|
+
2. Calls `tick` hook with source data, state, config, budget
|
|
154
|
+
3. AI returns intents (what to do)
|
|
155
|
+
4. If `config.approve: true` or intent has `permissions[]`, human approves
|
|
156
|
+
5. For each approved intent: `execute` hook (or pre-computed action) -> API call -> `result` hook
|
|
157
|
+
6. `result` hook can return follow-up intents (depth limit: 3)
|
|
158
|
+
|
|
159
|
+
### Message Mode Flow
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
user message -> message hook (with tools) -> reply + optional intents
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
1. User sends message via `AuraApp.send()` or adapter
|
|
166
|
+
2. Engine calls `message` hook with AI tools (`wallet_api`, `request_human_action`)
|
|
167
|
+
3. AI uses tools directly (try action -> 403 -> request approval)
|
|
168
|
+
4. Returns reply text and state updates
|
|
169
|
+
|
|
170
|
+
### Auto-Injected Context
|
|
171
|
+
|
|
172
|
+
You do **not** need to embed API docs or intent format instructions in your hooks. The engine auto-injects (via `hook-context.ts`):
|
|
173
|
+
|
|
174
|
+
- API endpoint reference (from `docs/API.md`)
|
|
175
|
+
- Response format specification
|
|
176
|
+
- Intent format with `permissions`, `limits`, `ttl`, `action`, `summary` fields
|
|
177
|
+
- Wallet tier documentation (COLD/HOT/TEMP)
|
|
178
|
+
- Budget-aware decision logic
|
|
179
|
+
|
|
180
|
+
Keep hook instructions focused on your app's specific behavior.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Hook Response Format
|
|
185
|
+
|
|
186
|
+
All hooks return `HookResult`:
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"reply": "Text response to the user (message hooks)",
|
|
191
|
+
"state": { "key": "persisted state values" },
|
|
192
|
+
"intents": [{ "type": "swap", "token": "0xABC" }],
|
|
193
|
+
"log": "Optional log message",
|
|
194
|
+
"emit": { "channel": "event-name", "data": { "price": 42 } }
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
| Field | Type | Description |
|
|
199
|
+
|-------|------|-------------|
|
|
200
|
+
| `reply` | string | Text reply sent to the user (message hooks) |
|
|
201
|
+
| `state` | object | Key-value state updates to persist across ticks |
|
|
202
|
+
| `log` | string | Fallback reply if `reply` is absent; also logged |
|
|
203
|
+
| `intents` | array | High-level intents for the engine to execute (tick mode) |
|
|
204
|
+
| `emit` | object or array | Custom events pushed to the app's iframe. `{ channel, data }` or `[{ channel, data }, ...]` |
|
|
205
|
+
|
|
206
|
+
### Mode-Specific Response Patterns
|
|
207
|
+
|
|
208
|
+
**Tick mode** hooks should return:
|
|
209
|
+
```json
|
|
210
|
+
{ "state": { ... }, "intents": [{ "type": "buy", ... }] }
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Message mode** hooks should return:
|
|
214
|
+
```json
|
|
215
|
+
{ "reply": "Response text", "state": { ... } }
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Message hooks use the tool-call flow (wallet_api + request_human_action) instead of intents. You can still return intents from message hooks, but it's not the recommended pattern.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Hook Contexts
|
|
223
|
+
|
|
224
|
+
Each hook receives a structured JSON context. These are the TypeScript interfaces for reference.
|
|
225
|
+
|
|
226
|
+
### TickContext (tick hook)
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
{
|
|
230
|
+
sources: Record<string, unknown[]>; // Fetched source data by source ID
|
|
231
|
+
positions?: unknown[]; // Wallet positions
|
|
232
|
+
state: Record<string, unknown>; // Persisted strategy state
|
|
233
|
+
config: StrategyConfig; // Manifest config + overrides
|
|
234
|
+
wallets?: unknown[]; // Available wallets
|
|
235
|
+
permissions: string[]; // App token's permissions
|
|
236
|
+
budget: {
|
|
237
|
+
limits: Record<string, number>; // Spending caps (ETH)
|
|
238
|
+
spent: Record<string, number>; // Already spent this session
|
|
239
|
+
remaining: Record<string, number>; // Remaining budget
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### ExecuteContext (execute hook)
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
{
|
|
248
|
+
intent: Intent; // The approved intent to convert to an action
|
|
249
|
+
wallet?: unknown; // Selected wallet
|
|
250
|
+
config: StrategyConfig; // Manifest config
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### ResultContext (result hook)
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
{
|
|
258
|
+
intent: Intent; // The original intent
|
|
259
|
+
action: Action; // The executed API call
|
|
260
|
+
outcome: ActionOutcome; // { success: boolean, data?, error? }
|
|
261
|
+
state: Record<string, unknown>;
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### InitContext (init hook)
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
{
|
|
269
|
+
config: StrategyConfig;
|
|
270
|
+
wallets?: unknown[];
|
|
271
|
+
state: Record<string, unknown>;
|
|
272
|
+
storage?: Record<string, unknown>;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### ShutdownContext (shutdown hook)
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
{
|
|
280
|
+
positions?: unknown[];
|
|
281
|
+
state: Record<string, unknown>;
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### MessageContext (message hook)
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
{
|
|
289
|
+
message: string; // User's message text
|
|
290
|
+
appId: string; // App identifier
|
|
291
|
+
state: Record<string, unknown>;
|
|
292
|
+
config: StrategyConfig;
|
|
293
|
+
permissions: string[]; // App token's permissions
|
|
294
|
+
budget: {
|
|
295
|
+
limits: Record<string, number>;
|
|
296
|
+
spent: Record<string, number>;
|
|
297
|
+
remaining: Record<string, number>;
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Intent Format and Approval Modes
|
|
305
|
+
|
|
306
|
+
Intents returned by `tick` or `message` hooks:
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
{
|
|
310
|
+
"type": "swap",
|
|
311
|
+
"summary": "Buy 0.01 ETH of TOKEN",
|
|
312
|
+
"permissions": ["swap"],
|
|
313
|
+
"limits": { "swap": 0.01 },
|
|
314
|
+
"ttl": 60,
|
|
315
|
+
"action": {
|
|
316
|
+
"endpoint": "/swap",
|
|
317
|
+
"method": "POST",
|
|
318
|
+
"body": { "tokenIn": "ETH", "tokenOut": "0xABC", "amountIn": "0.01" }
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
| Field | Type | Required | Description |
|
|
324
|
+
|-------|------|:---:|-------------|
|
|
325
|
+
| `type` | string | yes | Intent type label |
|
|
326
|
+
| `summary` | string | no | Human-readable description for approval card |
|
|
327
|
+
| `permissions` | string[] | no | Triggers per-action token flow with human approval |
|
|
328
|
+
| `limits` | object | no | Spending caps for the temp token |
|
|
329
|
+
| `ttl` | number | no | Token lifetime in seconds (default: 60) |
|
|
330
|
+
| `action` | object | no | Pre-computed API call (skips `execute` hook) |
|
|
331
|
+
| `action.endpoint` | string | — | API path (`/swap`) or external URL |
|
|
332
|
+
| `action.method` | string | — | HTTP method |
|
|
333
|
+
| `action.body` | object | — | Request body |
|
|
334
|
+
| `action.headers` | object | — | Custom headers |
|
|
335
|
+
|
|
336
|
+
### Approval Modes
|
|
337
|
+
|
|
338
|
+
| Intent has `permissions`? | `config.approve`? | Result |
|
|
339
|
+
|:---:|:---:|---|
|
|
340
|
+
| Yes | Any | Per-action token, individual approval per intent |
|
|
341
|
+
| No | true | Batch boolean approval |
|
|
342
|
+
| No | false | No approval needed |
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Pre-Computed Actions
|
|
347
|
+
|
|
348
|
+
Hooks can return intents with an `action` field to skip the `execute` hook entirely:
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"type": "swap",
|
|
353
|
+
"summary": "Buy 0.01 ETH of TOKEN",
|
|
354
|
+
"action": {
|
|
355
|
+
"endpoint": "/swap",
|
|
356
|
+
"method": "POST",
|
|
357
|
+
"body": { "tokenIn": "ETH", "tokenOut": "0xABC", "amountIn": "0.01" }
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
When `action` is present, the engine calls the API directly instead of invoking the `execute` hook. This is useful when the tick hook already has all the information needed to construct the API call.
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Sources
|
|
367
|
+
|
|
368
|
+
External data endpoints fetched before each tick. Results are passed to the `tick` hook as `sources.<id>`.
|
|
369
|
+
|
|
370
|
+
```yaml
|
|
371
|
+
sources:
|
|
372
|
+
- id: price
|
|
373
|
+
url: https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd
|
|
374
|
+
method: GET
|
|
375
|
+
select:
|
|
376
|
+
items: $.ethereum
|
|
377
|
+
price: $.usd
|
|
378
|
+
|
|
379
|
+
- id: holders
|
|
380
|
+
url: https://api.example.com/holders/${token}
|
|
381
|
+
method: GET
|
|
382
|
+
auth: header
|
|
383
|
+
header: X-API-KEY
|
|
384
|
+
key: example_key
|
|
385
|
+
depends: price
|
|
386
|
+
optional: true
|
|
387
|
+
select:
|
|
388
|
+
items: $.data
|
|
389
|
+
address: $.holder
|
|
390
|
+
balance: $.amount
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Source Fields
|
|
394
|
+
|
|
395
|
+
| Field | Type | Required | Default | Description |
|
|
396
|
+
|-------|------|:---:|---------|-------------|
|
|
397
|
+
| `id` | string | yes | — | Unique identifier (referenced in `jobs[].sources` and `depends`) |
|
|
398
|
+
| `url` | string | yes | — | URL template. `${var}` resolves from parent source `select` fields or `config` |
|
|
399
|
+
| `method` | string | yes | — | `GET` or `POST` |
|
|
400
|
+
| `body` | object | no | — | POST request body template |
|
|
401
|
+
| `auth` | string | no | `none` | Auth mode: `none`, `header`, `query`, `bearer` |
|
|
402
|
+
| `header` | string | no | — | Header name when `auth: header` |
|
|
403
|
+
| `query` | string | no | — | Query param name when `auth: query` |
|
|
404
|
+
| `key` | string | no | — | App storage key to read the API key from |
|
|
405
|
+
| `depends` | string | no | — | Source ID that must run first (enables URL template chaining) |
|
|
406
|
+
| `job` | string | no | — | Job ID this source belongs to |
|
|
407
|
+
| `optional` | boolean | no | `false` | Skip if API key not found in storage |
|
|
408
|
+
| `rateLimit` | string | no | — | Rate limit specification |
|
|
409
|
+
| `select` | object | no | — | JSONPath extraction: `items` = path to array, other keys = per-item field paths |
|
|
410
|
+
|
|
411
|
+
### URL Templates
|
|
412
|
+
|
|
413
|
+
Source URLs can contain `${var}` placeholders resolved from:
|
|
414
|
+
1. `select` fields of a parent source (via `depends`)
|
|
415
|
+
2. `config` values
|
|
416
|
+
|
|
417
|
+
Templated external URLs require explicit `allowedHosts`.
|
|
418
|
+
|
|
419
|
+
### API Key Auth
|
|
420
|
+
|
|
421
|
+
Sources that need auth reference a key stored in app storage:
|
|
422
|
+
|
|
423
|
+
```yaml
|
|
424
|
+
- id: analytics
|
|
425
|
+
url: https://public-api.birdeye.so/defi/token_overview?address=${mint}
|
|
426
|
+
auth: header
|
|
427
|
+
header: X-API-KEY
|
|
428
|
+
key: birdeye # reads from AuraApp.storage.get('birdeye')
|
|
429
|
+
optional: true # skip if key not in storage
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
The app developer builds the UI for entering and saving the key via `AuraApp.storage.set('birdeye', 'sk-...')`.
|
|
433
|
+
|
|
434
|
+
### Keys
|
|
435
|
+
|
|
436
|
+
Declare API keys the strategy needs. Informational — helps users know which keys to configure.
|
|
437
|
+
|
|
438
|
+
```yaml
|
|
439
|
+
keys:
|
|
440
|
+
- id: birdeye
|
|
441
|
+
name: Birdeye API Key
|
|
442
|
+
required: false
|
|
443
|
+
description: Used for token analytics data
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
| Field | Type | Required | Description |
|
|
447
|
+
|-------|------|:---:|-------------|
|
|
448
|
+
| `id` | string | yes | Key identifier (matches `sources[].key`) |
|
|
449
|
+
| `name` | string | yes | Display name |
|
|
450
|
+
| `required` | boolean | no | Whether the key is required for the app to function |
|
|
451
|
+
| `description` | string | no | What the key is used for |
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Config
|
|
456
|
+
|
|
457
|
+
The `config` object is passed to every hook invocation. It supports both special engine-recognized fields and custom fields.
|
|
458
|
+
|
|
459
|
+
### Special Config Fields
|
|
460
|
+
|
|
461
|
+
| Field | Type | Description |
|
|
462
|
+
|-------|------|-------------|
|
|
463
|
+
| `wallet` | string | Preferred wallet address or `"auto"` |
|
|
464
|
+
| `approve` | boolean | `true` = require batch human approval between tick and execute |
|
|
465
|
+
| `mode` | string | `"live"` (execute actions) or `"paper"` (log only, no execution) |
|
|
466
|
+
|
|
467
|
+
All other config keys are custom and passed through to hooks.
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## Auto-Granted Permissions
|
|
472
|
+
|
|
473
|
+
The engine auto-grants these permissions — you don't need to list them in `permissions`:
|
|
474
|
+
|
|
475
|
+
- `app:storage` — State persistence (always granted)
|
|
476
|
+
- `app:accesskey` — Granted when sources use `key` fields
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## Budget-Aware Intent Decisions
|
|
481
|
+
|
|
482
|
+
The tick context includes a `budget` object with `limits`, `spent`, and `remaining` fields. The engine auto-injects budget-aware decision logic into the system context, so hook AIs can make informed decisions about whether to proceed with an action based on remaining budget.
|
|
483
|
+
|
|
484
|
+
```json
|
|
485
|
+
{
|
|
486
|
+
"budget": {
|
|
487
|
+
"limits": { "swap": 0.1 },
|
|
488
|
+
"spent": { "swap": 0.03 },
|
|
489
|
+
"remaining": { "swap": 0.07 }
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## State Management
|
|
497
|
+
|
|
498
|
+
- **In-memory**: `Map<string, Record<string, unknown>>` per app
|
|
499
|
+
- **Persistence**: REST calls to app storage (`PUT /apps/{id}/storage/_strategy_state`)
|
|
500
|
+
- **Restore**: Read from DB at tick start (picks up UI changes)
|
|
501
|
+
- **Auto-persist**: Every 5 minutes + on disable + on error
|
|
502
|
+
|
|
503
|
+
State is passed to hooks via the `state` field in the context and updated via the `state` field in the hook response.
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Error Handling Config
|
|
508
|
+
|
|
509
|
+
Configure how the engine handles failures via `config.errors`:
|
|
510
|
+
|
|
511
|
+
```yaml
|
|
512
|
+
config:
|
|
513
|
+
errors:
|
|
514
|
+
sourceFail: skip # What to do when a source fetch fails
|
|
515
|
+
executeFail: skip # What to do when an action fails
|
|
516
|
+
maxRetries: 3 # Max consecutive retries before pausing
|
|
517
|
+
cooldown: "5m" # Pause duration after max retries
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
| Field | Type | Default | Options | Description |
|
|
521
|
+
|-------|------|---------|---------|-------------|
|
|
522
|
+
| `sourceFail` | string | `skip` | `skip`, `retry`, `pause` | Behavior on source fetch failure |
|
|
523
|
+
| `executeFail` | string | `skip` | `skip`, `pause` | Behavior on action execution failure |
|
|
524
|
+
| `maxRetries` | number | — | — | Consecutive error count before pausing |
|
|
525
|
+
| `cooldown` | string | — | Duration string | Pause duration (e.g., `"5m"`, `"1h"`) |
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
## Validation Rules
|
|
530
|
+
|
|
531
|
+
The loader (`server/lib/strategy/loader.ts`) enforces these rules. A manifest that fails validation is skipped with a console error.
|
|
532
|
+
|
|
533
|
+
### Required Structure
|
|
534
|
+
|
|
535
|
+
- Must have **at least one** of: `ticker`, `jobs`, or `hooks.message`
|
|
536
|
+
- If `ticker` or `jobs` is set, `hooks.tick` is **required**
|
|
537
|
+
- `ticker` must be one of: `sniper`, `active`, `standard`, `slow`, `maintenance`
|
|
538
|
+
- Each job must have `id` and a valid `ticker`
|
|
539
|
+
|
|
540
|
+
### Source Validation
|
|
541
|
+
|
|
542
|
+
- Source `depends` must reference an existing source `id`
|
|
543
|
+
- No circular dependencies between sources
|
|
544
|
+
- Source URLs cannot point to private/reserved hosts (`localhost`, `127.0.0.1`, `10.x`, `192.168.x`, `::1`, etc.)
|
|
545
|
+
- If a source URL uses templates (`${var}`) and points externally, `allowedHosts` must be declared
|
|
546
|
+
- Source hosts must be listed in `allowedHosts` (auto-derived from static URLs, but templated URLs need explicit declaration)
|
|
547
|
+
|
|
548
|
+
### Host Validation
|
|
549
|
+
|
|
550
|
+
- `allowedHosts` entries cannot be private/reserved IPs or hostnames
|
|
551
|
+
- Hostnames only (no protocol, no path, no port)
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
|
|
555
|
+
## Tool-Use in Hooks
|
|
556
|
+
|
|
557
|
+
Hook AIs can call the wallet API mid-conversation:
|
|
558
|
+
|
|
559
|
+
- **`wallet_api`** — `{ method, endpoint, body }` — call any wallet server endpoint
|
|
560
|
+
- **`request_human_action`** — request approval for a privileged action (message hooks only)
|
|
561
|
+
|
|
562
|
+
See [AI.md](./AI.md#tool-use-api-access) for the full tool-use reference.
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
566
|
+
## AI Provider Selection and Tiered Models
|
|
567
|
+
|
|
568
|
+
Models are auto-selected using a 3-tier system based on the hook name and the token's permissions. No user configuration needed.
|
|
569
|
+
|
|
570
|
+
| Tier | When |
|
|
571
|
+
|------|------|
|
|
572
|
+
| `fast` | `init`/`shutdown` hooks, no token, or read-only permissions |
|
|
573
|
+
| `standard` | Write permissions (`wallet:create:hot`, `wallet:create:temp`) |
|
|
574
|
+
| `powerful` | Financial permissions (`swap`, `send:hot`, `send:temp`, `fund`, `launch`) or `admin:*` |
|
|
575
|
+
|
|
576
|
+
See [AI.md](./AI.md#ai-provider-selection) for provider details, model mappings, and configuration.
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## DB-Backed Template Strategies
|
|
581
|
+
|
|
582
|
+
In addition to file-based `app.md` manifests, strategies can be created via the API from pre-built templates. These use the same `StrategyManifest` shape internally but are stored in the database.
|
|
583
|
+
|
|
584
|
+
Available templates: `recurring_buy`, `buy_on_drop`, `stop_loss`, `portfolio_report`.
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
# Create from template
|
|
588
|
+
curl -X POST http://localhost:4242/strategies \
|
|
589
|
+
-H "Authorization: Bearer <token>" \
|
|
590
|
+
-d '{ "templateId": "recurring_buy", "name": "Daily ETH Buy", "config": { ... } }'
|
|
591
|
+
|
|
592
|
+
# Install from raw manifest
|
|
593
|
+
curl -X POST http://localhost:4242/strategies/install \
|
|
594
|
+
-H "Authorization: Bearer <token>" \
|
|
595
|
+
-d '{ "manifest": { ... }, "approve": false }'
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
Template strategies have Zod-validated config schemas and capped permissions/limits defined by the template. See `server/lib/strategy/templates.ts` for template definitions.
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## Example: Tick-Mode Strategy
|
|
603
|
+
|
|
604
|
+
A price-alert app that monitors a token and emits a notification when the price drops.
|
|
605
|
+
|
|
606
|
+
```markdown
|
|
607
|
+
---
|
|
608
|
+
name: Price Alert
|
|
609
|
+
icon: Bell
|
|
610
|
+
category: strategy
|
|
611
|
+
size: 2x1
|
|
612
|
+
permissions:
|
|
613
|
+
- wallet:list
|
|
614
|
+
allowedHosts: []
|
|
615
|
+
|
|
616
|
+
ticker: standard
|
|
617
|
+
|
|
618
|
+
sources:
|
|
619
|
+
- id: price
|
|
620
|
+
url: /price/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
|
621
|
+
method: GET
|
|
622
|
+
select:
|
|
623
|
+
items: $
|
|
624
|
+
priceUsd: $.priceUsd
|
|
625
|
+
|
|
626
|
+
hooks:
|
|
627
|
+
init: |
|
|
628
|
+
Initialize state with empty lastPrice. No wallets needed for this strategy.
|
|
629
|
+
Return: { "state": { "lastPrice": null, "alertCount": 0 } }
|
|
630
|
+
|
|
631
|
+
tick: |
|
|
632
|
+
Compare current price to state.lastPrice.
|
|
633
|
+
If price dropped more than 5% since last check, return a notify intent.
|
|
634
|
+
Always update state.lastPrice with current price.
|
|
635
|
+
|
|
636
|
+
If no significant change:
|
|
637
|
+
{ "state": { "lastPrice": <current> }, "intents": [] }
|
|
638
|
+
|
|
639
|
+
If price dropped >5%:
|
|
640
|
+
{
|
|
641
|
+
"state": { "lastPrice": <current>, "alertCount": <state.alertCount + 1> },
|
|
642
|
+
"intents": [],
|
|
643
|
+
"emit": { "channel": "price-alert", "data": { "price": <current>, "drop": <percent> } }
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
shutdown: |
|
|
647
|
+
No cleanup needed.
|
|
648
|
+
Return: { "state": {} }
|
|
649
|
+
|
|
650
|
+
config:
|
|
651
|
+
dropThreshold: 5
|
|
652
|
+
mode: live
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
Monitors USDC price on Base and emits an alert when it drops more than 5%.
|
|
656
|
+
Simple read-only strategy with no trading actions.
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
### What makes this valid
|
|
660
|
+
|
|
661
|
+
- Has `ticker: standard` (1-minute interval)
|
|
662
|
+
- Has `hooks.tick` (required when ticker is set)
|
|
663
|
+
- Source URL starts with `/` (internal endpoint, no SSRF restrictions)
|
|
664
|
+
- Uses `emit` to push events to the app iframe instead of executing actions
|
|
665
|
+
- Minimal permissions (`wallet:list` is read-only)
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
## Example: Message-Mode Chat App
|
|
670
|
+
|
|
671
|
+
A chat assistant that helps users check balances and request swaps.
|
|
672
|
+
|
|
673
|
+
```markdown
|
|
674
|
+
---
|
|
675
|
+
name: Swap Chat
|
|
676
|
+
icon: MessageCircle
|
|
677
|
+
category: tools
|
|
678
|
+
size: 2x2
|
|
679
|
+
permissions:
|
|
680
|
+
- wallet:list
|
|
681
|
+
- action:create
|
|
682
|
+
allowedHosts: []
|
|
683
|
+
|
|
684
|
+
hooks:
|
|
685
|
+
message: |
|
|
686
|
+
You are a token swap assistant for AuraMaxx on Base chain.
|
|
687
|
+
|
|
688
|
+
Use wallet_api to look up wallets and balances. NEVER guess addresses.
|
|
689
|
+
|
|
690
|
+
When the user wants to swap tokens:
|
|
691
|
+
1. Look up their wallets with wallet_api GET /wallets
|
|
692
|
+
2. Try the swap with wallet_api POST /swap
|
|
693
|
+
3. If you get 403, call request_human_action with the swap details
|
|
694
|
+
4. Tell the user approval has been requested
|
|
695
|
+
|
|
696
|
+
NEVER say "I don't have permission." ALWAYS use request_human_action.
|
|
697
|
+
|
|
698
|
+
Keep replies concise (2-3 sentences).
|
|
699
|
+
|
|
700
|
+
config: {}
|
|
701
|
+
---
|
|
702
|
+
|
|
703
|
+
A simple swap assistant. Ask it to swap tokens and it will
|
|
704
|
+
handle wallet lookup and approval requests automatically.
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### What makes this valid
|
|
708
|
+
|
|
709
|
+
- Has `hooks.message` (message-only app, no ticker needed)
|
|
710
|
+
- Uses tool-call flow: `wallet_api` for reads/writes, `request_human_action` for 403s
|
|
711
|
+
- `action:create` permission enables the `request_human_action` tool
|
|
712
|
+
- No `intents` in the response — tool-call mode handles actions directly
|
|
713
|
+
- No response format instructions needed — the engine auto-injects the format spec
|