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