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.
- package/LICENSE +26 -0
- package/README.md +112 -0
- package/bin/aurawallet.js +121 -0
- package/docs/ADAPTERS.md +467 -0
- package/docs/API.md +2679 -0
- package/docs/APPS.md +198 -0
- package/docs/ARCHITECTURE.md +350 -0
- package/docs/AUTH.md +698 -0
- package/docs/BEST-PRACTICES.md +121 -0
- package/docs/CLI.md +61 -0
- package/docs/DEVELOPING-APPS.md +452 -0
- package/docs/EXTENSION.md +97 -0
- package/docs/JOBS.md +33 -0
- package/docs/MCP.md +76 -0
- package/docs/PROTOCOL.md +142 -0
- package/docs/SETUP.md +219 -0
- package/docs/WORKSPACE.md +672 -0
- package/docs/agent-auth.md +63 -0
- package/docs/aura-file.md +48 -0
- package/docs/credentials.md +53 -0
- package/docs/external/getting-started.md +65 -0
- package/docs/external/overview.md +45 -0
- package/docs/external/use-cases.md +48 -0
- package/docs/external/why-aura.md +35 -0
- package/docs/jobs/connect-agent.md +77 -0
- package/docs/jobs/migrate-from-dotenv.md +79 -0
- package/docs/jobs/recover-from-lockout.md +72 -0
- package/docs/jobs/secure-ci.md +63 -0
- package/docs/oauth2.md +42 -0
- package/docs/passkeys.md +60 -0
- package/docs/security.md +540 -0
- package/docs/specs/aura-open-protocol.md +61 -0
- package/docs/specs/aura-provider-plugin.md +24 -0
- package/docs/specs/aura-registry-model.md +31 -0
- package/docs/specs/fixtures/invalid-bad-key.aura +1 -0
- package/docs/specs/fixtures/invalid-bad-unicode-escape.aura +1 -0
- package/docs/specs/fixtures/invalid-duplicate-key.aura +2 -0
- package/docs/specs/fixtures/valid-basic.aura +4 -0
- package/docs/specs/fixtures/valid-provider-ref.aura +1 -0
- package/docs/specs/fixtures/valid-quoted-escapes.aura +2 -0
- package/docs/templates/RELEASE_NOTES_TEMPLATE.md +22 -0
- package/docs/totp.md +40 -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 +21 -0
- package/package.json +151 -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/migration_lock.toml +3 -0
- package/prisma/schema.prisma +447 -0
- package/public/logo-chevron.svg +31 -0
- package/public/logo-concentric.svg +31 -0
- package/public/logo-crosshatch.svg +39 -0
- package/public/logo-dashed.svg +39 -0
- package/public/logo-horizontal.svg +31 -0
- package/public/logo-m56.svg +64 -0
- package/public/logo.webp +0 -0
- package/scripts/add-app.js +245 -0
- package/scripts/init.sh +57 -0
- package/scripts/migrate-apikeys-to-credentials.ts +35 -0
- package/scripts/sandbox-agent-flow.sh +235 -0
- package/scripts/sandbox.sh +175 -0
- package/scripts/validate-job-docs.mjs +125 -0
- package/server/abi/SwapHelper.json +438 -0
- package/server/cli/approval.ts +447 -0
- package/server/cli/commands/app.ts +204 -0
- package/server/cli/commands/cron.ts +24 -0
- package/server/cli/commands/doctor.ts +1007 -0
- package/server/cli/commands/env.ts +456 -0
- package/server/cli/commands/init.ts +752 -0
- package/server/cli/commands/mcp.ts +125 -0
- package/server/cli/commands/restore.ts +314 -0
- package/server/cli/commands/shell-hook.ts +468 -0
- package/server/cli/commands/start.ts +62 -0
- package/server/cli/commands/status.ts +59 -0
- package/server/cli/commands/stop.ts +14 -0
- package/server/cli/commands/token.ts +180 -0
- package/server/cli/commands/unlock.ts +49 -0
- package/server/cli/commands/vault.ts +417 -0
- package/server/cli/index.ts +328 -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 +254 -0
- package/server/cli/lib/dotenv-migrate.ts +116 -0
- package/server/cli/lib/dotenv-parser.ts +146 -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/process.ts +136 -0
- package/server/cli/lib/prompt.ts +85 -0
- package/server/cli/lib/theme.ts +240 -0
- package/server/cli/socket.ts +570 -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 +406 -0
- package/server/lib/adapters/factory.ts +110 -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 +328 -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 +189 -0
- package/server/lib/app-installer.ts +505 -0
- package/server/lib/app-tokens.ts +247 -0
- package/server/lib/auth.ts +314 -0
- package/server/lib/batch.ts +242 -0
- package/server/lib/cold.ts +874 -0
- package/server/lib/config.ts +381 -0
- package/server/lib/credential-access-audit.ts +85 -0
- package/server/lib/credential-access-policy.ts +110 -0
- package/server/lib/credential-health.ts +343 -0
- package/server/lib/credential-import.ts +487 -0
- package/server/lib/credential-scope.ts +87 -0
- package/server/lib/credential-shares.ts +190 -0
- package/server/lib/credential-transport.ts +342 -0
- package/server/lib/credential-vault.ts +77 -0
- package/server/lib/credentials.ts +333 -0
- package/server/lib/crypto.ts +8 -0
- package/server/lib/db.ts +15 -0
- package/server/lib/defaults.ts +366 -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/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 +128 -0
- package/server/lib/error.ts +20 -0
- package/server/lib/events.ts +205 -0
- package/server/lib/hot.ts +357 -0
- package/server/lib/key-fingerprint.ts +28 -0
- package/server/lib/logger.ts +331 -0
- package/server/lib/network.ts +137 -0
- package/server/lib/notifications.ts +219 -0
- package/server/lib/oauth2-refresh.ts +241 -0
- package/server/lib/oursecret.ts +54 -0
- package/server/lib/passkey-credential.ts +360 -0
- package/server/lib/passkey.ts +68 -0
- package/server/lib/permissions.ts +248 -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 +239 -0
- package/server/lib/resolve-action.ts +427 -0
- package/server/lib/resolve.ts +36 -0
- package/server/lib/sessions.ts +632 -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 +158 -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 +235 -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 +75 -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/verified-summary.ts +421 -0
- package/server/mcp/profile-policy.ts +30 -0
- package/server/mcp/server.ts +619 -0
- package/server/mcp/tools.ts +523 -0
- package/server/middleware/auth.ts +119 -0
- package/server/middleware/requestLogger.ts +84 -0
- package/server/routes/actions.ts +459 -0
- package/server/routes/adapters.ts +703 -0
- package/server/routes/addressbook.ts +113 -0
- package/server/routes/ai.ts +34 -0
- package/server/routes/apikeys.ts +295 -0
- package/server/routes/apps.ts +601 -0
- package/server/routes/auth.ts +457 -0
- package/server/routes/backup.ts +340 -0
- package/server/routes/batch.ts +270 -0
- package/server/routes/bookmarks.ts +162 -0
- package/server/routes/credential-shares.ts +198 -0
- package/server/routes/credential-vaults.ts +154 -0
- package/server/routes/credentials.ts +1290 -0
- package/server/routes/dashboard.ts +71 -0
- package/server/routes/defaults.ts +124 -0
- package/server/routes/fund.ts +229 -0
- package/server/routes/import.ts +352 -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 +346 -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 +353 -0
- package/server/routes/swap-solana.ts +177 -0
- package/server/routes/swap.ts +356 -0
- package/server/routes/token.ts +247 -0
- package/server/routes/unlock.ts +403 -0
- package/server/routes/wallet-assets.ts +361 -0
- package/server/routes/wallet-transactions.ts +515 -0
- package/server/routes/wallet.ts +710 -0
- package/server/types.ts +146 -0
- package/skills/aurawallet/SKILL.md +739 -0
- package/skills/aurawallet-setup/SKILL.md +74 -0
- package/skills/security-review/SKILL.md +148 -0
- package/src/app/api/agent-requests/route.ts +30 -0
- package/src/app/api/apps/install/route.ts +126 -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/events/route.ts +92 -0
- package/src/app/api/page.tsx +212 -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 +34 -0
- package/src/app/api/workspace/config/route.ts +106 -0
- package/src/app/api/workspace/import/route.ts +127 -0
- package/src/app/api/workspace/route.ts +116 -0
- package/src/app/app/page.tsx +2122 -0
- package/src/app/apple-icon.png +0 -0
- package/src/app/docs/page.tsx +178 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +572 -0
- package/src/app/health/page.tsx +5 -0
- package/src/app/hello/page.tsx +15 -0
- package/src/app/icon.png +0 -0
- package/src/app/layout.tsx +34 -0
- package/src/app/page.tsx +986 -0
- package/src/app/providers.tsx +90 -0
- package/src/app/share/[token]/page.tsx +295 -0
- package/src/components/ChainSelector.tsx +144 -0
- package/src/components/HumanActionBar.tsx +695 -0
- package/src/components/NotificationDrawer.tsx +129 -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 +53 -0
- package/src/components/design-system/ChainIndicator.tsx +65 -0
- package/src/components/design-system/ChainSelector.tsx +137 -0
- package/src/components/design-system/ConfirmationModal.tsx +106 -0
- package/src/components/design-system/ConfirmationPopover.tsx +81 -0
- package/src/components/design-system/Drawer.tsx +123 -0
- package/src/components/design-system/FilterDropdown.tsx +72 -0
- package/src/components/design-system/Modal.tsx +206 -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 +58 -0
- package/src/components/design-system/index.ts +11 -0
- package/src/components/docs/DocsThemeToggle.tsx +49 -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/TabBar.tsx +278 -0
- package/src/components/layout/WalletSidebar.tsx +1033 -0
- package/src/components/layout/index.ts +4 -0
- package/src/components/marketing/AuraWalletSpecOverlay.tsx +635 -0
- package/src/components/marketing/DeviceMorphExperience.tsx +216 -0
- package/src/components/vault/ApiKeysConsole.tsx +1080 -0
- package/src/components/vault/AuditConsole.tsx +584 -0
- package/src/components/vault/CredentialDetail.tsx +455 -0
- package/src/components/vault/CredentialEmpty.tsx +55 -0
- package/src/components/vault/CredentialField.tsx +361 -0
- package/src/components/vault/CredentialForm.tsx +1212 -0
- package/src/components/vault/CredentialList.tsx +165 -0
- package/src/components/vault/CredentialRow.tsx +97 -0
- package/src/components/vault/CredentialShareModal.tsx +178 -0
- package/src/components/vault/CredentialVault.tsx +754 -0
- package/src/components/vault/CredentialWalletWidget.tsx +103 -0
- package/src/components/vault/ImportCredentialsModal.tsx +515 -0
- package/src/components/vault/LargeTypeModal.tsx +64 -0
- package/src/components/vault/PasswordGenerator.tsx +224 -0
- package/src/components/vault/TOTPDisplay.tsx +123 -0
- package/src/components/vault/VaultSidebar.tsx +413 -0
- package/src/components/vault/types.ts +54 -0
- package/src/context/AuthContext.tsx +337 -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 +3 -0
- package/src/hooks/useAgentActions.ts +368 -0
- package/src/hooks/useBalance.ts +103 -0
- package/src/hooks/useBalances.ts +129 -0
- package/src/instrumentation.ts +12 -0
- package/src/lib/api.ts +449 -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/crypto.ts +112 -0
- package/src/lib/db.ts +21 -0
- package/src/lib/docs.ts +390 -0
- package/src/lib/events.ts +361 -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/vault-crypto.ts +129 -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 +80 -0
- package/tailwind.config.ts +99 -0
- package/tsconfig.json +42 -0
package/docs/API.md
ADDED
|
@@ -0,0 +1,2679 @@
|
|
|
1
|
+
# Wallet Server API
|
|
2
|
+
|
|
3
|
+
HTTP REST API for wallet operations. Server runs on `http://localhost:4242`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Authentication
|
|
8
|
+
|
|
9
|
+
### Agent Token
|
|
10
|
+
|
|
11
|
+
Most agent endpoints require a Bearer token in the Authorization header:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
Authorization: Bearer <token>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Tokens are obtained by requesting `agent_access` and having a human approve it.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Public Endpoints
|
|
22
|
+
|
|
23
|
+
### Health Check
|
|
24
|
+
|
|
25
|
+
```http
|
|
26
|
+
GET /health
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Returns server status.
|
|
30
|
+
|
|
31
|
+
### Server Public Key
|
|
32
|
+
|
|
33
|
+
```http
|
|
34
|
+
GET /auth/connect
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Returns the server's ephemeral RSA public key for encrypting passwords (used by `/unlock` and `/setup`).
|
|
38
|
+
|
|
39
|
+
**Response:**
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBI..."
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Event Logs
|
|
47
|
+
|
|
48
|
+
```http
|
|
49
|
+
GET /logs
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Returns historical event logs from the database. Supports filtering and pagination.
|
|
53
|
+
|
|
54
|
+
**Query params:**
|
|
55
|
+
- `type`: Filter by exact event type (e.g., `token:created`)
|
|
56
|
+
- `category`: Filter by category prefix (e.g., `auth` matches `auth:unlocked`, `auth:auth_failed`, etc.)
|
|
57
|
+
- `agentId`: Filter events by agent ID (searches JSON data field)
|
|
58
|
+
- `since`: Start timestamp (ms epoch or ISO string)
|
|
59
|
+
- `until`: End timestamp (ms epoch or ISO string)
|
|
60
|
+
- `limit`: Max results (default 50, max 250)
|
|
61
|
+
- `offset`: Pagination offset
|
|
62
|
+
|
|
63
|
+
**Response:**
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"success": true,
|
|
67
|
+
"logs": [
|
|
68
|
+
{
|
|
69
|
+
"id": "cuid123",
|
|
70
|
+
"type": "auth:unlocked",
|
|
71
|
+
"source": "express",
|
|
72
|
+
"data": "{\"description\":\"Wallet unlocked\"}",
|
|
73
|
+
"timestamp": "2026-02-01T12:00:00.000Z"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"count": 50,
|
|
77
|
+
"total": 120,
|
|
78
|
+
"pagination": { "limit": 50, "offset": 0, "hasMore": true }
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### ENS Name Resolution
|
|
83
|
+
|
|
84
|
+
```http
|
|
85
|
+
GET /resolve/:name
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Resolves an ENS name (`.eth`) to an Ethereum address. Public endpoint — no authentication required. Uses Ethereum mainnet RPC for ENS resolution.
|
|
89
|
+
|
|
90
|
+
**Example:**
|
|
91
|
+
```bash
|
|
92
|
+
GET /resolve/vitalik.eth
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Response:**
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"success": true,
|
|
99
|
+
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
|
|
100
|
+
"name": "vitalik.eth"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Error:**
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"error": "Could not resolve: nonexistent.eth"
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Only `.eth` names are supported. Solana `.sol` names are out of scope.
|
|
112
|
+
|
|
113
|
+
### Token Price Lookup
|
|
114
|
+
|
|
115
|
+
```http
|
|
116
|
+
GET /price/:address?chain=base
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Returns USD price for any ERC-20 or SPL token. Public endpoint — no authentication required. Uses a cascading fallback of free APIs: DexScreener → CoinGecko → Alchemy (if configured). Results are cached in memory for 60 seconds.
|
|
120
|
+
|
|
121
|
+
Use `native` as the address to get the native currency price (ETH or SOL).
|
|
122
|
+
|
|
123
|
+
**Query params:**
|
|
124
|
+
- `chain` (optional): Chain to look up price on (default: server default chain). Supported: `base`, `ethereum`, `solana`, `polygon`, `arbitrum`, `optimism`
|
|
125
|
+
|
|
126
|
+
**Example — ERC-20 token:**
|
|
127
|
+
```bash
|
|
128
|
+
GET /price/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913?chain=base
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Response:**
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"success": true,
|
|
135
|
+
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
136
|
+
"chain": "base",
|
|
137
|
+
"priceUsd": "0.9998",
|
|
138
|
+
"source": "dexscreener",
|
|
139
|
+
"cached": false
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Example — Native currency:**
|
|
144
|
+
```bash
|
|
145
|
+
GET /price/native?chain=base
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Response:**
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"success": true,
|
|
152
|
+
"token": "native",
|
|
153
|
+
"chain": "base",
|
|
154
|
+
"priceUsd": "3200",
|
|
155
|
+
"source": "cache",
|
|
156
|
+
"cached": true
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Error (no price found):**
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"success": false,
|
|
164
|
+
"error": "No price found for 0x... on base"
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Error (invalid address):**
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"success": false,
|
|
172
|
+
"error": "Invalid EVM address format"
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Token Search
|
|
177
|
+
|
|
178
|
+
```http
|
|
179
|
+
GET /token/search?q=PEPE&chain=base&limit=10
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Search for tokens by ticker symbol or name. Returns deduplicated results sorted by liquidity. Uses DexScreener search API with CoinGecko fallback. Results cached for 5 minutes.
|
|
183
|
+
|
|
184
|
+
**Query parameters:**
|
|
185
|
+
| Param | Required | Default | Description |
|
|
186
|
+
|---------|----------|---------|-------------|
|
|
187
|
+
| `q` | Yes | — | Search query (ticker, name, or address) |
|
|
188
|
+
| `chain` | No | — | Filter to specific chain (`base`, `ethereum`, `solana`, etc.) |
|
|
189
|
+
| `limit` | No | 10 | Max results (1–50) |
|
|
190
|
+
|
|
191
|
+
**Response:**
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"success": true,
|
|
195
|
+
"query": "PEPE",
|
|
196
|
+
"results": [
|
|
197
|
+
{
|
|
198
|
+
"address": "0x6982508145454Ce325dDbE47a25d4ec3d2311933",
|
|
199
|
+
"chain": "ethereum",
|
|
200
|
+
"symbol": "PEPE",
|
|
201
|
+
"name": "Pepe",
|
|
202
|
+
"priceUsd": "0.00001234",
|
|
203
|
+
"liquidity": 5000000,
|
|
204
|
+
"volume24h": 12000000,
|
|
205
|
+
"marketCap": 5200000000,
|
|
206
|
+
"fdv": 5200000000,
|
|
207
|
+
"imageUrl": "https://dd.dexscreener.com/ds-data/tokens/ethereum/0x698.png",
|
|
208
|
+
"websites": ["https://pepe.vip"],
|
|
209
|
+
"socials": [{ "type": "twitter", "url": "https://twitter.com/pepecoineth" }],
|
|
210
|
+
"dexId": "uniswap",
|
|
211
|
+
"pairAddress": "0xA43fe16908251ee70EF74718545e4FE6C5cCEc9f"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Error (missing query):**
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"success": false,
|
|
221
|
+
"error": "Missing required query parameter: q"
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Token Balance Lookup
|
|
226
|
+
|
|
227
|
+
```http
|
|
228
|
+
GET /token/:tokenAddress/balance/:walletAddress?chain=base
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Returns the on-chain token balance for any wallet address. Works for both registered AuraWallet wallets and arbitrary external addresses. Performs a direct RPC call — no database lookup required.
|
|
232
|
+
|
|
233
|
+
**Path params:**
|
|
234
|
+
- `tokenAddress` — ERC-20 contract address (EVM) or SPL mint address (Solana)
|
|
235
|
+
- `walletAddress` — Wallet address to check balance for
|
|
236
|
+
|
|
237
|
+
**Query params:**
|
|
238
|
+
- `chain` (optional): Chain to query (default: server default chain). Supported: `base`, `ethereum`, `solana`, `solana-devnet`
|
|
239
|
+
|
|
240
|
+
**Example — EVM (ERC-20):**
|
|
241
|
+
```bash
|
|
242
|
+
GET /token/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913/balance/0x498581ff718922c3f8e6a244956af099b2652b2b?chain=base
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Response:**
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"success": true,
|
|
249
|
+
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
250
|
+
"walletAddress": "0x498581ff718922c3f8e6a244956af099b2652b2b",
|
|
251
|
+
"chain": "base",
|
|
252
|
+
"balance": "1000000",
|
|
253
|
+
"formatted": "1.0",
|
|
254
|
+
"decimals": 6,
|
|
255
|
+
"symbol": "USDC",
|
|
256
|
+
"name": "USD Coin",
|
|
257
|
+
"priceUsd": "0.9998",
|
|
258
|
+
"valueUsd": "1.00"
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Example — Solana (SPL):**
|
|
263
|
+
```bash
|
|
264
|
+
GET /token/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/balance/5Gh7s2...?chain=solana
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Response:**
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"success": true,
|
|
271
|
+
"tokenAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
272
|
+
"walletAddress": "5Gh7s2...",
|
|
273
|
+
"chain": "solana",
|
|
274
|
+
"balance": "1000000",
|
|
275
|
+
"formatted": "1.0",
|
|
276
|
+
"decimals": 6,
|
|
277
|
+
"priceUsd": "0.9998",
|
|
278
|
+
"valueUsd": "1.00"
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Error (invalid address):**
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"success": false,
|
|
286
|
+
"error": "Invalid EVM token address format"
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Error (RPC failure):**
|
|
291
|
+
```json
|
|
292
|
+
{
|
|
293
|
+
"success": false,
|
|
294
|
+
"error": "Failed to query token balance from RPC"
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Token Safety Check
|
|
299
|
+
|
|
300
|
+
```http
|
|
301
|
+
GET /token/safety/:address?chain=ethereum
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Returns a safety report for a token contract via GoPlusLabs. Includes honeypot detection, tax analysis, holder data, LP info, and contract red flags. 10-minute cache.
|
|
305
|
+
|
|
306
|
+
**Query parameters:**
|
|
307
|
+
| Param | Required | Default | Description |
|
|
308
|
+
|---------|----------|------------|-------------|
|
|
309
|
+
| `chain` | No | `ethereum` | Chain name (`ethereum`, `base`, `solana`, `polygon`, `arbitrum`, `optimism`) |
|
|
310
|
+
|
|
311
|
+
**Response:**
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"success": true,
|
|
315
|
+
"address": "0x6982...",
|
|
316
|
+
"chain": "ethereum",
|
|
317
|
+
"safety": {
|
|
318
|
+
"tokenName": "Pepe",
|
|
319
|
+
"tokenSymbol": "PEPE",
|
|
320
|
+
"totalSupply": "420689899653542",
|
|
321
|
+
"isHoneypot": false,
|
|
322
|
+
"isMintable": false,
|
|
323
|
+
"isOpenSource": true,
|
|
324
|
+
"isProxy": false,
|
|
325
|
+
"isBlacklisted": false,
|
|
326
|
+
"buyTax": "0",
|
|
327
|
+
"sellTax": "0",
|
|
328
|
+
"holderCount": 513429,
|
|
329
|
+
"holders": [
|
|
330
|
+
{ "address": "0x...", "balance": "100000000", "percent": "0.05", "isLocked": false, "isContract": true, "tag": "Uniswap V2" }
|
|
331
|
+
],
|
|
332
|
+
"lpHolderCount": 67,
|
|
333
|
+
"lpHolders": [
|
|
334
|
+
{ "address": "0x...", "balance": "500000", "percent": "0.5", "isLocked": true, "isContract": true }
|
|
335
|
+
],
|
|
336
|
+
"dexInfo": [
|
|
337
|
+
{ "name": "Uniswap V2", "liquidity": "5000000", "pair": "0x..." }
|
|
338
|
+
]
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Token Holders
|
|
344
|
+
|
|
345
|
+
```http
|
|
346
|
+
GET /token/holders/:address?chain=ethereum
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Returns top holders for a token (convenience endpoint — subset of safety data from GoPlusLabs).
|
|
350
|
+
|
|
351
|
+
**Response:**
|
|
352
|
+
```json
|
|
353
|
+
{
|
|
354
|
+
"success": true,
|
|
355
|
+
"address": "0x6982...",
|
|
356
|
+
"chain": "ethereum",
|
|
357
|
+
"tokenName": "Pepe",
|
|
358
|
+
"tokenSymbol": "PEPE",
|
|
359
|
+
"holderCount": 513429,
|
|
360
|
+
"holders": [
|
|
361
|
+
{ "address": "0x...", "balance": "100000000", "percent": "0.05", "isLocked": false, "isContract": true, "tag": "Uniswap V2" }
|
|
362
|
+
]
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Batch Requests
|
|
367
|
+
|
|
368
|
+
```http
|
|
369
|
+
POST /batch
|
|
370
|
+
Content-Type: application/json
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Executes multiple API calls in a single HTTP request with dependency chaining. Sub-requests within the same wave execute in parallel; waves execute sequentially. Template references (`${id.json.path}`) resolve data from prior responses.
|
|
374
|
+
|
|
375
|
+
**No auth on the batch endpoint itself** — authentication is enforced per-sub-request via inherited headers from the parent request.
|
|
376
|
+
|
|
377
|
+
**Request body:**
|
|
378
|
+
|
|
379
|
+
```json
|
|
380
|
+
{
|
|
381
|
+
"requests": [
|
|
382
|
+
{
|
|
383
|
+
"id": "search",
|
|
384
|
+
"method": "GET",
|
|
385
|
+
"path": "/token/search?q=PEPE&limit=1"
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"id": "safety",
|
|
389
|
+
"method": "GET",
|
|
390
|
+
"path": "/token/safety/${search.results.0.address}?chain=${search.results.0.chain}",
|
|
391
|
+
"dependsOn": "search"
|
|
392
|
+
}
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Field reference:**
|
|
398
|
+
|
|
399
|
+
| Field | Type | Required | Description |
|
|
400
|
+
|-------|------|----------|-------------|
|
|
401
|
+
| `requests` | array | yes | Array of sub-requests (1–20) |
|
|
402
|
+
| `requests[].id` | string | yes | Unique identifier for this request |
|
|
403
|
+
| `requests[].method` | string | yes | HTTP method: `GET`, `POST`, `PUT`, `DELETE` |
|
|
404
|
+
| `requests[].path` | string | yes | API path including query params. May contain `${id.json.path}` template references |
|
|
405
|
+
| `requests[].body` | object | no | Request body for POST/PUT. String values may contain template references |
|
|
406
|
+
| `requests[].dependsOn` | string | no | ID of a request that must complete before this one executes |
|
|
407
|
+
|
|
408
|
+
**Template syntax:**
|
|
409
|
+
|
|
410
|
+
Templates use `${requestId.json.path}` where `json.path` is a dot-separated path into the response body:
|
|
411
|
+
|
|
412
|
+
| Template | Resolves to |
|
|
413
|
+
|----------|-------------|
|
|
414
|
+
| `${search.results.0.address}` | First search result's address |
|
|
415
|
+
| `${search.results.0.chain}` | First search result's chain |
|
|
416
|
+
| `${wallets.wallets.0.address}` | First wallet's address |
|
|
417
|
+
|
|
418
|
+
Array elements are accessed by numeric index: `results.0.address`, `results.1.chain`.
|
|
419
|
+
|
|
420
|
+
**Response (always 200):**
|
|
421
|
+
|
|
422
|
+
```json
|
|
423
|
+
{
|
|
424
|
+
"responses": {
|
|
425
|
+
"search": {
|
|
426
|
+
"status": 200,
|
|
427
|
+
"body": { "success": true, "query": "PEPE", "results": [...] }
|
|
428
|
+
},
|
|
429
|
+
"safety": {
|
|
430
|
+
"status": 200,
|
|
431
|
+
"body": { "success": true, "address": "0x6982...", "safety": { ... } }
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
"meta": {
|
|
435
|
+
"total": 2,
|
|
436
|
+
"succeeded": 2,
|
|
437
|
+
"failed": 0,
|
|
438
|
+
"timings": { "search": 245, "safety": 312 }
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Error handling:**
|
|
444
|
+
|
|
445
|
+
| Scenario | Behavior |
|
|
446
|
+
|----------|----------|
|
|
447
|
+
| Invalid request format | `400` on the batch endpoint |
|
|
448
|
+
| Circular dependency | `400` with descriptive error |
|
|
449
|
+
| Unknown `dependsOn` target | `400` with descriptive error |
|
|
450
|
+
| Too many requests (>20) | `400` |
|
|
451
|
+
| Sub-request fails (4xx/5xx) | Other independent sub-requests still execute; dependent ones get `424` |
|
|
452
|
+
| Template reference not found | Sub-request gets `422` |
|
|
453
|
+
| Sub-request timeout (>30s) | Sub-request gets `504`; dependents get `424` |
|
|
454
|
+
|
|
455
|
+
**Example — search + safety in one call:**
|
|
456
|
+
|
|
457
|
+
```bash
|
|
458
|
+
curl -X POST http://localhost:4242/batch \
|
|
459
|
+
-H 'Content-Type: application/json' \
|
|
460
|
+
-d '{
|
|
461
|
+
"requests": [
|
|
462
|
+
{ "id": "s", "method": "GET", "path": "/token/search?q=PEPE&limit=1" },
|
|
463
|
+
{ "id": "safety", "method": "GET", "path": "/token/safety/${s.results.0.address}?chain=${s.results.0.chain}", "dependsOn": "s" }
|
|
464
|
+
]
|
|
465
|
+
}'
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
**Rate limiting:** The batch request counts as 1 request against the general rate limiter. Individual sub-requests do not count against rate limits.
|
|
469
|
+
|
|
470
|
+
### Setup Status
|
|
471
|
+
|
|
472
|
+
```http
|
|
473
|
+
GET /setup
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
Returns setup status including vault state, adapter configuration, and API key availability.
|
|
477
|
+
|
|
478
|
+
**Response:**
|
|
479
|
+
```json
|
|
480
|
+
{
|
|
481
|
+
"hasWallet": true,
|
|
482
|
+
"unlocked": true,
|
|
483
|
+
"address": "0x...",
|
|
484
|
+
"adapters": { "telegram": false, "webhook": false },
|
|
485
|
+
"apiKeys": { "alchemy": true, "anthropic": false },
|
|
486
|
+
"defaultChain": "base"
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Dashboard Data
|
|
491
|
+
|
|
492
|
+
```http
|
|
493
|
+
GET /dashboard
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Returns pending actions, active tokens, and counts for the UI.
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Human Endpoints (Require Unlock)
|
|
501
|
+
|
|
502
|
+
### Setup Cold Wallet
|
|
503
|
+
|
|
504
|
+
```http
|
|
505
|
+
POST /setup
|
|
506
|
+
Content-Type: application/json
|
|
507
|
+
|
|
508
|
+
{
|
|
509
|
+
"encrypted": "base64...",
|
|
510
|
+
"pubkey": "<RSA public key PEM or base64>"
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Creates the cold wallet with encrypted password. Only works once. Returns an admin token (vault is auto-unlocked after creation).
|
|
515
|
+
|
|
516
|
+
**Response:**
|
|
517
|
+
```json
|
|
518
|
+
{
|
|
519
|
+
"success": true,
|
|
520
|
+
"address": "0x...",
|
|
521
|
+
"mnemonic": "word1 word2 ... word12",
|
|
522
|
+
"token": "eyJ...",
|
|
523
|
+
"message": "Cold wallet created. SAVE YOUR MNEMONIC SECURELY."
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### Change Primary Vault Password
|
|
528
|
+
|
|
529
|
+
```http
|
|
530
|
+
POST /setup/password
|
|
531
|
+
Authorization: Bearer <admin-token>
|
|
532
|
+
Content-Type: application/json
|
|
533
|
+
|
|
534
|
+
{
|
|
535
|
+
"currentEncrypted": "base64...",
|
|
536
|
+
"newEncrypted": "base64..."
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
Rotates the primary vault password by decrypting with the current password and re-encrypting with the new password.
|
|
541
|
+
|
|
542
|
+
**Response:**
|
|
543
|
+
```json
|
|
544
|
+
{
|
|
545
|
+
"success": true,
|
|
546
|
+
"message": "Primary vault password updated"
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Errors:**
|
|
551
|
+
- `400` if new password is shorter than 8 characters
|
|
552
|
+
- `401` if current password is invalid
|
|
553
|
+
|
|
554
|
+
### Unlock Page
|
|
555
|
+
|
|
556
|
+
```http
|
|
557
|
+
GET /unlock
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Returns a self-contained HTML page for unlocking the vault in a browser. The page handles RSA-OAEP password encryption client-side and submits to `POST /unlock`. **This is a fallback for headless environments** where the dashboard (`:4747/app`) isn't running. When the dashboard is available, always direct users to `http://localhost:4747/app` instead — it provides the full UI experience including setup wizard, wallet management, and approval flows.
|
|
561
|
+
|
|
562
|
+
### Unlock Vault
|
|
563
|
+
|
|
564
|
+
```http
|
|
565
|
+
POST /unlock
|
|
566
|
+
Content-Type: application/json
|
|
567
|
+
|
|
568
|
+
{
|
|
569
|
+
"encrypted": "base64...",
|
|
570
|
+
"pubkey": "<RSA public key PEM or base64>"
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
Unlocks the primary vault for wallet operations.
|
|
575
|
+
|
|
576
|
+
### Unlock Specific Vault
|
|
577
|
+
|
|
578
|
+
```http
|
|
579
|
+
POST /unlock/:vaultId
|
|
580
|
+
Content-Type: application/json
|
|
581
|
+
|
|
582
|
+
{
|
|
583
|
+
"encrypted": "base64...",
|
|
584
|
+
"pubkey": "<RSA public key PEM or base64>"
|
|
585
|
+
}
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Unlocks a specific vault by ID. Each vault has its own independent password. Returns:
|
|
589
|
+
|
|
590
|
+
```json
|
|
591
|
+
{
|
|
592
|
+
"success": true,
|
|
593
|
+
"vaultId": "vault-abc123",
|
|
594
|
+
"address": "0x...",
|
|
595
|
+
"token": "eyJhZ2VudElkIjoiYWRtaW4i..."
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Lock Vault
|
|
600
|
+
|
|
601
|
+
```http
|
|
602
|
+
POST /lock
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
Locks ALL vaults, preventing further operations until unlock.
|
|
606
|
+
|
|
607
|
+
### Lock Specific Vault
|
|
608
|
+
|
|
609
|
+
```http
|
|
610
|
+
POST /lock/:vaultId
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
Locks a specific vault by ID. Requires admin auth.
|
|
614
|
+
|
|
615
|
+
### Create Additional Vault
|
|
616
|
+
|
|
617
|
+
```http
|
|
618
|
+
POST /setup/vault
|
|
619
|
+
Authorization: Bearer <admin-token>
|
|
620
|
+
Content-Type: application/json
|
|
621
|
+
|
|
622
|
+
{
|
|
623
|
+
"encrypted": "base64...",
|
|
624
|
+
"name": "Trading Vault"
|
|
625
|
+
}
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Creates an additional vault with its own encrypted seed. Requires admin auth and an unlocked primary vault.
|
|
629
|
+
|
|
630
|
+
**Request body:**
|
|
631
|
+
- `encrypted` (required) - RSA-OAEP encrypted password for the new vault
|
|
632
|
+
- `name` (optional) - Human-readable name for the vault
|
|
633
|
+
|
|
634
|
+
**Response:**
|
|
635
|
+
```json
|
|
636
|
+
{
|
|
637
|
+
"id": "vault-abc123",
|
|
638
|
+
"address": "0x...",
|
|
639
|
+
"solanaAddress": "5Gh7...",
|
|
640
|
+
"mnemonic": "word1 word2 ... word12",
|
|
641
|
+
"name": "Trading Vault"
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### Import Vault from Seed
|
|
646
|
+
|
|
647
|
+
```http
|
|
648
|
+
POST /setup/vault/import
|
|
649
|
+
Authorization: Bearer <admin-token>
|
|
650
|
+
Content-Type: application/json
|
|
651
|
+
|
|
652
|
+
{
|
|
653
|
+
"mnemonic": "word1 word2 ... word12",
|
|
654
|
+
"encrypted": "base64...",
|
|
655
|
+
"name": "Imported Vault"
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
Imports a vault from an existing mnemonic seed phrase. Requires admin auth and an unlocked primary vault.
|
|
660
|
+
|
|
661
|
+
**Request body:**
|
|
662
|
+
- `mnemonic` (required) - BIP-39 mnemonic seed phrase to import
|
|
663
|
+
- `encrypted` (required) - RSA-OAEP encrypted password for the vault
|
|
664
|
+
- `name` (optional) - Human-readable name for the vault
|
|
665
|
+
|
|
666
|
+
**Response:**
|
|
667
|
+
```json
|
|
668
|
+
{
|
|
669
|
+
"id": "vault-def456",
|
|
670
|
+
"address": "0x...",
|
|
671
|
+
"solanaAddress": "7Kx9...",
|
|
672
|
+
"name": "Imported Vault"
|
|
673
|
+
}
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### List Vaults
|
|
677
|
+
|
|
678
|
+
```http
|
|
679
|
+
GET /setup/vaults
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
Lists all vaults and their status.
|
|
683
|
+
|
|
684
|
+
**Response:**
|
|
685
|
+
```json
|
|
686
|
+
{
|
|
687
|
+
"vaults": [
|
|
688
|
+
{
|
|
689
|
+
"id": "vault-primary",
|
|
690
|
+
"name": "Primary",
|
|
691
|
+
"address": "0x...",
|
|
692
|
+
"solanaAddress": "5Gh7...",
|
|
693
|
+
"isUnlocked": true,
|
|
694
|
+
"isPrimary": true,
|
|
695
|
+
"createdAt": "2026-01-15T10:00:00.000Z"
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
"id": "vault-abc123",
|
|
699
|
+
"name": "Trading Vault",
|
|
700
|
+
"address": "0x...",
|
|
701
|
+
"solanaAddress": "7Kx9...",
|
|
702
|
+
"isUnlocked": false,
|
|
703
|
+
"isPrimary": false,
|
|
704
|
+
"createdAt": "2026-02-01T12:00:00.000Z"
|
|
705
|
+
}
|
|
706
|
+
]
|
|
707
|
+
}
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### Export Seed Phrase
|
|
711
|
+
|
|
712
|
+
```http
|
|
713
|
+
GET /export-seed?vaultId=vault-abc123
|
|
714
|
+
POST /export-seed
|
|
715
|
+
Content-Type: application/json
|
|
716
|
+
|
|
717
|
+
{
|
|
718
|
+
"vaultId": "vault-abc123"
|
|
719
|
+
}
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
Exports the seed phrase for a vault. The `vaultId` parameter is optional; if omitted, exports the primary vault's seed. Requires the targeted vault to be unlocked.
|
|
723
|
+
|
|
724
|
+
### Create Human Action Request
|
|
725
|
+
|
|
726
|
+
```http
|
|
727
|
+
POST /actions
|
|
728
|
+
Authorization: Bearer <token-with-action:create>
|
|
729
|
+
Content-Type: application/json
|
|
730
|
+
|
|
731
|
+
{
|
|
732
|
+
"summary": "Buy $DOGE2 for 0.005 ETH",
|
|
733
|
+
"pubkey": "<RSA public key PEM or base64>",
|
|
734
|
+
"permissions": ["swap"],
|
|
735
|
+
"limits": { "swap": 0.005 },
|
|
736
|
+
"walletAccess": ["0x..."],
|
|
737
|
+
"ttl": 60
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
Creates a pending action request that requires human approval. On approval, a temporary scoped token is generated with the requested permissions and limits. The caller polls `GET /auth/:requestId?secret=...` to retrieve the token (same as the agent auth flow).
|
|
742
|
+
|
|
743
|
+
Requires `action:create` permission. Cannot request `admin:*` or `action:create` in the `permissions` array.
|
|
744
|
+
|
|
745
|
+
**Request body:**
|
|
746
|
+
- `type` (optional) - Request type: `'action'` (default, requires approval) or `'notify'` (notification-only, no approval needed)
|
|
747
|
+
- `summary` (required) - Human-readable description of the action
|
|
748
|
+
- `pubkey` (required for `action` type) - RSA public key used for temp token issuance
|
|
749
|
+
- `permissions` (required for `action` type) - Array of permissions for the temp token
|
|
750
|
+
- `limits` (optional) - Spending limits for the temp token
|
|
751
|
+
- `walletAccess` (optional) - Wallet addresses the temp token can access
|
|
752
|
+
- `ttl` (optional) - Token lifetime in seconds (default: 60)
|
|
753
|
+
- `metadata` (optional) - Arbitrary metadata. Known fields:
|
|
754
|
+
- `action` (object) - Pre-computed API call `{ endpoint, method, body }`. On approval, this action auto-executes with the scoped temp token and the result is emitted to the app via `action:executed` and `agent:message` channels
|
|
755
|
+
|
|
756
|
+
**Response:**
|
|
757
|
+
```json
|
|
758
|
+
{
|
|
759
|
+
"success": true,
|
|
760
|
+
"requestId": "clx...",
|
|
761
|
+
"secret": "hex...",
|
|
762
|
+
"message": "Waiting for human approval"
|
|
763
|
+
}
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
**Token retrieval:** Poll `GET /auth/:requestId?secret=...` — returns `{ status: "pending" }`, `{ status: "approved", token: "..." }`, or `{ status: "rejected" }`.
|
|
767
|
+
|
|
768
|
+
#### Notification-Only Mode (`type: 'notify'`)
|
|
769
|
+
|
|
770
|
+
When `type` is set to `'notify'`, the endpoint creates a dashboard notification without requiring human approval. No permissions, limits, or token are involved. Adapter fan-out (Telegram, webhook) is **opt-in** via the `notify` flag.
|
|
771
|
+
|
|
772
|
+
```http
|
|
773
|
+
POST /actions
|
|
774
|
+
Authorization: Bearer <token-with-action:create>
|
|
775
|
+
Content-Type: application/json
|
|
776
|
+
|
|
777
|
+
{
|
|
778
|
+
"type": "notify",
|
|
779
|
+
"notify": true,
|
|
780
|
+
"summary": "$TOKEN — Risk 3/10 — MC $25K",
|
|
781
|
+
"metadata": {
|
|
782
|
+
"evaluation": "AI analysis text...",
|
|
783
|
+
"contractAddress": "0x...",
|
|
784
|
+
"symbol": "TOKEN",
|
|
785
|
+
"risk": 3
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
**Request body (notify):**
|
|
791
|
+
- `type` (required) - Must be `'notify'`
|
|
792
|
+
- `summary` (required) - Notification text
|
|
793
|
+
- `notify` (optional, default `true`) - When `true`, emits `action:created` to adapters (Telegram, webhook). Set to `false` to create a dashboard-only notification without triggering external adapters.
|
|
794
|
+
- `metadata` (optional) - Arbitrary metadata passed to adapters. Known fields: `evaluation`, `contractAddress`, `symbol`, `name`, `marketCap`, `socialLinks`, `risk`
|
|
795
|
+
|
|
796
|
+
**Response:**
|
|
797
|
+
```json
|
|
798
|
+
{
|
|
799
|
+
"success": true,
|
|
800
|
+
"id": "clx..."
|
|
801
|
+
}
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
The request is created with `status: 'acknowledged'` (not `'pending'`), so it does not appear in `GET /actions/pending` and cannot be resolved.
|
|
805
|
+
|
|
806
|
+
### Resolve Action (Primary)
|
|
807
|
+
|
|
808
|
+
```http
|
|
809
|
+
POST /actions/:id/resolve
|
|
810
|
+
Content-Type: application/json
|
|
811
|
+
|
|
812
|
+
{
|
|
813
|
+
"approved": true
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
Approves or rejects a pending action. For `agent_access` and `permission_update` types, generates a token on approval. Set `approved` to `false` to reject. Supports optional `walletAccess` and `limits` overrides.
|
|
818
|
+
|
|
819
|
+
### List Pending Actions
|
|
820
|
+
|
|
821
|
+
```http
|
|
822
|
+
GET /actions/pending
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
Returns all pending human actions.
|
|
826
|
+
|
|
827
|
+
### Create Token (Direct)
|
|
828
|
+
|
|
829
|
+
```http
|
|
830
|
+
POST /actions/token
|
|
831
|
+
Content-Type: application/json
|
|
832
|
+
|
|
833
|
+
{
|
|
834
|
+
"agentId": "my-agent",
|
|
835
|
+
"limit": 0.5,
|
|
836
|
+
"permissions": ["wallet:create:hot", "send:hot"],
|
|
837
|
+
"ttl": 3600,
|
|
838
|
+
"credentialAccess": {
|
|
839
|
+
"read": ["vault:primary"],
|
|
840
|
+
"excludeFields": ["password"]
|
|
841
|
+
},
|
|
842
|
+
"pubkey": "<RSA public key PEM or base64>"
|
|
843
|
+
}
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
Creates a signed agent token directly (admin only).
|
|
847
|
+
|
|
848
|
+
`pubkey` is required for all token mints.
|
|
849
|
+
|
|
850
|
+
Profile policy-pack mode is also supported:
|
|
851
|
+
|
|
852
|
+
```json
|
|
853
|
+
{
|
|
854
|
+
"agentId": "observer-agent",
|
|
855
|
+
"profile": "observer",
|
|
856
|
+
"profileVersion": "v1",
|
|
857
|
+
"profileOverrides": {
|
|
858
|
+
"ttlSeconds": 900,
|
|
859
|
+
"maxReads": 50
|
|
860
|
+
},
|
|
861
|
+
"pubkey": "<RSA public key PEM or base64>"
|
|
862
|
+
}
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
In profile mode, `permissions` / `credentialAccess` / `ttl` are resolved from the shared profile resolver, and the response includes `profile`, `effectivePolicyHash`, `overrideDelta`, and `warnings`.
|
|
866
|
+
|
|
867
|
+
### Request Agent Token (Public Bootstrap)
|
|
868
|
+
|
|
869
|
+
```http
|
|
870
|
+
POST /auth
|
|
871
|
+
Content-Type: application/json
|
|
872
|
+
|
|
873
|
+
{
|
|
874
|
+
"agentId": "my-agent",
|
|
875
|
+
"permissions": ["wallet:list", "swap", "action:create"],
|
|
876
|
+
"limits": { "fund": 0.5, "send": 1.0, "swap": 0.5 },
|
|
877
|
+
"ttl": 3600,
|
|
878
|
+
"pubkey": "<RSA public key PEM or base64>"
|
|
879
|
+
}
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
Creates a pending auth request for human approval. Returns `requestId` and `secret` for polling `GET /auth/:requestId?secret=...`.
|
|
883
|
+
|
|
884
|
+
### List Tokens
|
|
885
|
+
|
|
886
|
+
```http
|
|
887
|
+
GET /actions/tokens
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
Lists all agent tokens grouped by status (active, inactive, expired, revoked, depleted).
|
|
891
|
+
|
|
892
|
+
### Request Permission Upgrade
|
|
893
|
+
|
|
894
|
+
```http
|
|
895
|
+
POST /auth/request-permissions
|
|
896
|
+
Authorization: Bearer <token>
|
|
897
|
+
Content-Type: application/json
|
|
898
|
+
|
|
899
|
+
{
|
|
900
|
+
"requestedPermissions": ["swap", "launch"],
|
|
901
|
+
"requestedWalletAccess": ["0x..."],
|
|
902
|
+
"requestedLimits": { "swap": 1.0 },
|
|
903
|
+
"requestedPubkey": "<RSA public key PEM or base64>"
|
|
904
|
+
}
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
Requests additional permissions, wallet access, or higher spending limits for an existing token. Creates a `permission_update` pending request that requires human approval. On approval, the agent polls `GET /auth/:requestId?secret=...` to retrieve a new token with the upgraded permissions (same flow as initial token request).
|
|
908
|
+
|
|
909
|
+
Requires a valid agent token. Admin tokens are rejected (already have all permissions).
|
|
910
|
+
|
|
911
|
+
**Request body** (at least one required):
|
|
912
|
+
- `requestedPermissions` (optional) - Additional permission strings to add
|
|
913
|
+
- `requestedWalletAccess` (optional) - Additional wallet addresses to grant access to
|
|
914
|
+
- `requestedLimits` (optional) - New spending limits (replaces existing limits for specified types)
|
|
915
|
+
- `requestedPubkey` (required) - RSA public key for replacement token issuance
|
|
916
|
+
|
|
917
|
+
**Response:**
|
|
918
|
+
```json
|
|
919
|
+
{
|
|
920
|
+
"success": true,
|
|
921
|
+
"requestId": "clx...",
|
|
922
|
+
"secret": "hex...",
|
|
923
|
+
"message": "Permission update request created, waiting for human approval",
|
|
924
|
+
"currentPermissions": ["trade:all"],
|
|
925
|
+
"requestedPermissions": ["swap", "launch"],
|
|
926
|
+
"requestedWalletAccess": ["0x..."],
|
|
927
|
+
"requestedLimits": { "swap": 1.0 }
|
|
928
|
+
}
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
**Token retrieval:** Poll `GET /auth/:requestId?secret=...` — same as the initial auth flow.
|
|
932
|
+
|
|
933
|
+
### Revoke Token
|
|
934
|
+
|
|
935
|
+
```http
|
|
936
|
+
POST /actions/tokens/revoke
|
|
937
|
+
Content-Type: application/json
|
|
938
|
+
|
|
939
|
+
{
|
|
940
|
+
"tokenHash": "abc123..."
|
|
941
|
+
}
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
Revokes an active agent token. Admins can revoke any token; agents can only revoke their own.
|
|
945
|
+
|
|
946
|
+
### List Backups
|
|
947
|
+
|
|
948
|
+
```http
|
|
949
|
+
GET /backup
|
|
950
|
+
Authorization: Bearer <admin-token>
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
Lists all database backups. Requires admin permission.
|
|
954
|
+
|
|
955
|
+
### Create Backup
|
|
956
|
+
|
|
957
|
+
```http
|
|
958
|
+
POST /backup
|
|
959
|
+
Authorization: Bearer <admin-token>
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
Creates a new database backup. Keeps last 10 backups. Requires admin permission.
|
|
963
|
+
|
|
964
|
+
### Restore Backup
|
|
965
|
+
|
|
966
|
+
```http
|
|
967
|
+
PUT /backup
|
|
968
|
+
Authorization: Bearer <admin-token>
|
|
969
|
+
Content-Type: application/json
|
|
970
|
+
|
|
971
|
+
{
|
|
972
|
+
"filename": "aurawallet.db.20240201_120000.bak"
|
|
973
|
+
}
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
Restores database from a backup. Requires admin permission.
|
|
977
|
+
|
|
978
|
+
### Nuke (Reset)
|
|
979
|
+
|
|
980
|
+
```http
|
|
981
|
+
POST /nuke
|
|
982
|
+
Authorization: Bearer <admin-token>
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
Resets the wallet database. Requires admin permission. **Destructive — cannot be undone.**
|
|
986
|
+
|
|
987
|
+
### Import Wallet from Seed
|
|
988
|
+
|
|
989
|
+
```http
|
|
990
|
+
POST /nuke/import
|
|
991
|
+
Authorization: Bearer <admin-token>
|
|
992
|
+
Content-Type: application/json
|
|
993
|
+
|
|
994
|
+
{
|
|
995
|
+
"mnemonic": "word1 word2 ... word12",
|
|
996
|
+
"encrypted": "base64..."
|
|
997
|
+
}
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
Imports a wallet from an existing mnemonic seed phrase. Supports encrypted password transport (`encrypted`) or plaintext (`password`). Requires admin permission. Password must be at least 8 characters.
|
|
1001
|
+
|
|
1002
|
+
---
|
|
1003
|
+
|
|
1004
|
+
## Agent Endpoints (Require Bearer Token)
|
|
1005
|
+
|
|
1006
|
+
### List Wallets
|
|
1007
|
+
|
|
1008
|
+
```http
|
|
1009
|
+
GET /wallets
|
|
1010
|
+
Authorization: Bearer <token>
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
Returns all wallets the agent has access to. The response includes separate cold wallet entries per chain (e.g., one for EVM/Base and one for Solana). Each wallet includes a `chain` field and a `balance` field with the native currency balance for that chain (served from cache when available, with RPC fallback). The `balanceUpdatedAt` field indicates when the cached balance was last synced. The response also includes a `vaults` array listing all vaults and their status (see `GET /setup/vaults` for the vault object shape).
|
|
1014
|
+
|
|
1015
|
+
### List All Transactions
|
|
1016
|
+
|
|
1017
|
+
```http
|
|
1018
|
+
GET /wallets/transactions
|
|
1019
|
+
Authorization: Bearer <token> (optional)
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
Returns all transactions across all wallets. Without auth (human), returns all. Agents without `wallet:list` see only transactions for their own wallets. Agents with `wallet:list` see all.
|
|
1023
|
+
|
|
1024
|
+
**Query params:**
|
|
1025
|
+
- `wallet`: Filter by wallet address
|
|
1026
|
+
- `type`: Filter by type (send, receive, swap, contract, manual)
|
|
1027
|
+
- `status`: Filter by status (confirmed, pending)
|
|
1028
|
+
- `chain`: Filter by chain
|
|
1029
|
+
- `token`: Filter by token address
|
|
1030
|
+
- `search`: Search description, txHash, from, to
|
|
1031
|
+
- `limit`: Max results (default 50, max 250)
|
|
1032
|
+
- `offset`: Pagination offset
|
|
1033
|
+
- `sortBy`: Sort field (default: createdAt)
|
|
1034
|
+
- `sortDir`: Sort direction (asc, desc)
|
|
1035
|
+
|
|
1036
|
+
**Response:**
|
|
1037
|
+
```json
|
|
1038
|
+
{
|
|
1039
|
+
"success": true,
|
|
1040
|
+
"transactions": [
|
|
1041
|
+
{
|
|
1042
|
+
"id": "cuid123",
|
|
1043
|
+
"walletAddress": "0x...",
|
|
1044
|
+
"txHash": "0x...",
|
|
1045
|
+
"type": "swap",
|
|
1046
|
+
"status": "confirmed",
|
|
1047
|
+
"amount": "0.1",
|
|
1048
|
+
"tokenAddress": "0x...",
|
|
1049
|
+
"description": "Bought TOKEN with 0.1 ETH",
|
|
1050
|
+
"chain": "base",
|
|
1051
|
+
"createdAt": "2026-02-01T12:00:00.000Z"
|
|
1052
|
+
}
|
|
1053
|
+
],
|
|
1054
|
+
"pagination": {
|
|
1055
|
+
"total": 120,
|
|
1056
|
+
"limit": 50,
|
|
1057
|
+
"offset": 0,
|
|
1058
|
+
"hasMore": true
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
### Create Wallet
|
|
1064
|
+
|
|
1065
|
+
```http
|
|
1066
|
+
POST /wallet/create
|
|
1067
|
+
Authorization: Bearer <token>
|
|
1068
|
+
Content-Type: application/json
|
|
1069
|
+
|
|
1070
|
+
{
|
|
1071
|
+
"tier": "hot", // or "temp"
|
|
1072
|
+
"chain": "base", // Optional: "base", "ethereum", "solana", "solana-devnet" (default: "base")
|
|
1073
|
+
"name": "Trading",
|
|
1074
|
+
"color": "#ff4d00",
|
|
1075
|
+
"emoji": "🔥",
|
|
1076
|
+
"vaultId": "vault-abc123" // Optional: create under a specific vault (default: primary)
|
|
1077
|
+
}
|
|
1078
|
+
```
|
|
1079
|
+
|
|
1080
|
+
Creates a new hot or temp wallet. When `vaultId` is provided, the wallet is created under the specified vault and its private key is encrypted with that vault's mnemonic. If omitted, the primary vault is used.
|
|
1081
|
+
|
|
1082
|
+
### Search Wallets
|
|
1083
|
+
|
|
1084
|
+
```http
|
|
1085
|
+
GET /wallets/search?q=trading
|
|
1086
|
+
Authorization: Bearer <token> (optional)
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
Searches hot wallets by name or address. Agents with tokens only see their accessible wallets. Includes balance information.
|
|
1090
|
+
|
|
1091
|
+
**Query params:**
|
|
1092
|
+
- `q` (required): Search query string
|
|
1093
|
+
|
|
1094
|
+
**Response:**
|
|
1095
|
+
```json
|
|
1096
|
+
{
|
|
1097
|
+
"success": true,
|
|
1098
|
+
"wallets": [
|
|
1099
|
+
{
|
|
1100
|
+
"address": "0x...",
|
|
1101
|
+
"name": "Trading",
|
|
1102
|
+
"chain": "base",
|
|
1103
|
+
"tier": "hot",
|
|
1104
|
+
"balance": "500000000000000000"
|
|
1105
|
+
}
|
|
1106
|
+
]
|
|
1107
|
+
}
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
### Rename/Update Wallet
|
|
1111
|
+
|
|
1112
|
+
```http
|
|
1113
|
+
POST /wallet/rename
|
|
1114
|
+
Authorization: Bearer <token>
|
|
1115
|
+
Content-Type: application/json
|
|
1116
|
+
|
|
1117
|
+
{
|
|
1118
|
+
"address": "0x...",
|
|
1119
|
+
"name": "New Name",
|
|
1120
|
+
"color": "#ff4d00",
|
|
1121
|
+
"emoji": "🔥",
|
|
1122
|
+
"description": "Trading wallet",
|
|
1123
|
+
"hidden": false
|
|
1124
|
+
}
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
Updates hot wallet metadata. Requires `wallet:rename` permission and wallet access. All fields except `address` are optional.
|
|
1128
|
+
|
|
1129
|
+
### Export Wallet Private Key
|
|
1130
|
+
|
|
1131
|
+
```http
|
|
1132
|
+
POST /wallet/:address/export
|
|
1133
|
+
Authorization: Bearer <token> (optional)
|
|
1134
|
+
```
|
|
1135
|
+
|
|
1136
|
+
Exports the private key for a hot wallet. Requires the vault to be unlocked. Agents need `wallet:export` permission and wallet access. Humans (no token) can export when unlocked.
|
|
1137
|
+
|
|
1138
|
+
**Response:**
|
|
1139
|
+
```json
|
|
1140
|
+
{
|
|
1141
|
+
"success": true,
|
|
1142
|
+
"address": "0x...",
|
|
1143
|
+
"privateKey": "0x..."
|
|
1144
|
+
}
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
### Send Transaction
|
|
1148
|
+
|
|
1149
|
+
```http
|
|
1150
|
+
POST /send
|
|
1151
|
+
Authorization: Bearer <token>
|
|
1152
|
+
Content-Type: application/json
|
|
1153
|
+
|
|
1154
|
+
{
|
|
1155
|
+
"from": "0x...", // Hot wallet address (EVM or Solana base58)
|
|
1156
|
+
"to": "0x...", // Recipient address or ENS name (e.g. "vitalik.eth")
|
|
1157
|
+
"amount": "100000000000000000", // Amount in wei (EVM) or lamports (Solana). 0.1 ETH = 100000000000000000 wei, 0.1 SOL = 100000000 lamports.
|
|
1158
|
+
"tokenAddress": "0x...", // Optional: ERC-20/SPL token contract address for token sends
|
|
1159
|
+
"chain": "base", // Optional: chain to send on (default: configured default)
|
|
1160
|
+
"description": "..." // Optional: description for transaction history
|
|
1161
|
+
}
|
|
1162
|
+
```
|
|
1163
|
+
|
|
1164
|
+
Sends native currency or tokens from a hot wallet. Supports both EVM chains (ETH) and Solana (SOL). **Amounts must be in wei (EVM, 18 decimals) or lamports (Solana, 9 decimals).** Send spending limit enforced for agent tokens (if `limits.send` is set). Sends to the cold wallet address bypass the limit (returning funds to vault). Admin tokens bypass all limits.
|
|
1165
|
+
|
|
1166
|
+
**ENS resolution**: The `to` field accepts ENS names (e.g., `"vitalik.eth"`). Names are resolved to addresses before processing.
|
|
1167
|
+
|
|
1168
|
+
#### ERC-20/SPL Token Send
|
|
1169
|
+
|
|
1170
|
+
When `tokenAddress` is provided, the endpoint sends tokens instead of native currency:
|
|
1171
|
+
|
|
1172
|
+
```http
|
|
1173
|
+
POST /send
|
|
1174
|
+
Authorization: Bearer <token>
|
|
1175
|
+
Content-Type: application/json
|
|
1176
|
+
|
|
1177
|
+
{
|
|
1178
|
+
"from": "0x...",
|
|
1179
|
+
"to": "0x...",
|
|
1180
|
+
"amount": "1000000", // Token amount in raw units (e.g. 1 USDC = 1000000 for 6 decimals)
|
|
1181
|
+
"tokenAddress": "0xA0b86991...", // ERC-20 contract address (EVM) or SPL mint address (Solana)
|
|
1182
|
+
"chain": "base"
|
|
1183
|
+
}
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
- **EVM**: Encodes ERC-20 `transfer(to, amount)` calldata and sends to the token contract
|
|
1187
|
+
- **Solana**: Uses SPL token transfer with automatic ATA creation for the recipient
|
|
1188
|
+
- **Spending limits**: Token sends do NOT count against the native currency send limit (tokens are spent, not ETH/SOL)
|
|
1189
|
+
- Auto-tracks the token after a successful send
|
|
1190
|
+
- Response includes `tokenAddress` and `tokenAmount` instead of `amount`/`value`
|
|
1191
|
+
|
|
1192
|
+
#### Raw Solana Transaction
|
|
1193
|
+
|
|
1194
|
+
For Solana chains, you can submit a pre-built `VersionedTransaction` instead of a simple transfer. This enables interaction with any Solana program (pump.fun, Tensor, Marinade, Raydium, etc.):
|
|
1195
|
+
|
|
1196
|
+
```http
|
|
1197
|
+
POST /send
|
|
1198
|
+
Authorization: Bearer <token>
|
|
1199
|
+
Content-Type: application/json
|
|
1200
|
+
|
|
1201
|
+
{
|
|
1202
|
+
"from": "5Gh7...", // Solana hot/temp wallet address
|
|
1203
|
+
"transaction": "base64...", // Base64-encoded VersionedTransaction
|
|
1204
|
+
"chain": "solana",
|
|
1205
|
+
"to": "ProgramId...", // Optional: for logging only
|
|
1206
|
+
"description": "Buy on pump.fun bonding curve" // Optional
|
|
1207
|
+
}
|
|
1208
|
+
```
|
|
1209
|
+
|
|
1210
|
+
When `transaction` is provided:
|
|
1211
|
+
- The transaction is deserialized, signed with the wallet's keypair, and submitted
|
|
1212
|
+
- `to` and `amount` are not required (the transaction encodes its own instructions)
|
|
1213
|
+
- Spending limits are not tracked (value is encoded in instructions, same tradeoff as EVM `data` field)
|
|
1214
|
+
- Permission checks (`send:hot`/`send:temp`, wallet access) still apply
|
|
1215
|
+
- Response includes `type: "program"` and the transaction is logged as type `contract`
|
|
1216
|
+
|
|
1217
|
+
### Estimate Gas
|
|
1218
|
+
|
|
1219
|
+
```http
|
|
1220
|
+
POST /send/estimate
|
|
1221
|
+
Content-Type: application/json
|
|
1222
|
+
|
|
1223
|
+
{
|
|
1224
|
+
"from": "0x...",
|
|
1225
|
+
"to": "0x...",
|
|
1226
|
+
"amount": "100000000000000000",
|
|
1227
|
+
"data": "0x...",
|
|
1228
|
+
"chain": "base"
|
|
1229
|
+
}
|
|
1230
|
+
```
|
|
1231
|
+
|
|
1232
|
+
Estimates gas fees for a transaction (EVM only). No authentication required.
|
|
1233
|
+
|
|
1234
|
+
**Response:**
|
|
1235
|
+
```json
|
|
1236
|
+
{
|
|
1237
|
+
"success": true,
|
|
1238
|
+
"gasLimit": "21000",
|
|
1239
|
+
"gasPrice": "1000000000",
|
|
1240
|
+
"maxFeePerGas": "2000000000",
|
|
1241
|
+
"maxPriorityFeePerGas": "1000000",
|
|
1242
|
+
"estimatedCostWei": "42000000000000",
|
|
1243
|
+
"estimatedCostEth": "0.000042"
|
|
1244
|
+
}
|
|
1245
|
+
```
|
|
1246
|
+
|
|
1247
|
+
### Fund Hot Wallet
|
|
1248
|
+
|
|
1249
|
+
```http
|
|
1250
|
+
POST /fund
|
|
1251
|
+
Authorization: Bearer <token>
|
|
1252
|
+
Content-Type: application/json
|
|
1253
|
+
|
|
1254
|
+
{
|
|
1255
|
+
"to": "0x...", // Hot wallet to fund (EVM or Solana base58)
|
|
1256
|
+
"amount": "1000000000000000000", // Amount in wei (EVM) or lamports (Solana). 1.0 ETH = 1000000000000000000 wei.
|
|
1257
|
+
"chain": "base" // Optional: chain to fund on (default: configured default)
|
|
1258
|
+
}
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
Transfers native currency from cold wallet to hot wallet. Supports both EVM (ETH) and Solana (SOL). **Amounts must be in wei (EVM, 18 decimals) or lamports (Solana, 9 decimals).** Spending limit enforced for agent tokens.
|
|
1262
|
+
|
|
1263
|
+
### Swap Tokens
|
|
1264
|
+
|
|
1265
|
+
```http
|
|
1266
|
+
POST /swap
|
|
1267
|
+
Authorization: Bearer <token>
|
|
1268
|
+
Content-Type: application/json
|
|
1269
|
+
|
|
1270
|
+
{
|
|
1271
|
+
"from": "0x...", // Hot wallet address (EVM or Solana base58)
|
|
1272
|
+
"token": "0x...", // Token contract/mint address
|
|
1273
|
+
"direction": "buy", // "buy" or "sell"
|
|
1274
|
+
"amount": "100000000000000000", // Amount in wei (EVM) or lamports (Solana). For buy: native currency amount. For sell: token amount in base units.
|
|
1275
|
+
"slippage": 1, // Required: slippage tolerance % (e.g. 1.0 for 1%)
|
|
1276
|
+
"minOut": "...", // Alternative to slippage: explicit minimum output amount (EVM only)
|
|
1277
|
+
"dex": "relay", // Optional: "relay" (default), "uniswap", or "jupiter" (Solana)
|
|
1278
|
+
"chain": "base", // Optional: chain to swap on (default: configured default)
|
|
1279
|
+
"chainOut": "ethereum", // Optional: destination chain for cross-chain swaps (Relay only)
|
|
1280
|
+
"description": "..." // Optional: description for transaction history
|
|
1281
|
+
}
|
|
1282
|
+
```
|
|
1283
|
+
|
|
1284
|
+
Swaps tokens via DEX. On EVM chains, uses Relay (relay.link) as the default swap provider. Relay is an aggregator that supports all major EVM chains (Base, Ethereum, Arbitrum, Optimism, Polygon, and more). Uniswap is available as a fallback via `dex: "uniswap"` (Base only). On Solana, uses Jupiter aggregator. Creates Transaction record and auto-tracks the swapped token.
|
|
1285
|
+
|
|
1286
|
+
**Cross-chain swaps**: Set `chainOut` to a different chain name (e.g., `"ethereum"`) to perform a cross-chain swap via Relay. Cross-chain is only supported with Relay (the default DEX). If `chainOut` is omitted, the swap stays on the origin chain.
|
|
1287
|
+
|
|
1288
|
+
**App fee**: Relay swaps include a 1% app fee (Relay retains 25%, AuraWallet retains 75%).
|
|
1289
|
+
|
|
1290
|
+
**Slippage protection**: Either `slippage` or `minOut` must be provided. Slippage of 0% is rejected. Minimum floor: 0.5% for admin (manual swaps), 1% for agents (automated). Maximum: 50%.
|
|
1291
|
+
|
|
1292
|
+
### Swap Quote (Preview)
|
|
1293
|
+
|
|
1294
|
+
```http
|
|
1295
|
+
POST /swap/quote
|
|
1296
|
+
Authorization: Bearer <token>
|
|
1297
|
+
Content-Type: application/json
|
|
1298
|
+
|
|
1299
|
+
{
|
|
1300
|
+
"from": "0x...", // Hot wallet address
|
|
1301
|
+
"token": "0x...", // Token contract/mint address
|
|
1302
|
+
"direction": "buy", // "buy" or "sell"
|
|
1303
|
+
"amount": "100000000000000000", // Amount in wei/lamports
|
|
1304
|
+
"slippage": 1, // Optional: slippage tolerance %
|
|
1305
|
+
"dex": "relay", // Optional: DEX to quote from
|
|
1306
|
+
"chain": "base", // Optional: chain
|
|
1307
|
+
"chainOut": "ethereum" // Optional: destination chain (Relay only)
|
|
1308
|
+
}
|
|
1309
|
+
```
|
|
1310
|
+
|
|
1311
|
+
Returns a swap quote without executing. Same auth and validation as `POST /swap` (requires `swap` permission + wallet access), but no transaction is created and no spending limit is consumed.
|
|
1312
|
+
|
|
1313
|
+
**Response (Relay):**
|
|
1314
|
+
```json
|
|
1315
|
+
{
|
|
1316
|
+
"success": true,
|
|
1317
|
+
"inputAmount": "100000000000000000",
|
|
1318
|
+
"inputFormatted": "0.1",
|
|
1319
|
+
"inputUsd": "350.00",
|
|
1320
|
+
"outputAmount": "350000000",
|
|
1321
|
+
"outputFormatted": "350.0",
|
|
1322
|
+
"outputUsd": "350.00",
|
|
1323
|
+
"rate": "3500.0",
|
|
1324
|
+
"fees": { "gas": { "amount": "21000", "amountUsd": "0.05" } },
|
|
1325
|
+
"slippage": 1,
|
|
1326
|
+
"dex": "relay",
|
|
1327
|
+
"chain": "base"
|
|
1328
|
+
}
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
**Response (Jupiter/Solana):**
|
|
1332
|
+
```json
|
|
1333
|
+
{
|
|
1334
|
+
"success": true,
|
|
1335
|
+
"inputAmount": "100000000",
|
|
1336
|
+
"outputAmount": "5000000000",
|
|
1337
|
+
"priceImpact": "0.12",
|
|
1338
|
+
"route": [{ "label": "Raydium", "percent": 100, "inAmount": "100000000", "outAmount": "5000000000" }],
|
|
1339
|
+
"slippage": 1,
|
|
1340
|
+
"dex": "jupiter",
|
|
1341
|
+
"chain": "solana"
|
|
1342
|
+
}
|
|
1343
|
+
```
|
|
1344
|
+
|
|
1345
|
+
### List Available DEXes
|
|
1346
|
+
|
|
1347
|
+
```http
|
|
1348
|
+
GET /swap/dexes
|
|
1349
|
+
```
|
|
1350
|
+
|
|
1351
|
+
Lists all available DEX adapters and their configurations. No authentication required.
|
|
1352
|
+
|
|
1353
|
+
**Response:**
|
|
1354
|
+
```json
|
|
1355
|
+
{
|
|
1356
|
+
"success": true,
|
|
1357
|
+
"dexes": [
|
|
1358
|
+
{ "id": "relay", "name": "Relay", "chains": ["base", "ethereum", "arbitrum", "optimism"] },
|
|
1359
|
+
{ "id": "uniswap", "name": "Uniswap", "chains": ["base"] },
|
|
1360
|
+
{ "id": "jupiter", "name": "Jupiter", "chains": ["solana"] }
|
|
1361
|
+
]
|
|
1362
|
+
}
|
|
1363
|
+
```
|
|
1364
|
+
|
|
1365
|
+
### Launch Token
|
|
1366
|
+
|
|
1367
|
+
```http
|
|
1368
|
+
POST /launch
|
|
1369
|
+
Authorization: Bearer <token>
|
|
1370
|
+
Content-Type: application/json
|
|
1371
|
+
|
|
1372
|
+
{
|
|
1373
|
+
"from": "0x...", // Hot wallet address
|
|
1374
|
+
"name": "My Token", // Token name
|
|
1375
|
+
"symbol": "MTK", // Token symbol
|
|
1376
|
+
"tokenURI": "https://...", // Optional: explicit token metadata URI (overrides imageUrl/metadata)
|
|
1377
|
+
"imageUrl": "https://telegra.ph/file/abc.jpg", // Optional: public image URL for token
|
|
1378
|
+
"metadata": { // Optional: extra metadata fields (description, website, twitter, etc.)
|
|
1379
|
+
"description": "A fair launch token",
|
|
1380
|
+
"website": "https://example.com"
|
|
1381
|
+
},
|
|
1382
|
+
"type": "multicurve", // Optional: "static", "dynamic", or "multicurve" (default)
|
|
1383
|
+
"initialSupply": "1000000000", // Optional: total supply (default: 1B)
|
|
1384
|
+
"numTokensToSell": "900000000", // Optional: tokens for sale (default: 90% of supply)
|
|
1385
|
+
"preset": "medium", // Optional: market cap preset ("low", "medium", "high")
|
|
1386
|
+
"migration": "uniswapV2", // Optional: "uniswapV2" (default), "uniswapV3", "uniswapV4", "noOp"
|
|
1387
|
+
"vestingDuration": 31536000, // Optional: vesting period in seconds
|
|
1388
|
+
"startTime": 1707100000, // Optional: scheduled launch (Unix timestamp, multicurve only)
|
|
1389
|
+
"governance": "default", // Optional: "default" or "noOp"
|
|
1390
|
+
"beneficiaries": [ // Optional: fee recipients for the launched pool
|
|
1391
|
+
{ "address": "0x...", "shares": "0.5" }, // shares in ETH units (0.5 = 50%)
|
|
1392
|
+
{ "address": "0x...", "shares": "0.5" }
|
|
1393
|
+
],
|
|
1394
|
+
"chain": "base", // Optional: chain (default: configured default)
|
|
1395
|
+
"description": "..." // Optional: description for transaction history
|
|
1396
|
+
}
|
|
1397
|
+
```
|
|
1398
|
+
|
|
1399
|
+
Launches a new token via the [Doppler protocol](https://doppler.lol) fair launch mechanism. Uses the Doppler SDK to create token auctions on Uniswap. Requires `launch` permission. Creates Transaction record (type: 'launch') and auto-tracks the launched token.
|
|
1400
|
+
|
|
1401
|
+
**Auction types:**
|
|
1402
|
+
- `multicurve` (default): Multicurve initializer using Uniswap V4, supports market cap presets and scheduled launches
|
|
1403
|
+
- `static`: Fixed price range using Uniswap V3, ideal for simple price discovery
|
|
1404
|
+
- `dynamic`: Gradual Dutch auction using Uniswap V4 hooks
|
|
1405
|
+
|
|
1406
|
+
**Market cap presets** (multicurve only): `low` (~$7.5k-$30k), `medium` (~$50k-$150k), `high` (~$250k-$750k).
|
|
1407
|
+
|
|
1408
|
+
**Beneficiaries** (optional): Array of `{ address, shares }` specifying fee recipients for the launched pool. Shares are in ETH units (e.g. `"0.5"` = 50%, shares must sum to `"1.0"` = 100%). Supported on multicurve and static auction types. Ignored on dynamic auctions (SDK limitation).
|
|
1409
|
+
|
|
1410
|
+
**Token metadata:** If `tokenURI` is not provided but `imageUrl` or `metadata` is, the server auto-builds a metadata JSON from name, symbol, imageUrl, and any extra metadata fields, then encodes it as a `data:application/json;base64,...` data URI for the on-chain tokenURI. The agent is responsible for hosting the image at a publicly accessible URL (e.g. upload to [telegra.ph](https://telegra.ph) which requires no API key or signup). If `tokenURI` is explicitly provided, it takes precedence.
|
|
1411
|
+
|
|
1412
|
+
**Supported chains:** Base, Ethereum, Ink, Unichain (any chain supported by Doppler protocol).
|
|
1413
|
+
|
|
1414
|
+
### Collect Fees (Single Token)
|
|
1415
|
+
|
|
1416
|
+
```http
|
|
1417
|
+
POST /launch/:tokenAddress/collect-fees
|
|
1418
|
+
Authorization: Bearer <token>
|
|
1419
|
+
Content-Type: application/json
|
|
1420
|
+
|
|
1421
|
+
{
|
|
1422
|
+
"from": "0x...", // Wallet address to pay gas
|
|
1423
|
+
"chain": "base" // Optional: chain (default: configured default)
|
|
1424
|
+
}
|
|
1425
|
+
```
|
|
1426
|
+
|
|
1427
|
+
Collects accumulated trading fees from a Doppler multicurve pool and distributes them to the configured beneficiaries. The `collectFees` call is permissionless on-chain — anyone can trigger it, but fees always go to the beneficiary addresses configured at launch time. The caller only pays gas. No `launch` permission required, only valid auth token and wallet access for the gas-paying wallet.
|
|
1428
|
+
|
|
1429
|
+
**Response:**
|
|
1430
|
+
```json
|
|
1431
|
+
{
|
|
1432
|
+
"success": true,
|
|
1433
|
+
"tokenAddress": "0x...",
|
|
1434
|
+
"fees0": "1234567890",
|
|
1435
|
+
"fees1": "9876543210",
|
|
1436
|
+
"transactionHash": "0x...",
|
|
1437
|
+
"chain": "base"
|
|
1438
|
+
}
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
### Collect Fees (All Launched Tokens)
|
|
1442
|
+
|
|
1443
|
+
```http
|
|
1444
|
+
POST /launch/collect-fees
|
|
1445
|
+
Authorization: Bearer <token>
|
|
1446
|
+
Content-Type: application/json
|
|
1447
|
+
|
|
1448
|
+
{
|
|
1449
|
+
"from": "0x...", // Wallet address to pay gas
|
|
1450
|
+
"chain": "base" // Optional: chain (default: configured default)
|
|
1451
|
+
}
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
Collects fees from ALL tokens previously launched via AuraWallet on the specified chain. Iterates over all `launch` transactions in the database and calls `collectFees()` on each. Individual failures are reported per-token without failing the entire request. Same permissionless semantics as the single-token endpoint.
|
|
1455
|
+
|
|
1456
|
+
**Response:**
|
|
1457
|
+
```json
|
|
1458
|
+
{
|
|
1459
|
+
"success": true,
|
|
1460
|
+
"chain": "base",
|
|
1461
|
+
"total": 5,
|
|
1462
|
+
"collected": 4,
|
|
1463
|
+
"failed": 1,
|
|
1464
|
+
"results": [
|
|
1465
|
+
{ "tokenAddress": "0x...", "success": true, "fees0": "...", "fees1": "...", "transactionHash": "0x..." },
|
|
1466
|
+
{ "tokenAddress": "0x...", "success": false, "error": "Pool not found" }
|
|
1467
|
+
]
|
|
1468
|
+
}
|
|
1469
|
+
```
|
|
1470
|
+
|
|
1471
|
+
---
|
|
1472
|
+
|
|
1473
|
+
## Wallet Data Endpoints
|
|
1474
|
+
|
|
1475
|
+
### List Transactions
|
|
1476
|
+
|
|
1477
|
+
```http
|
|
1478
|
+
GET /wallet/:address/transactions
|
|
1479
|
+
Authorization: Bearer <token> (optional for own wallets, not required for external)
|
|
1480
|
+
```
|
|
1481
|
+
|
|
1482
|
+
**Two modes:**
|
|
1483
|
+
|
|
1484
|
+
1. **DB path** (our wallets): When the address belongs to a HotWallet in our DB, returns transaction records from the database. Response includes `"source": "db"`.
|
|
1485
|
+
|
|
1486
|
+
2. **On-chain fallback** (external addresses): When the address is not in our HotWallet table, fetches events from the chain via `eth_getLogs` (EVM) or `getSignaturesForAddress` (Solana). No auth required. Response includes `"source": "on-chain"`, `chain`, and `blockRange`.
|
|
1487
|
+
|
|
1488
|
+
**DB path query params:**
|
|
1489
|
+
- `type`: Filter by type (send, receive, swap, contract, manual)
|
|
1490
|
+
- `status`: Filter by status (confirmed, pending)
|
|
1491
|
+
- `token`: Filter by token address
|
|
1492
|
+
- `search`: Search description, txHash, from, to
|
|
1493
|
+
- `limit`: Max results (default 50, max 250)
|
|
1494
|
+
- `offset`: Pagination offset
|
|
1495
|
+
- `sortBy`: Sort field (default: createdAt)
|
|
1496
|
+
- `sortDir`: Sort direction (asc, desc)
|
|
1497
|
+
|
|
1498
|
+
**On-chain path query params:**
|
|
1499
|
+
- `chain`: Chain to query (default: base). Use `solana` or `solana-devnet` for Solana.
|
|
1500
|
+
- `limit`: Max results (1-100, default: 20)
|
|
1501
|
+
- `types`: Comma-separated event type filter (transfer, swap, swap_v2, swap_v3, swap_v4, approval, wrap)
|
|
1502
|
+
- `token`: Token contract address — when set, queries logs emitted BY the token contract (using the `address` field in `eth_getLogs`) instead of topic-based wallet matching. Useful for fetching all Transfer events for a specific token.
|
|
1503
|
+
- `fromBlock`: Start block (default: latest - 10000). EVM only.
|
|
1504
|
+
- `toBlock`: End block (default: latest). EVM only.
|
|
1505
|
+
|
|
1506
|
+
**V4 swap auto-correlation:** For wallet-level queries (no `token` param), the fetcher automatically discovers Uniswap V4 Swap events. V4 Swap topics don't contain the wallet address (topic1 = poolId, topic2 = Universal Router), so the fetcher looks for Transfer events without matching swaps ("orphan transfers") and queries the V4 PoolManager at those blocks to find correlated V4 Swap events sharing the same txHash.
|
|
1507
|
+
|
|
1508
|
+
**On-chain response format:**
|
|
1509
|
+
```json
|
|
1510
|
+
{
|
|
1511
|
+
"success": true,
|
|
1512
|
+
"source": "on-chain",
|
|
1513
|
+
"chain": "base",
|
|
1514
|
+
"blockRange": { "from": "90000", "to": "100000" },
|
|
1515
|
+
"transactions": [
|
|
1516
|
+
{
|
|
1517
|
+
"type": "transfer",
|
|
1518
|
+
"summary": "Received 500 USDC from 0x1234...abcd",
|
|
1519
|
+
"txHash": "0x...",
|
|
1520
|
+
"blockNumber": "99500",
|
|
1521
|
+
"timestamp": 1700000000,
|
|
1522
|
+
"details": { "from": "0x...", "to": "0x...", "amount": "500", "symbol": "USDC", "direction": "in" }
|
|
1523
|
+
}
|
|
1524
|
+
],
|
|
1525
|
+
"pagination": { "total": 42, "limit": 20, "returned": 20 }
|
|
1526
|
+
}
|
|
1527
|
+
```
|
|
1528
|
+
|
|
1529
|
+
Supported event types: Transfer (ERC-20/721), Swap (Uniswap V2/V3/V4), WETH Wrap/Unwrap, Approval. Note: native ETH transfers are not visible via `eth_getLogs`.
|
|
1530
|
+
|
|
1531
|
+
### Add Transaction
|
|
1532
|
+
|
|
1533
|
+
```http
|
|
1534
|
+
POST /wallet/:address/transactions
|
|
1535
|
+
Authorization: Bearer <token>
|
|
1536
|
+
Content-Type: application/json
|
|
1537
|
+
|
|
1538
|
+
{
|
|
1539
|
+
"type": "manual", // send, receive, swap, contract, manual
|
|
1540
|
+
"txHash": "0x...", // Optional
|
|
1541
|
+
"amount": "0.5", // Optional: ETH amount
|
|
1542
|
+
"tokenAddress": "0x...", // Optional: token contract
|
|
1543
|
+
"tokenAmount": "...", // Optional: token amount
|
|
1544
|
+
"from": "0x...", // Optional
|
|
1545
|
+
"to": "0x...", // Optional
|
|
1546
|
+
"description": "...", // Optional
|
|
1547
|
+
"executedAt": "..." // Optional: ISO timestamp
|
|
1548
|
+
}
|
|
1549
|
+
```
|
|
1550
|
+
|
|
1551
|
+
Requires `wallet:tx:add` permission.
|
|
1552
|
+
|
|
1553
|
+
### List Tracked Assets
|
|
1554
|
+
|
|
1555
|
+
```http
|
|
1556
|
+
GET /wallet/:address/assets
|
|
1557
|
+
Authorization: Bearer <token> (optional)
|
|
1558
|
+
```
|
|
1559
|
+
|
|
1560
|
+
Returns tracked assets for a wallet with USD pricing. Each asset includes `priceUsd` (current token price) and `valueUsd` (balance × price) when price data is available. Prices are fetched via the same cascading fallback as `GET /price/:address` (DexScreener → CoinGecko → Alchemy).
|
|
1561
|
+
|
|
1562
|
+
Query params:
|
|
1563
|
+
- `search`: Search symbol, name, or address
|
|
1564
|
+
- `includeHidden`: Include hidden assets (default: false)
|
|
1565
|
+
- `limit`, `offset`, `sortBy`, `sortDir`: Pagination/sorting
|
|
1566
|
+
|
|
1567
|
+
### Add Tracked Asset
|
|
1568
|
+
|
|
1569
|
+
```http
|
|
1570
|
+
POST /wallet/:address/asset
|
|
1571
|
+
Authorization: Bearer <token>
|
|
1572
|
+
Content-Type: application/json
|
|
1573
|
+
|
|
1574
|
+
{
|
|
1575
|
+
"tokenAddress": "0x...", // Required
|
|
1576
|
+
"symbol": "TKN", // Optional
|
|
1577
|
+
"name": "Token Name", // Optional
|
|
1578
|
+
"decimals": 18, // Optional (default: 18)
|
|
1579
|
+
"chain": "base", // Optional (default: base)
|
|
1580
|
+
"isHidden": false // Optional
|
|
1581
|
+
}
|
|
1582
|
+
```
|
|
1583
|
+
|
|
1584
|
+
Requires `wallet:asset:add` permission. Upserts if token already tracked.
|
|
1585
|
+
|
|
1586
|
+
### Portfolio Overview
|
|
1587
|
+
|
|
1588
|
+
```http
|
|
1589
|
+
GET /portfolio
|
|
1590
|
+
Authorization: Bearer <token> (optional)
|
|
1591
|
+
```
|
|
1592
|
+
|
|
1593
|
+
Returns an aggregated portfolio view across all wallets. Native balances are grouped by chain, token balances are grouped by token address. Includes cached ETH/SOL USD prices and per-token USD values.
|
|
1594
|
+
|
|
1595
|
+
Agents with tokens need `wallet:list` permission to see all wallets. Without auth (human), returns all.
|
|
1596
|
+
|
|
1597
|
+
**Query params:**
|
|
1598
|
+
- `token` — Filter by token contract address. Returns only that token's aggregated balance plus a `wallets` array with per-wallet breakdown.
|
|
1599
|
+
- `symbol` — Filter by token symbol (case-insensitive). Same behavior as `token` filter.
|
|
1600
|
+
- `chain` — Filter by chain name (e.g., `base`, `ethereum`, `solana`). Applies to both native and token balances.
|
|
1601
|
+
|
|
1602
|
+
**Example — filter by token:**
|
|
1603
|
+
```bash
|
|
1604
|
+
GET /portfolio?token=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
|
1605
|
+
```
|
|
1606
|
+
|
|
1607
|
+
**Response:**
|
|
1608
|
+
```json
|
|
1609
|
+
{
|
|
1610
|
+
"success": true,
|
|
1611
|
+
"byChain": [
|
|
1612
|
+
{ "chain": "base", "totalBalance": 4.0, "walletCount": 2, "valueUsd": "12002.00" },
|
|
1613
|
+
{ "chain": "ethereum", "totalBalance": 10.0, "walletCount": 1, "valueUsd": "30005.00" }
|
|
1614
|
+
],
|
|
1615
|
+
"byToken": [
|
|
1616
|
+
{
|
|
1617
|
+
"tokenAddress": "0xaaa...",
|
|
1618
|
+
"chain": "base",
|
|
1619
|
+
"symbol": "TKN",
|
|
1620
|
+
"name": "Test Token",
|
|
1621
|
+
"totalBalance": 300.75,
|
|
1622
|
+
"walletCount": 2,
|
|
1623
|
+
"priceUsd": "1.00",
|
|
1624
|
+
"valueUsd": "300.75"
|
|
1625
|
+
}
|
|
1626
|
+
],
|
|
1627
|
+
"prices": { "ETH": 3000.50, "SOL": 150.25 },
|
|
1628
|
+
"totalValueUsd": "42307.75"
|
|
1629
|
+
}
|
|
1630
|
+
```
|
|
1631
|
+
|
|
1632
|
+
**Response with `token` or `symbol` filter** (includes per-wallet breakdown):
|
|
1633
|
+
```json
|
|
1634
|
+
{
|
|
1635
|
+
"success": true,
|
|
1636
|
+
"byChain": [],
|
|
1637
|
+
"byToken": [
|
|
1638
|
+
{
|
|
1639
|
+
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
1640
|
+
"chain": "base",
|
|
1641
|
+
"symbol": "USDC",
|
|
1642
|
+
"name": "USD Coin",
|
|
1643
|
+
"totalBalance": 800.0,
|
|
1644
|
+
"walletCount": 2,
|
|
1645
|
+
"priceUsd": "1.00",
|
|
1646
|
+
"valueUsd": "800.00"
|
|
1647
|
+
}
|
|
1648
|
+
],
|
|
1649
|
+
"wallets": [
|
|
1650
|
+
{ "walletAddress": "0xaaa...", "chain": "base", "balance": 500, "valueUsd": "500.00" },
|
|
1651
|
+
{ "walletAddress": "0xbbb...", "chain": "base", "balance": 300, "valueUsd": "300.00" }
|
|
1652
|
+
],
|
|
1653
|
+
"prices": { "ETH": 3000.50, "SOL": 150.25 },
|
|
1654
|
+
"totalValueUsd": "800.00"
|
|
1655
|
+
}
|
|
1656
|
+
```
|
|
1657
|
+
|
|
1658
|
+
### Remove Tracked Asset
|
|
1659
|
+
|
|
1660
|
+
```http
|
|
1661
|
+
DELETE /wallet/:address/asset/:assetId
|
|
1662
|
+
Authorization: Bearer <token>
|
|
1663
|
+
```
|
|
1664
|
+
|
|
1665
|
+
Removes a tracked asset from the wallet. Requires `wallet:asset:remove` permission.
|
|
1666
|
+
|
|
1667
|
+
Emits `asset:changed` event with `removed: true`.
|
|
1668
|
+
|
|
1669
|
+
---
|
|
1670
|
+
|
|
1671
|
+
## Address Book
|
|
1672
|
+
|
|
1673
|
+
Label external addresses with nicknames, emojis, and colors.
|
|
1674
|
+
|
|
1675
|
+
### List Address Labels
|
|
1676
|
+
|
|
1677
|
+
```
|
|
1678
|
+
GET /address-labels?q=search_term
|
|
1679
|
+
```
|
|
1680
|
+
|
|
1681
|
+
Returns all labels, optionally filtered by search query (matches label or address).
|
|
1682
|
+
|
|
1683
|
+
### Create/Update Address Label
|
|
1684
|
+
|
|
1685
|
+
```
|
|
1686
|
+
POST /address-labels
|
|
1687
|
+
{
|
|
1688
|
+
"address": "0x1234...",
|
|
1689
|
+
"label": "Vitalik",
|
|
1690
|
+
"emoji": "🦄", // optional
|
|
1691
|
+
"color": "#FF5733", // optional
|
|
1692
|
+
"notes": "ETH co-founder" // optional
|
|
1693
|
+
}
|
|
1694
|
+
```
|
|
1695
|
+
|
|
1696
|
+
Requires `addressbook:write` permission. Upserts by address (lowercased).
|
|
1697
|
+
|
|
1698
|
+
`createdBy` is auto-set: `"human"` for admin tokens, agent ID for agent tokens.
|
|
1699
|
+
|
|
1700
|
+
### Delete Address Label
|
|
1701
|
+
|
|
1702
|
+
```
|
|
1703
|
+
DELETE /address-labels/:id
|
|
1704
|
+
```
|
|
1705
|
+
|
|
1706
|
+
Requires `addressbook:write` permission.
|
|
1707
|
+
|
|
1708
|
+
---
|
|
1709
|
+
|
|
1710
|
+
## Bookmarks (Token Watchlist)
|
|
1711
|
+
|
|
1712
|
+
Bookmark tokens without owning them. Creates a `TrackedAsset` row with `walletAddress: null`.
|
|
1713
|
+
|
|
1714
|
+
### List Bookmarks
|
|
1715
|
+
|
|
1716
|
+
```
|
|
1717
|
+
GET /bookmarks?chain=base&q=search_term
|
|
1718
|
+
```
|
|
1719
|
+
|
|
1720
|
+
Returns all bookmarks, enriched with `TokenMetadata` when available.
|
|
1721
|
+
|
|
1722
|
+
### Create Bookmark
|
|
1723
|
+
|
|
1724
|
+
```
|
|
1725
|
+
POST /bookmarks
|
|
1726
|
+
{
|
|
1727
|
+
"tokenAddress": "0xabcd...",
|
|
1728
|
+
"chain": "base" // optional, defaults to "base"
|
|
1729
|
+
}
|
|
1730
|
+
```
|
|
1731
|
+
|
|
1732
|
+
Requires `bookmark:write` permission. Idempotent — re-creating the same bookmark is a no-op. Seeds `TokenMetadata` cache on creation.
|
|
1733
|
+
|
|
1734
|
+
### Delete Bookmark
|
|
1735
|
+
|
|
1736
|
+
```
|
|
1737
|
+
DELETE /bookmarks/:id
|
|
1738
|
+
```
|
|
1739
|
+
|
|
1740
|
+
Requires `bookmark:write` permission. Only deletes bookmarks (null walletAddress), not wallet-tracked assets.
|
|
1741
|
+
|
|
1742
|
+
---
|
|
1743
|
+
|
|
1744
|
+
## System Defaults (Admin Only)
|
|
1745
|
+
|
|
1746
|
+
Centralized management of system-wide defaults (limits, permissions, TTLs, rate limits, etc.).
|
|
1747
|
+
|
|
1748
|
+
All endpoints require `admin:*` permission.
|
|
1749
|
+
|
|
1750
|
+
### List Defaults
|
|
1751
|
+
|
|
1752
|
+
```http
|
|
1753
|
+
GET /defaults
|
|
1754
|
+
Authorization: Bearer <admin-token>
|
|
1755
|
+
```
|
|
1756
|
+
|
|
1757
|
+
Returns all defaults grouped by type.
|
|
1758
|
+
|
|
1759
|
+
**Response:**
|
|
1760
|
+
```json
|
|
1761
|
+
{
|
|
1762
|
+
"success": true,
|
|
1763
|
+
"defaults": {
|
|
1764
|
+
"financial": [
|
|
1765
|
+
{ "key": "limits.fund", "value": 0.1, "type": "financial", "label": "Default Fund Limit (ETH)", "description": "...", "updatedAt": "..." }
|
|
1766
|
+
],
|
|
1767
|
+
"permissions": [...],
|
|
1768
|
+
"ttl": [...],
|
|
1769
|
+
"rate_limit": [...],
|
|
1770
|
+
"swap": [...],
|
|
1771
|
+
"ai_safety": [...],
|
|
1772
|
+
"launch": [...],
|
|
1773
|
+
"app": [...]
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
```
|
|
1777
|
+
|
|
1778
|
+
### Update Default
|
|
1779
|
+
|
|
1780
|
+
```http
|
|
1781
|
+
PATCH /defaults/:key
|
|
1782
|
+
Authorization: Bearer <admin-token>
|
|
1783
|
+
Content-Type: application/json
|
|
1784
|
+
|
|
1785
|
+
{ "value": 0.05 }
|
|
1786
|
+
```
|
|
1787
|
+
|
|
1788
|
+
Updates a single default value. Validates type against seed definition.
|
|
1789
|
+
|
|
1790
|
+
**Response:**
|
|
1791
|
+
```json
|
|
1792
|
+
{ "success": true, "key": "limits.fund", "value": 0.05 }
|
|
1793
|
+
```
|
|
1794
|
+
|
|
1795
|
+
### Reset Default
|
|
1796
|
+
|
|
1797
|
+
```http
|
|
1798
|
+
POST /defaults/reset
|
|
1799
|
+
Authorization: Bearer <admin-token>
|
|
1800
|
+
Content-Type: application/json
|
|
1801
|
+
|
|
1802
|
+
{ "key": "limits.fund" }
|
|
1803
|
+
```
|
|
1804
|
+
|
|
1805
|
+
Resets a single key to its seed value. Use `"key": "*"` to reset all defaults.
|
|
1806
|
+
|
|
1807
|
+
**Response:**
|
|
1808
|
+
```json
|
|
1809
|
+
{ "success": true, "key": "limits.fund", "reset": true }
|
|
1810
|
+
```
|
|
1811
|
+
|
|
1812
|
+
---
|
|
1813
|
+
|
|
1814
|
+
## Configuration Endpoints (Require Auth)
|
|
1815
|
+
|
|
1816
|
+
### Credential Vault Management (Admin)
|
|
1817
|
+
|
|
1818
|
+
#### List Credential Vaults
|
|
1819
|
+
|
|
1820
|
+
```http
|
|
1821
|
+
GET /vaults/credential
|
|
1822
|
+
Authorization: Bearer <admin-token>
|
|
1823
|
+
```
|
|
1824
|
+
|
|
1825
|
+
Returns wallet vaults with credential unlock status and credential counts.
|
|
1826
|
+
|
|
1827
|
+
#### Create Credential Vault
|
|
1828
|
+
|
|
1829
|
+
```http
|
|
1830
|
+
POST /vaults/credential
|
|
1831
|
+
Authorization: Bearer <admin-token>
|
|
1832
|
+
Content-Type: application/json
|
|
1833
|
+
|
|
1834
|
+
{
|
|
1835
|
+
"encrypted": "<rsa-oaep password>",
|
|
1836
|
+
"name": "work"
|
|
1837
|
+
}
|
|
1838
|
+
```
|
|
1839
|
+
|
|
1840
|
+
Creates an additional vault and unlocks it.
|
|
1841
|
+
|
|
1842
|
+
#### Lock Credential Vault
|
|
1843
|
+
|
|
1844
|
+
```http
|
|
1845
|
+
POST /vaults/credential/:id/lock
|
|
1846
|
+
Authorization: Bearer <admin-token>
|
|
1847
|
+
```
|
|
1848
|
+
|
|
1849
|
+
Locks the vault and clears credential subkeys from memory.
|
|
1850
|
+
|
|
1851
|
+
#### Delete Credential Vault
|
|
1852
|
+
|
|
1853
|
+
```http
|
|
1854
|
+
DELETE /vaults/credential/:id
|
|
1855
|
+
Authorization: Bearer <admin-token>
|
|
1856
|
+
```
|
|
1857
|
+
|
|
1858
|
+
Deletes the vault and all credentials assigned to it.
|
|
1859
|
+
|
|
1860
|
+
### Credential Management
|
|
1861
|
+
|
|
1862
|
+
#### List Credentials (Metadata)
|
|
1863
|
+
|
|
1864
|
+
```http
|
|
1865
|
+
GET /credentials?vault=<id>&type=<type>&tag=<tag>&q=<query>
|
|
1866
|
+
Authorization: Bearer <token>
|
|
1867
|
+
```
|
|
1868
|
+
|
|
1869
|
+
Requires `secret:read` (or `admin:*`). Results are scope-filtered by `credentialAccess.read`.
|
|
1870
|
+
|
|
1871
|
+
#### Create Credential
|
|
1872
|
+
|
|
1873
|
+
```http
|
|
1874
|
+
POST /credentials
|
|
1875
|
+
Authorization: Bearer <token>
|
|
1876
|
+
Content-Type: application/json
|
|
1877
|
+
|
|
1878
|
+
{
|
|
1879
|
+
"vaultId": "primary",
|
|
1880
|
+
"type": "login",
|
|
1881
|
+
"name": "GitHub",
|
|
1882
|
+
"meta": { "tags": ["deploy"] },
|
|
1883
|
+
"fields": [
|
|
1884
|
+
{ "key": "username", "value": "alice", "type": "text", "sensitive": false },
|
|
1885
|
+
{ "key": "password", "value": "hunter2", "type": "secret", "sensitive": true }
|
|
1886
|
+
]
|
|
1887
|
+
}
|
|
1888
|
+
```
|
|
1889
|
+
|
|
1890
|
+
Requires `secret:write` (or `admin:*`) and matching write scope.
|
|
1891
|
+
|
|
1892
|
+
#### Read Credential (Encrypted Response)
|
|
1893
|
+
|
|
1894
|
+
```http
|
|
1895
|
+
POST /credentials/:id/read
|
|
1896
|
+
Authorization: Bearer <token>
|
|
1897
|
+
```
|
|
1898
|
+
|
|
1899
|
+
Requires `secret:read` (or `admin:*`), matching read scope, and `agentPubkey` on the token.
|
|
1900
|
+
Enforces `credentialAccess.ttl` and `credentialAccess.maxReads`.
|
|
1901
|
+
|
|
1902
|
+
**Response:**
|
|
1903
|
+
|
|
1904
|
+
```json
|
|
1905
|
+
{
|
|
1906
|
+
"success": true,
|
|
1907
|
+
"credentialId": "cred-abc123",
|
|
1908
|
+
"encrypted": "<base64 ciphertext>"
|
|
1909
|
+
}
|
|
1910
|
+
```
|
|
1911
|
+
|
|
1912
|
+
`encrypted` may be direct RSA-OAEP ciphertext (small payloads) or a base64-encoded hybrid envelope (RSA-wrapped AES key + AES-GCM data) for larger payloads.
|
|
1913
|
+
|
|
1914
|
+
### API Key Management
|
|
1915
|
+
|
|
1916
|
+
#### List API Keys
|
|
1917
|
+
|
|
1918
|
+
```http
|
|
1919
|
+
GET /apikeys
|
|
1920
|
+
Authorization: Bearer <token>
|
|
1921
|
+
```
|
|
1922
|
+
|
|
1923
|
+
Permission: `apikey:get` (or `trade:all`)
|
|
1924
|
+
|
|
1925
|
+
Returns masked API key entries served from credential vault storage (`type: "apikey"`).
|
|
1926
|
+
|
|
1927
|
+
#### Create/Update API Key
|
|
1928
|
+
|
|
1929
|
+
```http
|
|
1930
|
+
POST /apikeys
|
|
1931
|
+
Authorization: Bearer <token>
|
|
1932
|
+
Content-Type: application/json
|
|
1933
|
+
|
|
1934
|
+
{
|
|
1935
|
+
"service": "alchemy",
|
|
1936
|
+
"name": "default",
|
|
1937
|
+
"key": "your-api-key"
|
|
1938
|
+
}
|
|
1939
|
+
```
|
|
1940
|
+
|
|
1941
|
+
Permission: `apikey:set`
|
|
1942
|
+
|
|
1943
|
+
Upserts by `service` + `name` composite key.
|
|
1944
|
+
The value is stored in credential vault as an encrypted `apikey` credential (legacy DB row is kept in sync for compatibility).
|
|
1945
|
+
|
|
1946
|
+
#### Validate API Key
|
|
1947
|
+
|
|
1948
|
+
```http
|
|
1949
|
+
POST /apikeys/validate
|
|
1950
|
+
Authorization: Bearer <token>
|
|
1951
|
+
Content-Type: application/json
|
|
1952
|
+
|
|
1953
|
+
{
|
|
1954
|
+
"service": "alchemy",
|
|
1955
|
+
"key": "your-api-key"
|
|
1956
|
+
}
|
|
1957
|
+
```
|
|
1958
|
+
|
|
1959
|
+
Permission: `apikey:set`
|
|
1960
|
+
|
|
1961
|
+
Validates an API key against its external service before saving. All validation calls have a 5-second timeout.
|
|
1962
|
+
|
|
1963
|
+
**Supported services:**
|
|
1964
|
+
|
|
1965
|
+
| Service | Validation | Success Info |
|
|
1966
|
+
|---------|-----------|--------------|
|
|
1967
|
+
| `alchemy` | `eth_blockNumber` JSON-RPC call | — |
|
|
1968
|
+
| `anthropic` | Minimal Messages API request (200 or 429 = valid) | — |
|
|
1969
|
+
| `openai` | OpenAI Models API (200 = valid) | — |
|
|
1970
|
+
| `adapter:telegram` | Telegram Bot API `getMe` | `{ botUsername }` |
|
|
1971
|
+
|
|
1972
|
+
**Response:**
|
|
1973
|
+
```json
|
|
1974
|
+
{ "valid": true, "info": { "botUsername": "MyBot" } }
|
|
1975
|
+
```
|
|
1976
|
+
|
|
1977
|
+
```json
|
|
1978
|
+
{ "valid": false, "error": "Invalid API key" }
|
|
1979
|
+
```
|
|
1980
|
+
|
|
1981
|
+
#### Delete API Key
|
|
1982
|
+
|
|
1983
|
+
```http
|
|
1984
|
+
DELETE /apikeys/:id
|
|
1985
|
+
Authorization: Bearer <token>
|
|
1986
|
+
```
|
|
1987
|
+
|
|
1988
|
+
Permission: `apikey:set`
|
|
1989
|
+
|
|
1990
|
+
Soft-deletes by setting `isActive = false`.
|
|
1991
|
+
|
|
1992
|
+
### Adapter Management
|
|
1993
|
+
|
|
1994
|
+
#### List Adapters
|
|
1995
|
+
|
|
1996
|
+
```http
|
|
1997
|
+
GET /adapters
|
|
1998
|
+
Authorization: Bearer <token>
|
|
1999
|
+
```
|
|
2000
|
+
|
|
2001
|
+
Permission: `adapter:manage`
|
|
2002
|
+
|
|
2003
|
+
Returns configured adapters with secret status and running state.
|
|
2004
|
+
|
|
2005
|
+
#### Save Adapter Config
|
|
2006
|
+
|
|
2007
|
+
```http
|
|
2008
|
+
POST /adapters
|
|
2009
|
+
Authorization: Bearer <token>
|
|
2010
|
+
Content-Type: application/json
|
|
2011
|
+
|
|
2012
|
+
{
|
|
2013
|
+
"type": "telegram",
|
|
2014
|
+
"enabled": true,
|
|
2015
|
+
"config": { "chatId": "123456789" }
|
|
2016
|
+
}
|
|
2017
|
+
```
|
|
2018
|
+
|
|
2019
|
+
Permission: `adapter:manage`
|
|
2020
|
+
|
|
2021
|
+
#### Test Adapter
|
|
2022
|
+
|
|
2023
|
+
```http
|
|
2024
|
+
POST /adapters/test
|
|
2025
|
+
Authorization: Bearer <token>
|
|
2026
|
+
Content-Type: application/json
|
|
2027
|
+
|
|
2028
|
+
{
|
|
2029
|
+
"type": "telegram"
|
|
2030
|
+
}
|
|
2031
|
+
```
|
|
2032
|
+
|
|
2033
|
+
Permission: `adapter:manage`
|
|
2034
|
+
|
|
2035
|
+
Sends a test message through a configured adapter. Returns 404 if the adapter's required config (bot token, chat ID, webhook URL) is not configured.
|
|
2036
|
+
|
|
2037
|
+
**Supported types:**
|
|
2038
|
+
|
|
2039
|
+
| Type | Behavior |
|
|
2040
|
+
|------|----------|
|
|
2041
|
+
| `telegram` | Sends test message via Telegram Bot API `sendMessage` |
|
|
2042
|
+
| `webhook` | POSTs `{ type: "test", data: {}, timestamp }` to webhook URL |
|
|
2043
|
+
|
|
2044
|
+
**Response:**
|
|
2045
|
+
```json
|
|
2046
|
+
{ "success": true }
|
|
2047
|
+
```
|
|
2048
|
+
|
|
2049
|
+
```json
|
|
2050
|
+
{ "success": false, "error": "Failed to send test message" }
|
|
2051
|
+
```
|
|
2052
|
+
|
|
2053
|
+
#### Update Chat Config
|
|
2054
|
+
|
|
2055
|
+
```http
|
|
2056
|
+
POST /adapters/chat
|
|
2057
|
+
Authorization: Bearer <token>
|
|
2058
|
+
Content-Type: application/json
|
|
2059
|
+
|
|
2060
|
+
{
|
|
2061
|
+
"defaultApp": "swap-chat"
|
|
2062
|
+
}
|
|
2063
|
+
```
|
|
2064
|
+
|
|
2065
|
+
Permission: `adapter:manage`
|
|
2066
|
+
|
|
2067
|
+
Sets the default app for adapter chat routing. The `defaultApp` determines which app's AI handles incoming chat messages from adapters.
|
|
2068
|
+
|
|
2069
|
+
**Response:**
|
|
2070
|
+
```json
|
|
2071
|
+
{ "success": true, "chat": { "defaultApp": "swap-chat" } }
|
|
2072
|
+
```
|
|
2073
|
+
|
|
2074
|
+
#### Send Chat Message (Webhook Inbound)
|
|
2075
|
+
|
|
2076
|
+
```http
|
|
2077
|
+
POST /adapters/:type/message
|
|
2078
|
+
Content-Type: application/json
|
|
2079
|
+
X-Signature-256: sha256=<hmac>
|
|
2080
|
+
|
|
2081
|
+
{
|
|
2082
|
+
"text": "What is my balance?",
|
|
2083
|
+
"senderId": "user-123",
|
|
2084
|
+
"targetApp": "swap-chat"
|
|
2085
|
+
}
|
|
2086
|
+
```
|
|
2087
|
+
|
|
2088
|
+
Inbound chat endpoint for adapter webhooks. Routes the message to the target app's AI via `handleAppMessage()`.
|
|
2089
|
+
|
|
2090
|
+
**Authentication:** HMAC-SHA256 signature required if the adapter has a secret stored (`POST /apikeys` with `service: "adapter:<type>"`). Uses the same `X-Signature-256` header format as webhook notifications.
|
|
2091
|
+
|
|
2092
|
+
**Request body:**
|
|
2093
|
+
- `text` (required) - Message text
|
|
2094
|
+
- `senderId` (required) - Sender identifier
|
|
2095
|
+
- `targetApp` (optional) - Explicit app target. If omitted, uses `chat.defaultApp` from adapter config.
|
|
2096
|
+
|
|
2097
|
+
**Response:**
|
|
2098
|
+
```json
|
|
2099
|
+
{
|
|
2100
|
+
"success": true,
|
|
2101
|
+
"reply": "You have 1.5 ETH in your hot wallet.",
|
|
2102
|
+
"error": null
|
|
2103
|
+
}
|
|
2104
|
+
```
|
|
2105
|
+
|
|
2106
|
+
#### Restart Adapters
|
|
2107
|
+
|
|
2108
|
+
```http
|
|
2109
|
+
POST /adapters/restart
|
|
2110
|
+
Authorization: Bearer <token>
|
|
2111
|
+
```
|
|
2112
|
+
|
|
2113
|
+
Permission: `adapter:manage`
|
|
2114
|
+
|
|
2115
|
+
Restarts the approval router with current DB config.
|
|
2116
|
+
|
|
2117
|
+
#### Delete Adapter
|
|
2118
|
+
|
|
2119
|
+
```http
|
|
2120
|
+
DELETE /adapters/:type
|
|
2121
|
+
Authorization: Bearer <token>
|
|
2122
|
+
```
|
|
2123
|
+
|
|
2124
|
+
Permission: `adapter:manage`
|
|
2125
|
+
|
|
2126
|
+
---
|
|
2127
|
+
|
|
2128
|
+
## Request Types
|
|
2129
|
+
|
|
2130
|
+
When agents call endpoints that require approval:
|
|
2131
|
+
|
|
2132
|
+
| Type | Trigger | What Happens |
|
|
2133
|
+
|------|---------|--------------|
|
|
2134
|
+
| `agent_access` | Agent requests token | Human approves → Token generated |
|
|
2135
|
+
| `fund` | `/fund` endpoint | If over limit → Pending approval |
|
|
2136
|
+
| `send` | `/send` endpoint | Send limit enforced (if `limits.send` set). Cold wallet returns bypass limit |
|
|
2137
|
+
| `launch` | `/launch` endpoint | Launch limit enforced (if `limits.launch` set) |
|
|
2138
|
+
|
|
2139
|
+
---
|
|
2140
|
+
|
|
2141
|
+
## WebSocket Events
|
|
2142
|
+
|
|
2143
|
+
The wallet server broadcasts events to `ws://localhost:4748`:
|
|
2144
|
+
|
|
2145
|
+
| Event | Description |
|
|
2146
|
+
|-------|-------------|
|
|
2147
|
+
| `token:created` | New agent token issued |
|
|
2148
|
+
| `token:revoked` | Token was revoked |
|
|
2149
|
+
| `token:spent` | Token spending updated |
|
|
2150
|
+
| `vault:unlocked` | Vault was unlocked |
|
|
2151
|
+
| `action:created` | New human action pending |
|
|
2152
|
+
| `action:resolved` | Human action approved/rejected |
|
|
2153
|
+
| `wallet:created` | New wallet created |
|
|
2154
|
+
| `wallet:changed` | Wallet data updated |
|
|
2155
|
+
| `asset:changed` | Token asset tracked or pool info updated |
|
|
2156
|
+
| `tx:created` | New transaction recorded |
|
|
2157
|
+
| `balance:updated` | Cached balance synced (from cron server) |
|
|
2158
|
+
|
|
2159
|
+
### asset:changed Event
|
|
2160
|
+
|
|
2161
|
+
Emitted when:
|
|
2162
|
+
- A new token is tracked for a wallet
|
|
2163
|
+
- Pool detection discovers DEX pool info
|
|
2164
|
+
- An asset is removed (`removed: true`)
|
|
2165
|
+
|
|
2166
|
+
```json
|
|
2167
|
+
{
|
|
2168
|
+
"type": "asset:changed",
|
|
2169
|
+
"timestamp": 1707052800000,
|
|
2170
|
+
"source": "express",
|
|
2171
|
+
"data": {
|
|
2172
|
+
"walletAddress": "0x123...",
|
|
2173
|
+
"tokenAddress": "0xabc...",
|
|
2174
|
+
"symbol": "TOKEN",
|
|
2175
|
+
"name": "My Token",
|
|
2176
|
+
"poolAddress": "0xdef...",
|
|
2177
|
+
"poolVersion": "v3",
|
|
2178
|
+
"removed": false
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
```
|
|
2182
|
+
|
|
2183
|
+
### tx:created Event
|
|
2184
|
+
|
|
2185
|
+
Emitted when:
|
|
2186
|
+
- A send transaction is recorded
|
|
2187
|
+
- A swap transaction is recorded
|
|
2188
|
+
- A manual transaction is added
|
|
2189
|
+
|
|
2190
|
+
```json
|
|
2191
|
+
{
|
|
2192
|
+
"type": "tx:created",
|
|
2193
|
+
"timestamp": 1707052800000,
|
|
2194
|
+
"source": "express",
|
|
2195
|
+
"data": {
|
|
2196
|
+
"walletAddress": "0x123...",
|
|
2197
|
+
"id": "cuid123",
|
|
2198
|
+
"type": "swap",
|
|
2199
|
+
"txHash": "0x789...",
|
|
2200
|
+
"amount": "0.1",
|
|
2201
|
+
"tokenAddress": "0xabc...",
|
|
2202
|
+
"description": "Bought TOKEN with 0.1 ETH"
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
```
|
|
2206
|
+
|
|
2207
|
+
---
|
|
2208
|
+
|
|
2209
|
+
## AI Status (Admin Only)
|
|
2210
|
+
|
|
2211
|
+
### Get AI Provider Status
|
|
2212
|
+
|
|
2213
|
+
```http
|
|
2214
|
+
GET /ai/status
|
|
2215
|
+
Authorization: Bearer <admin-token>
|
|
2216
|
+
```
|
|
2217
|
+
|
|
2218
|
+
Returns the active AI provider, default model, and availability status of all providers. Used by the SystemDefaultsApp to populate the AI Engine settings.
|
|
2219
|
+
|
|
2220
|
+
**Response:**
|
|
2221
|
+
```json
|
|
2222
|
+
{
|
|
2223
|
+
"activeProvider": "claude-cli",
|
|
2224
|
+
"defaultModel": "sonnet",
|
|
2225
|
+
"providers": [
|
|
2226
|
+
{ "mode": "claude-cli", "label": "Claude Max (CLI)", "available": true, "reason": "claude CLI found in PATH", "models": ["haiku", "sonnet", "opus"] },
|
|
2227
|
+
{ "mode": "claude-api", "label": "Claude API Key", "available": false, "reason": "No Anthropic API key configured", "models": ["haiku", "sonnet", "opus"] },
|
|
2228
|
+
{ "mode": "codex-cli", "label": "Codex Max (CLI)", "available": false, "reason": "codex CLI not found in PATH", "models": ["codex-mini", "codex", "codex-max"] },
|
|
2229
|
+
{ "mode": "openai-api", "label": "OpenAI API Key", "available": false, "reason": "No OpenAI API key configured", "models": ["codex-mini", "codex", "codex-max"] }
|
|
2230
|
+
]
|
|
2231
|
+
}
|
|
2232
|
+
```
|
|
2233
|
+
|
|
2234
|
+
Provider/model selection is configured via the system defaults `ai.provider` and `ai.default_model` (use `PATCH /defaults/:key`).
|
|
2235
|
+
|
|
2236
|
+
---
|
|
2237
|
+
|
|
2238
|
+
## Strategy Endpoints
|
|
2239
|
+
|
|
2240
|
+
Strategy endpoints manage strategy templates, creation, install, lifecycle, config/state, and approvals.
|
|
2241
|
+
All endpoints are mounted at `/strategies`.
|
|
2242
|
+
|
|
2243
|
+
### List Strategies
|
|
2244
|
+
|
|
2245
|
+
```http
|
|
2246
|
+
GET /strategies
|
|
2247
|
+
Authorization: Bearer <token>
|
|
2248
|
+
```
|
|
2249
|
+
|
|
2250
|
+
Permission: `strategy:read`
|
|
2251
|
+
|
|
2252
|
+
Returns DB-backed strategies with current runtime/status metadata.
|
|
2253
|
+
|
|
2254
|
+
**Response:**
|
|
2255
|
+
```json
|
|
2256
|
+
{
|
|
2257
|
+
"success": true,
|
|
2258
|
+
"strategies": [
|
|
2259
|
+
{
|
|
2260
|
+
"id": "strategy-123",
|
|
2261
|
+
"name": "ETH DCA Daily",
|
|
2262
|
+
"enabled": true,
|
|
2263
|
+
"running": false,
|
|
2264
|
+
"ticker": "maintenance",
|
|
2265
|
+
"lastTick": 1760000000000,
|
|
2266
|
+
"lastError": null,
|
|
2267
|
+
"errorCount": 0
|
|
2268
|
+
}
|
|
2269
|
+
]
|
|
2270
|
+
}
|
|
2271
|
+
```
|
|
2272
|
+
|
|
2273
|
+
### List Strategy Templates
|
|
2274
|
+
|
|
2275
|
+
```http
|
|
2276
|
+
GET /strategies/templates
|
|
2277
|
+
Authorization: Bearer <token>
|
|
2278
|
+
```
|
|
2279
|
+
|
|
2280
|
+
Permission: `strategy:read`
|
|
2281
|
+
|
|
2282
|
+
Returns the v1 template catalog (`recurring_buy`, `buy_on_drop`, `stop_loss`, `portfolio_report`).
|
|
2283
|
+
|
|
2284
|
+
### Create Template Strategy
|
|
2285
|
+
|
|
2286
|
+
```http
|
|
2287
|
+
POST /strategies
|
|
2288
|
+
Authorization: Bearer <token>
|
|
2289
|
+
Content-Type: application/json
|
|
2290
|
+
|
|
2291
|
+
{
|
|
2292
|
+
"template": "recurring_buy",
|
|
2293
|
+
"name": "Buy $100 BNKR Daily",
|
|
2294
|
+
"mode": "headless",
|
|
2295
|
+
"config": {
|
|
2296
|
+
"chain": "base",
|
|
2297
|
+
"wallet": "0x1111111111111111111111111111111111111111",
|
|
2298
|
+
"token": "0x2222222222222222222222222222222222222222",
|
|
2299
|
+
"amountUsd": "100"
|
|
2300
|
+
},
|
|
2301
|
+
"enabled": false
|
|
2302
|
+
}
|
|
2303
|
+
```
|
|
2304
|
+
|
|
2305
|
+
Permission: `strategy:manage`
|
|
2306
|
+
|
|
2307
|
+
Creates a DB-backed strategy from a supported template. `permissions`/`limits` overrides are rejected for template strategies.
|
|
2308
|
+
|
|
2309
|
+
### Install Third-Party Strategy
|
|
2310
|
+
|
|
2311
|
+
```http
|
|
2312
|
+
POST /strategies/install
|
|
2313
|
+
Authorization: Bearer <token>
|
|
2314
|
+
Content-Type: application/json
|
|
2315
|
+
```
|
|
2316
|
+
|
|
2317
|
+
Permission: `strategy:manage`
|
|
2318
|
+
|
|
2319
|
+
Provide exactly one of:
|
|
2320
|
+
- `source`: local path / git / tarball / zip source
|
|
2321
|
+
- `manifest`: inline strategy manifest
|
|
2322
|
+
|
|
2323
|
+
Supports `enabled`, `mode`, `config`, `name`, and `approve` flags. Third-party strategies with permissions/limits require explicit install approval before enable.
|
|
2324
|
+
|
|
2325
|
+
### Strategy Runtime Health
|
|
2326
|
+
|
|
2327
|
+
```http
|
|
2328
|
+
GET /strategies/health
|
|
2329
|
+
Authorization: Bearer <token>
|
|
2330
|
+
```
|
|
2331
|
+
|
|
2332
|
+
Permission: `strategy:read`
|
|
2333
|
+
|
|
2334
|
+
Returns cron runtime health for strategy execution.
|
|
2335
|
+
|
|
2336
|
+
**Response (healthy):**
|
|
2337
|
+
```json
|
|
2338
|
+
{
|
|
2339
|
+
"success": true,
|
|
2340
|
+
"strategyRuntime": {
|
|
2341
|
+
"owner": "cron",
|
|
2342
|
+
"cronEnabled": true,
|
|
2343
|
+
"apiEngineStarted": false,
|
|
2344
|
+
"healthy": true,
|
|
2345
|
+
"staleAfterMs": 30000,
|
|
2346
|
+
"isStale": false,
|
|
2347
|
+
"lastSyncAt": "2026-02-14T19:11:22.123Z",
|
|
2348
|
+
"lastStatus": "ok",
|
|
2349
|
+
"lastError": null,
|
|
2350
|
+
"syncCount": 42
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
```
|
|
2354
|
+
|
|
2355
|
+
### Enable Strategy
|
|
2356
|
+
|
|
2357
|
+
```http
|
|
2358
|
+
POST /strategies/:id/enable
|
|
2359
|
+
Authorization: Bearer <token>
|
|
2360
|
+
```
|
|
2361
|
+
|
|
2362
|
+
Permission: `strategy:manage`
|
|
2363
|
+
|
|
2364
|
+
Enables a strategy.
|
|
2365
|
+
|
|
2366
|
+
**Response:**
|
|
2367
|
+
```json
|
|
2368
|
+
{
|
|
2369
|
+
"success": true,
|
|
2370
|
+
"enabled": true,
|
|
2371
|
+
"owner": "cron-runtime"
|
|
2372
|
+
}
|
|
2373
|
+
```
|
|
2374
|
+
|
|
2375
|
+
### Disable Strategy
|
|
2376
|
+
|
|
2377
|
+
```http
|
|
2378
|
+
POST /strategies/:id/disable
|
|
2379
|
+
Authorization: Bearer <token>
|
|
2380
|
+
```
|
|
2381
|
+
|
|
2382
|
+
Permission: `strategy:manage`
|
|
2383
|
+
|
|
2384
|
+
Disables a strategy.
|
|
2385
|
+
|
|
2386
|
+
**Response:**
|
|
2387
|
+
```json
|
|
2388
|
+
{
|
|
2389
|
+
"success": true,
|
|
2390
|
+
"enabled": false,
|
|
2391
|
+
"owner": "cron-runtime"
|
|
2392
|
+
}
|
|
2393
|
+
```
|
|
2394
|
+
|
|
2395
|
+
### Toggle Strategy (Compatibility)
|
|
2396
|
+
|
|
2397
|
+
```http
|
|
2398
|
+
POST /strategies/:id/toggle
|
|
2399
|
+
Authorization: Bearer <token>
|
|
2400
|
+
```
|
|
2401
|
+
|
|
2402
|
+
Permission: `strategy:manage`
|
|
2403
|
+
|
|
2404
|
+
Compatibility endpoint that flips current enabled state.
|
|
2405
|
+
|
|
2406
|
+
### Get Strategy Config
|
|
2407
|
+
|
|
2408
|
+
```http
|
|
2409
|
+
GET /strategies/:id/config
|
|
2410
|
+
Authorization: Bearer <token>
|
|
2411
|
+
```
|
|
2412
|
+
|
|
2413
|
+
Permission: `strategy:read`
|
|
2414
|
+
|
|
2415
|
+
Returns the effective config (manifest defaults merged with overrides).
|
|
2416
|
+
|
|
2417
|
+
**Response:**
|
|
2418
|
+
```json
|
|
2419
|
+
{
|
|
2420
|
+
"success": true,
|
|
2421
|
+
"config": { "amount": "0.05", "interval": "daily" },
|
|
2422
|
+
"manifest": { "amount": "0.01", "interval": "daily" },
|
|
2423
|
+
"overrides": { "amount": "0.05" }
|
|
2424
|
+
}
|
|
2425
|
+
```
|
|
2426
|
+
|
|
2427
|
+
### Update Strategy Config
|
|
2428
|
+
|
|
2429
|
+
```http
|
|
2430
|
+
PUT /strategies/:id/config
|
|
2431
|
+
Authorization: Bearer <token>
|
|
2432
|
+
Content-Type: application/json
|
|
2433
|
+
|
|
2434
|
+
{
|
|
2435
|
+
"amount": "0.05"
|
|
2436
|
+
}
|
|
2437
|
+
```
|
|
2438
|
+
|
|
2439
|
+
Permission: `strategy:manage`
|
|
2440
|
+
|
|
2441
|
+
Sets config overrides. Request body is merged on top of manifest defaults.
|
|
2442
|
+
|
|
2443
|
+
**Response:**
|
|
2444
|
+
```json
|
|
2445
|
+
{
|
|
2446
|
+
"success": true,
|
|
2447
|
+
"config": { "amount": "0.05", "interval": "daily" }
|
|
2448
|
+
}
|
|
2449
|
+
```
|
|
2450
|
+
|
|
2451
|
+
### Approve/Reject Pending Intents
|
|
2452
|
+
|
|
2453
|
+
```http
|
|
2454
|
+
POST /strategies/:id/approve
|
|
2455
|
+
Authorization: Bearer <token>
|
|
2456
|
+
Content-Type: application/json
|
|
2457
|
+
|
|
2458
|
+
{
|
|
2459
|
+
"approvalId": "approval-123",
|
|
2460
|
+
"approved": true
|
|
2461
|
+
}
|
|
2462
|
+
```
|
|
2463
|
+
|
|
2464
|
+
Permission: `strategy:manage`
|
|
2465
|
+
|
|
2466
|
+
Resolves pending approval records (`strategy:approve` or `strategy:install:approve`). Set `approved` to `false` to reject.
|
|
2467
|
+
|
|
2468
|
+
### Get Strategy State (Debug)
|
|
2469
|
+
|
|
2470
|
+
```http
|
|
2471
|
+
GET /strategies/:id/state
|
|
2472
|
+
Authorization: Bearer <token>
|
|
2473
|
+
```
|
|
2474
|
+
|
|
2475
|
+
Permission: `strategy:read`
|
|
2476
|
+
|
|
2477
|
+
Returns internal strategy state and pending approvals for debugging.
|
|
2478
|
+
|
|
2479
|
+
**Response:**
|
|
2480
|
+
```json
|
|
2481
|
+
{
|
|
2482
|
+
"success": true,
|
|
2483
|
+
"state": { "lastPrice": "3200.50", "positions": [] },
|
|
2484
|
+
"pendingApprovals": []
|
|
2485
|
+
}
|
|
2486
|
+
```
|
|
2487
|
+
|
|
2488
|
+
### Strategy Action History
|
|
2489
|
+
|
|
2490
|
+
```http
|
|
2491
|
+
GET /strategies/history
|
|
2492
|
+
Authorization: Bearer <token>
|
|
2493
|
+
```
|
|
2494
|
+
|
|
2495
|
+
Permission: `strategy:read`
|
|
2496
|
+
|
|
2497
|
+
Query params:
|
|
2498
|
+
- `strategyId`: Filter by strategy ID
|
|
2499
|
+
- `limit`: Max results (default 50, max 250)
|
|
2500
|
+
- `offset`: Pagination offset
|
|
2501
|
+
|
|
2502
|
+
Returns strategy events from the Event table (all events with `strategy:*` type prefix).
|
|
2503
|
+
|
|
2504
|
+
### Reload Runtime Metadata
|
|
2505
|
+
|
|
2506
|
+
```http
|
|
2507
|
+
POST /strategies/reload
|
|
2508
|
+
Authorization: Bearer <token>
|
|
2509
|
+
```
|
|
2510
|
+
|
|
2511
|
+
Permission: `strategy:manage`
|
|
2512
|
+
|
|
2513
|
+
Returns runtime reload metadata. DB-backed strategy rows remain the source of truth.
|
|
2514
|
+
|
|
2515
|
+
---
|
|
2516
|
+
|
|
2517
|
+
## Error Responses
|
|
2518
|
+
|
|
2519
|
+
All endpoints return JSON with `success` field:
|
|
2520
|
+
|
|
2521
|
+
```json
|
|
2522
|
+
{
|
|
2523
|
+
"success": false,
|
|
2524
|
+
"error": "Error message here"
|
|
2525
|
+
}
|
|
2526
|
+
```
|
|
2527
|
+
|
|
2528
|
+
Common HTTP status codes:
|
|
2529
|
+
- `401` - Unauthorized (missing/invalid token)
|
|
2530
|
+
- `403` - Forbidden (vault locked, insufficient permissions)
|
|
2531
|
+
- `404` - Not found
|
|
2532
|
+
- `400` - Bad request (validation error)
|
|
2533
|
+
|
|
2534
|
+
---
|
|
2535
|
+
|
|
2536
|
+
## Frontend API Client
|
|
2537
|
+
|
|
2538
|
+
Use the unified `api` helper from `@/lib/api` for all frontend API calls:
|
|
2539
|
+
|
|
2540
|
+
```typescript
|
|
2541
|
+
import { api, Api } from '@/lib/api';
|
|
2542
|
+
|
|
2543
|
+
// Wallet operations (Express :4242)
|
|
2544
|
+
const wallets = await api.get(Api.Wallet, '/wallets');
|
|
2545
|
+
await api.post(Api.Wallet, '/send', { from, to, amount }); // amount in wei or lamports
|
|
2546
|
+
await api.post(Api.Wallet, '/swap', { from, token, direction, amount });
|
|
2547
|
+
|
|
2548
|
+
// Workspace operations (Next.js :4747)
|
|
2549
|
+
const workspaces = await api.get(Api.Workspace, '/workspace');
|
|
2550
|
+
await api.post(Api.Workspace, '/workspace', { name: 'My Workspace' });
|
|
2551
|
+
|
|
2552
|
+
// Events (Next.js :4747)
|
|
2553
|
+
const events = await api.get(Api.Events, '/events', { limit: 50, category: 'auth' });
|
|
2554
|
+
|
|
2555
|
+
// Agent dashboard (Next.js :4747)
|
|
2556
|
+
const dashboard = await api.get(Api.AgentDashboard, '/agent-requests');
|
|
2557
|
+
```
|
|
2558
|
+
|
|
2559
|
+
### Api Enum
|
|
2560
|
+
|
|
2561
|
+
| Target | Backend | Purpose |
|
|
2562
|
+
|--------|---------|---------|
|
|
2563
|
+
| `Api.Wallet` | Express `:4242` | Wallet operations, auth, agents, transactions |
|
|
2564
|
+
| `Api.Workspace` | Next.js `:4747/api` | Workspace CRUD, app management |
|
|
2565
|
+
| `Api.Events` | Next.js `:4747/api` | Event logs from database |
|
|
2566
|
+
| `Api.AgentDashboard` | Next.js `:4747/api` | Agent dashboard (requests + tokens) |
|
|
2567
|
+
|
|
2568
|
+
### Available Methods
|
|
2569
|
+
|
|
2570
|
+
- `api.get<T>(target, path, params?)` - GET request with optional query params
|
|
2571
|
+
- `api.post<T>(target, path, body?)` - POST request with optional body
|
|
2572
|
+
- `api.put<T>(target, path, body?)` - PUT request with optional body
|
|
2573
|
+
- `api.patch<T>(target, path, body?)` - PATCH request with optional body
|
|
2574
|
+
- `api.delete<T>(target, path)` - DELETE request
|
|
2575
|
+
|
|
2576
|
+
The helper automatically:
|
|
2577
|
+
- Adds Bearer token from sessionStorage
|
|
2578
|
+
- Constructs the correct base URL based on target
|
|
2579
|
+
- Parses JSON responses and handles errors
|
|
2580
|
+
|
|
2581
|
+
---
|
|
2582
|
+
|
|
2583
|
+
## Next.js API Endpoints
|
|
2584
|
+
|
|
2585
|
+
UI-specific endpoints on `:4747`:
|
|
2586
|
+
|
|
2587
|
+
### Workspace
|
|
2588
|
+
|
|
2589
|
+
| Method | Path | Description |
|
|
2590
|
+
|--------|------|-------------|
|
|
2591
|
+
| GET | `/api/workspace` | List all workspaces |
|
|
2592
|
+
| POST | `/api/workspace` | Create workspace |
|
|
2593
|
+
| GET | `/api/workspace/:id` | Get workspace by ID |
|
|
2594
|
+
| PUT | `/api/workspace/:id` | Update workspace |
|
|
2595
|
+
| DELETE | `/api/workspace/:id` | Delete workspace |
|
|
2596
|
+
| GET | `/api/workspace/:id/apps` | List apps in workspace |
|
|
2597
|
+
| POST | `/api/workspace/:id/apps` | Add app to workspace |
|
|
2598
|
+
| PATCH | `/api/workspace/:id/apps/:wid` | Update app |
|
|
2599
|
+
| DELETE | `/api/workspace/:id/apps/:wid` | Remove app |
|
|
2600
|
+
| GET | `/api/workspace/:id/export` | Export workspace config |
|
|
2601
|
+
| POST | `/api/workspace/import` | Import workspace config |
|
|
2602
|
+
| GET | `/api/workspace/config` | Get global app config (chain overrides) |
|
|
2603
|
+
| POST | `/api/workspace/config` | Update global app config |
|
|
2604
|
+
|
|
2605
|
+
#### App Config (`/api/workspace/config`)
|
|
2606
|
+
|
|
2607
|
+
Global application configuration including RPC chain overrides.
|
|
2608
|
+
|
|
2609
|
+
**GET** - Returns current config:
|
|
2610
|
+
```json
|
|
2611
|
+
{
|
|
2612
|
+
"success": true,
|
|
2613
|
+
"config": {
|
|
2614
|
+
"chainOverrides": {
|
|
2615
|
+
"base": { "rpc": "https://custom-rpc.com", "chainId": 8453, "explorer": "https://basescan.org" }
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
```
|
|
2620
|
+
|
|
2621
|
+
**POST** - Update chain overrides:
|
|
2622
|
+
```json
|
|
2623
|
+
{
|
|
2624
|
+
"chainOverrides": {
|
|
2625
|
+
"base": { "rpc": "https://custom-rpc.com", "chainId": 8453, "explorer": "https://basescan.org" },
|
|
2626
|
+
"zksync": { "rpc": "https://mainnet.era.zksync.io", "chainId": 324, "explorer": "https://explorer.zksync.io" }
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
```
|
|
2630
|
+
|
|
2631
|
+
RPC resolution order: Custom override > Alchemy key (if configured) > Public fallback.
|
|
2632
|
+
|
|
2633
|
+
### Events
|
|
2634
|
+
|
|
2635
|
+
| Method | Path | Description |
|
|
2636
|
+
|--------|------|-------------|
|
|
2637
|
+
| GET | `/api/events` | Query events from database |
|
|
2638
|
+
| POST | `/api/events` | Webhook for Express to broadcast events |
|
|
2639
|
+
|
|
2640
|
+
#### GET /api/events
|
|
2641
|
+
|
|
2642
|
+
Query parameters:
|
|
2643
|
+
- `type`: Filter by exact event type (e.g., `action:created`)
|
|
2644
|
+
- `category`: Filter by category prefix (e.g., `auth` matches `auth:*`)
|
|
2645
|
+
- `limit`: Max results (default 50, max 250)
|
|
2646
|
+
- `offset`: Pagination offset
|
|
2647
|
+
|
|
2648
|
+
Response:
|
|
2649
|
+
```json
|
|
2650
|
+
{
|
|
2651
|
+
"success": true,
|
|
2652
|
+
"events": [
|
|
2653
|
+
{
|
|
2654
|
+
"id": "cuid123",
|
|
2655
|
+
"type": "auth:unlocked",
|
|
2656
|
+
"source": "express",
|
|
2657
|
+
"data": { "description": "Wallet unlocked: 0x123..." },
|
|
2658
|
+
"timestamp": "2024-02-01T12:00:00.000Z"
|
|
2659
|
+
}
|
|
2660
|
+
],
|
|
2661
|
+
"pagination": {
|
|
2662
|
+
"total": 100,
|
|
2663
|
+
"limit": 50,
|
|
2664
|
+
"offset": 0,
|
|
2665
|
+
"hasMore": true
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
```
|
|
2669
|
+
|
|
2670
|
+
### Agent Keys
|
|
2671
|
+
|
|
2672
|
+
| Method | Path | Description |
|
|
2673
|
+
|--------|------|-------------|
|
|
2674
|
+
| GET | `/api/agent-requests` | Get pending actions and tokens |
|
|
2675
|
+
|
|
2676
|
+
Proxies to Express `/dashboard` endpoint. Returns:
|
|
2677
|
+
- Pending approval requests
|
|
2678
|
+
- Active tokens (including admin tokens with `isAdmin: true`)
|
|
2679
|
+
- Inactive tokens (expired, revoked, or depleted)
|