ethagent 3.3.4 → 4.0.0
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/.claude-plugin/marketplace.json +11 -0
- package/.claude-plugin/plugin.json +35 -0
- package/LICENSE +1 -1
- package/README.md +64 -104
- package/commands/ethagent.md +40 -0
- package/package.json +16 -16
- package/src/app/keybindings/KeybindingProvider.tsx +1 -6
- package/src/app/keybindings/types.ts +1 -6
- package/src/cli/ResetConfirmView.tsx +54 -53
- package/src/cli/demo.ts +86 -0
- package/src/cli/hookIo.ts +45 -0
- package/src/cli/main.tsx +94 -123
- package/src/cli/memoryGuard.ts +49 -0
- package/src/cli/reset.ts +28 -70
- package/src/cli/sessionStart.ts +33 -0
- package/src/cli/status.ts +46 -0
- package/src/cli/sync.ts +167 -0
- package/src/cli/syncAdapters/claude-code.ts +86 -0
- package/src/cli/syncAdapters/codex.ts +66 -0
- package/src/cli/syncAdapters/index.ts +45 -0
- package/src/cli/syncAdapters/managedBlock.ts +175 -0
- package/src/cli/syncAdapters/shared.ts +63 -0
- package/src/identity/continuity/envelopeParse.ts +20 -1
- package/src/identity/continuity/publicSkills.ts +3 -1
- package/src/identity/continuity/skills/publicSkillsSync.ts +2 -1
- package/src/identity/continuity/skills/scaffold.ts +5 -2
- package/src/identity/continuity/snapshots.ts +12 -5
- package/src/identity/continuity/storage/defaults.ts +20 -19
- package/src/identity/continuity/storage/status.ts +1 -1
- package/src/identity/ens/ensLookup/constants.ts +1 -1
- package/src/identity/manager/IdentityManager.tsx +33 -0
- package/src/identity/{hub → manager}/OperationalRoutes.tsx +37 -18
- package/src/identity/{hub → manager}/Routes.tsx +48 -34
- package/src/identity/{hub → manager}/continuity/ContinuityDashboardScreen.tsx +9 -19
- package/src/identity/{hub → manager}/continuity/RebackupStorageScreen.tsx +3 -3
- package/src/identity/manager/continuity/RecoveryConfirmScreen.tsx +102 -0
- package/src/identity/{hub → manager}/continuity/SavePromptScreen.tsx +2 -3
- package/src/identity/{hub → manager}/continuity/completion.ts +1 -1
- package/src/identity/{hub → manager}/continuity/effects.ts +1 -1
- package/src/identity/{hub → manager}/continuity/skills/DeleteSkillConfirmScreen.tsx +2 -2
- package/src/identity/{hub → manager}/continuity/skills/NewSkillScreen.tsx +0 -5
- package/src/identity/{hub → manager}/continuity/skills/NewSkillVisibilityScreen.tsx +4 -4
- package/src/identity/{hub → manager}/continuity/skills/SkillActionsScreen.tsx +6 -22
- package/src/identity/{hub → manager}/continuity/skills/SkillsTreeScreen.tsx +5 -17
- package/src/identity/{hub → manager}/continuity/snapshot.ts +1 -1
- package/src/identity/{hub → manager}/continuity/vault.ts +1 -1
- package/src/identity/{hub → manager}/create/CreateFlow.tsx +59 -32
- package/src/identity/{hub → manager}/create/effects.ts +19 -10
- package/src/identity/manager/create/importScan.ts +122 -0
- package/src/identity/{hub → manager}/custody/CustodyEditFlow.tsx +17 -61
- package/src/identity/{hub → manager}/custody/actions.ts +1 -15
- package/src/identity/{hub → manager}/custody/routes.tsx +20 -40
- package/src/identity/{hub → manager}/custody/transactions.ts +1 -0
- package/src/identity/{hub → manager}/custody/types.ts +1 -2
- package/src/identity/{hub → manager}/custody/useCustodyEffects.ts +1 -1
- package/src/identity/{hub → manager}/ens/EnsEditAdvancedScreens.tsx +2 -2
- package/src/identity/{hub → manager}/ens/EnsEditMaintenanceScreens.tsx +12 -23
- package/src/identity/{hub → manager}/ens/EnsEditReviewScreens.tsx +18 -42
- package/src/identity/{hub → manager}/ens/EnsEditRunners.tsx +1 -1
- package/src/identity/{hub → manager}/ens/EnsEditShared.tsx +0 -2
- package/src/identity/{hub → manager}/ens/EnsEditSimpleScreens.tsx +10 -19
- package/src/identity/{hub → manager}/ens/EnsFlow.tsx +133 -41
- package/src/identity/{hub → manager}/ens/EnsOperatorWalletsScreen.tsx +14 -19
- package/src/identity/{hub → manager}/ens/editCopy.ts +1 -14
- package/src/identity/{hub → manager}/profile/EditProfileFlow.tsx +99 -66
- package/src/identity/{hub → manager}/profile/effects.ts +1 -3
- package/src/identity/{hub → manager}/profile/operatorSave.ts +1 -1
- package/src/identity/{hub → manager}/profile/state.ts +1 -1
- package/src/identity/{hub/identityHubReducer.ts → manager/reducer.ts} +25 -26
- package/src/identity/{hub → manager}/restore/RestoreFlow.tsx +16 -24
- package/src/identity/{hub → manager}/restore/apply.ts +1 -1
- package/src/identity/{hub → manager}/restore/auth.ts +1 -1
- package/src/identity/{hub → manager}/restore/discover.ts +1 -1
- package/src/identity/{hub → manager}/restore/fetch.ts +1 -1
- package/src/identity/{hub → manager}/restore/restoreAdmin.ts +1 -1
- package/src/identity/{hub → manager}/restore/useRestoreEffects.ts +2 -9
- package/src/identity/{hub → manager}/settings/StorageCredentialScreen.tsx +10 -25
- package/src/identity/{hub → manager}/shared/components/DetailsScreen.tsx +5 -7
- package/src/identity/{hub → manager}/shared/components/ErrorScreen.tsx +6 -10
- package/src/identity/{hub → manager}/shared/components/FlowTimeline.tsx +4 -3
- package/src/identity/{hub → manager}/shared/components/IdentitySummary.tsx +19 -59
- package/src/identity/manager/shared/components/LazyMenu.tsx +147 -0
- package/src/identity/manager/shared/components/MenuScreen.tsx +220 -0
- package/src/identity/manager/shared/components/OperationCompleteScreen.tsx +28 -0
- package/src/identity/{hub → manager}/shared/components/UnlinkedIdentityScreen.tsx +9 -10
- package/src/identity/{hub → manager}/shared/components/WalletApprovalScreen.tsx +1 -2
- package/src/identity/manager/shared/components/Wordmark.tsx +54 -0
- package/src/identity/{hub → manager}/shared/components/menuFlagsFromReconciliation.ts +39 -15
- package/src/identity/{hub → manager}/shared/effects/profilePrep.ts +1 -1
- package/src/identity/manager/shared/effects/types.ts +30 -0
- package/src/identity/{hub → manager}/shared/model/copy.ts +0 -4
- package/src/identity/{hub → manager}/shared/model/errors.ts +32 -3
- package/src/identity/{hub → manager}/shared/model/network.ts +2 -2
- package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/hook.ts +5 -0
- package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/run.ts +1 -1
- package/src/identity/{hub/shared/reconciliation/useAgentReconciliation.ts → manager/shared/reconciliation/index.ts} +6 -0
- package/src/identity/{hub → manager}/shared/utils.ts +6 -10
- package/src/identity/{hub → manager}/transfer/TokenTransferFlow.tsx +3 -3
- package/src/identity/{hub → manager}/transfer/TokenTransferScreens.tsx +4 -10
- package/src/identity/{hub → manager}/transfer/effects.ts +1 -1
- package/src/identity/{hub → manager}/types.ts +5 -6
- package/src/identity/{hub/useIdentityHubContinuity.ts → manager/useContinuity.ts} +59 -27
- package/src/identity/{hub/useIdentityHubController.ts → manager/useController.ts} +38 -35
- package/src/identity/{hub/useIdentityHubSideEffects.ts → manager/useSideEffects.ts} +40 -4
- package/src/identity/registry/erc8004/discovery.ts +3 -17
- package/src/identity/registry/erc8004/utils.ts +1 -1
- package/src/identity/storage/ipfs.ts +21 -1
- package/src/identity/wallet/browserWallet/html.ts +10 -2
- package/src/identity/wallet/browserWallet/http.ts +18 -0
- package/src/identity/wallet/browserWallet/requestServer.ts +5 -1
- package/src/identity/wallet/browserWallet/requests.ts +10 -28
- package/src/identity/wallet/browserWallet/session.ts +26 -33
- package/src/identity/wallet/browserWallet/validation.ts +14 -0
- package/src/identity/wallet/browserWallet/walletPageSource.ts +22 -40
- package/src/identity/wallet/page/boot.ts +43 -0
- package/src/identity/wallet/page/config.ts +59 -0
- package/src/identity/wallet/page/constants.ts +12 -0
- package/src/identity/wallet/page/copy.ts +47 -68
- package/src/identity/wallet/page/css.ts +638 -0
- package/src/identity/wallet/page/{errorView.ts → errors.ts} +5 -14
- package/src/identity/wallet/page/{controller.ts → flow.ts} +4 -71
- package/src/identity/wallet/page/markup.ts +44 -34
- package/src/identity/wallet/page/{walletProvider.ts → provider.ts} +0 -3
- package/src/identity/wallet/page/resize.ts +95 -0
- package/src/identity/wallet/page/state.ts +135 -8
- package/src/identity/wallet/page/timeline.ts +161 -0
- package/src/identity/wallet/page/view.ts +22 -302
- package/src/storage/config.ts +30 -80
- package/src/storage/reset.ts +31 -0
- package/src/storage/secrets.ts +1 -16
- package/src/ui/Select.tsx +27 -5
- package/src/ui/Spinner.tsx +16 -15
- package/src/ui/Surface.tsx +21 -17
- package/src/ui/TextArea.tsx +173 -0
- package/src/ui/TextInput.tsx +31 -133
- package/src/ui/theme.ts +22 -13
- package/src/utils/clipboard.ts +0 -140
- package/src/app/FirstRun.tsx +0 -577
- package/src/app/FirstRunTimeline.tsx +0 -51
- package/src/app/firstRunConfig.ts +0 -26
- package/src/app/hooks/useCancelRequest.ts +0 -22
- package/src/app/hooks/useDoublePress.ts +0 -46
- package/src/app/hooks/useExitOnCtrlC.ts +0 -36
- package/src/auth/openaiOAuth/credentials.ts +0 -47
- package/src/auth/openaiOAuth/crypto.ts +0 -23
- package/src/auth/openaiOAuth/index.ts +0 -238
- package/src/auth/openaiOAuth/landingPage.ts +0 -116
- package/src/auth/openaiOAuth/listener.ts +0 -151
- package/src/auth/openaiOAuth/refresh.ts +0 -70
- package/src/auth/openaiOAuth/shared.ts +0 -115
- package/src/chat/ChatBottomPane.tsx +0 -296
- package/src/chat/ChatScreen.tsx +0 -1685
- package/src/chat/ConversationStack.tsx +0 -56
- package/src/chat/MessageList.tsx +0 -638
- package/src/chat/SessionStatus.tsx +0 -53
- package/src/chat/chatEnvironment.ts +0 -16
- package/src/chat/chatScreenUtils.ts +0 -194
- package/src/chat/chatSessionState.ts +0 -146
- package/src/chat/chatTurnContext.ts +0 -50
- package/src/chat/chatTurnOrchestrator.ts +0 -603
- package/src/chat/chatTurnRows.ts +0 -64
- package/src/chat/commands.ts +0 -494
- package/src/chat/continuityEditReview.ts +0 -42
- package/src/chat/display/DiffView.tsx +0 -193
- package/src/chat/display/SyntaxText.tsx +0 -192
- package/src/chat/display/toolCallDisplay.ts +0 -103
- package/src/chat/display/toolResultDisplay.ts +0 -19
- package/src/chat/input/ChatInput.tsx +0 -625
- package/src/chat/input/chatInputHelpers.ts +0 -62
- package/src/chat/input/chatInputState.ts +0 -247
- package/src/chat/input/chatPaste.ts +0 -49
- package/src/chat/input/imageRefs.ts +0 -30
- package/src/chat/input/inputRendering.tsx +0 -93
- package/src/chat/input/textCursor.ts +0 -212
- package/src/chat/messageMarkdown.ts +0 -220
- package/src/chat/messageRows.ts +0 -43
- package/src/chat/planImplementation.ts +0 -62
- package/src/chat/slashCommandHandlers.ts +0 -122
- package/src/chat/slashCommandViews.ts +0 -120
- package/src/chat/transcript/TranscriptView.tsx +0 -184
- package/src/chat/transcript/transcriptViewport.ts +0 -295
- package/src/chat/views/ContextLimitView.tsx +0 -95
- package/src/chat/views/ContinuityEditReviewView.tsx +0 -50
- package/src/chat/views/CopyPicker.tsx +0 -50
- package/src/chat/views/PermissionPrompt.tsx +0 -156
- package/src/chat/views/PermissionsView.tsx +0 -165
- package/src/chat/views/PlanApprovalView.tsx +0 -91
- package/src/chat/views/ResumeView.tsx +0 -273
- package/src/chat/views/RewindView.tsx +0 -412
- package/src/cli/preview.tsx +0 -14
- package/src/cli/updateNotice.ts +0 -54
- package/src/identity/continuity/privateEdit/apply.ts +0 -170
- package/src/identity/continuity/privateEdit/diff.ts +0 -6
- package/src/identity/continuity/privateEdit/files.ts +0 -23
- package/src/identity/continuity/privateEdit/types.ts +0 -28
- package/src/identity/continuity/privateEdit.ts +0 -46
- package/src/identity/hub/IdentityHub.tsx +0 -14
- package/src/identity/hub/continuity/RecoveryConfirmScreen.tsx +0 -104
- package/src/identity/hub/ens/effects.ts +0 -218
- package/src/identity/hub/shared/components/MenuScreen.tsx +0 -241
- package/src/identity/hub/shared/effects/types.ts +0 -53
- package/src/identity/hub/shared/reconciliation/index.ts +0 -14
- package/src/identity/wallet/page/grainient.ts +0 -278
- package/src/identity/wallet/page/html.ts +0 -28
- package/src/identity/wallet/page/styles/base.ts +0 -260
- package/src/identity/wallet/page/styles/components.ts +0 -262
- package/src/identity/wallet/page/styles/index.ts +0 -5
- package/src/identity/wallet/page/styles/responsive.ts +0 -247
- package/src/identity/wallet/page.tsx +0 -38
- package/src/mcp/approvals.ts +0 -113
- package/src/mcp/config.ts +0 -235
- package/src/mcp/manager.ts +0 -482
- package/src/mcp/managerHelpers.ts +0 -70
- package/src/mcp/names.ts +0 -19
- package/src/mcp/output.ts +0 -96
- package/src/models/ModelPicker.tsx +0 -1009
- package/src/models/catalog.ts +0 -327
- package/src/models/huggingface.ts +0 -712
- package/src/models/huggingfaceStorage.ts +0 -136
- package/src/models/llamacpp.ts +0 -848
- package/src/models/llamacppCommands.ts +0 -44
- package/src/models/llamacppConfig.ts +0 -34
- package/src/models/llamacppDiscovery.ts +0 -176
- package/src/models/llamacppOutput.ts +0 -65
- package/src/models/llamacppPreflight.ts +0 -158
- package/src/models/modelDisplay.ts +0 -180
- package/src/models/modelPickerCatalogFlow.ts +0 -56
- package/src/models/modelPickerCredentials.ts +0 -166
- package/src/models/modelPickerData.ts +0 -41
- package/src/models/modelPickerDisplay.tsx +0 -132
- package/src/models/modelPickerHfFlow.ts +0 -192
- package/src/models/modelPickerLocalRunnerFlow.ts +0 -115
- package/src/models/modelPickerOptions.ts +0 -457
- package/src/models/modelPickerTypes.ts +0 -69
- package/src/models/modelPickerUninstallFlow.ts +0 -48
- package/src/models/modelPickerViewHelpers.ts +0 -174
- package/src/models/modelRecommendation.ts +0 -139
- package/src/models/providerDisplay.ts +0 -16
- package/src/models/runtimeDetection.ts +0 -81
- package/src/models/uncensoredCatalog.ts +0 -86
- package/src/providers/anthropic.ts +0 -290
- package/src/providers/contracts.ts +0 -71
- package/src/providers/errors.ts +0 -80
- package/src/providers/gemini.ts +0 -391
- package/src/providers/openai-chat.ts +0 -474
- package/src/providers/openai-responses-format.ts +0 -177
- package/src/providers/openai-responses.ts +0 -306
- package/src/providers/openaiChatWire.ts +0 -124
- package/src/providers/registry.ts +0 -120
- package/src/providers/retry.ts +0 -58
- package/src/providers/sse.ts +0 -93
- package/src/runtime/compaction.ts +0 -395
- package/src/runtime/cwd.ts +0 -43
- package/src/runtime/providerTurn.ts +0 -38
- package/src/runtime/sessionMode.ts +0 -55
- package/src/runtime/systemPrompt.ts +0 -213
- package/src/runtime/textToolParser.ts +0 -161
- package/src/runtime/toolClaimGuards.ts +0 -143
- package/src/runtime/toolExecution.ts +0 -304
- package/src/runtime/toolIntent.ts +0 -143
- package/src/runtime/turn.ts +0 -369
- package/src/runtime/turnNudges.ts +0 -223
- package/src/runtime/turnTypes.ts +0 -86
- package/src/storage/factoryReset.ts +0 -127
- package/src/storage/history.ts +0 -58
- package/src/storage/permissions.ts +0 -76
- package/src/storage/rewind.ts +0 -266
- package/src/storage/sessionExport.ts +0 -49
- package/src/storage/sessions.ts +0 -495
- package/src/tools/bashSafety.ts +0 -186
- package/src/tools/bashTool.ts +0 -140
- package/src/tools/changeDirectoryTool.ts +0 -213
- package/src/tools/contracts.ts +0 -192
- package/src/tools/deleteFileTool.ts +0 -116
- package/src/tools/editTool.ts +0 -165
- package/src/tools/editUtils.ts +0 -170
- package/src/tools/fileDiff.ts +0 -261
- package/src/tools/listDirectoryTool.ts +0 -55
- package/src/tools/listSkillFilesTool.ts +0 -77
- package/src/tools/listSkillsTool.ts +0 -68
- package/src/tools/mcpResourceTools.ts +0 -95
- package/src/tools/permissionRules.ts +0 -85
- package/src/tools/privateContinuityEditTool.ts +0 -187
- package/src/tools/privateContinuityReadTool.ts +0 -106
- package/src/tools/readSkillTool.ts +0 -107
- package/src/tools/readTool.ts +0 -85
- package/src/tools/registry.ts +0 -103
- package/src/tools/writeFileTool.ts +0 -167
- package/src/ui/BrandSplash.tsx +0 -133
- package/src/ui/terminalTitle.ts +0 -30
- package/src/utils/images.ts +0 -140
- package/src/utils/markdownSegments.ts +0 -51
- package/src/utils/messages.ts +0 -37
- package/src/utils/withRetry.ts +0 -324
- /package/src/identity/{hub → manager}/continuity/state.ts +0 -0
- /package/src/identity/{hub → manager}/custody/helpers.ts +0 -0
- /package/src/identity/{hub → manager}/custody/preflight.ts +0 -0
- /package/src/identity/{hub → manager}/custody/state.ts +0 -0
- /package/src/identity/{hub → manager}/custody/useCustodyFlow.tsx +0 -0
- /package/src/identity/{hub → manager}/ens/EnsEditFlow.tsx +0 -0
- /package/src/identity/{hub → manager}/ens/advancedEnsValidation.ts +0 -0
- /package/src/identity/{hub → manager}/ens/state.ts +0 -0
- /package/src/identity/{hub → manager}/ens/transactions.ts +0 -0
- /package/src/identity/{hub → manager}/ens/types.ts +0 -0
- /package/src/identity/{hub → manager}/profile/identity.ts +0 -0
- /package/src/identity/{hub → manager}/restore/envelopes.ts +0 -0
- /package/src/identity/{hub → manager}/restore/helpers.ts +0 -0
- /package/src/identity/{hub → manager}/restore/recovery.ts +0 -0
- /package/src/identity/{hub → manager}/restore/resolve.ts +0 -0
- /package/src/identity/{hub → manager}/shared/components/BusyScreen.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/components/NetworkScreen.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/components/PinataJwtInput.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/effects/receipts.ts +0 -0
- /package/src/identity/{hub → manager}/shared/effects/sync.ts +0 -0
- /package/src/identity/{hub → manager}/shared/model/format.ts +0 -0
- /package/src/identity/{hub → manager}/shared/operatorWallets.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/ownership.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/types.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/walletSetup.ts +0 -0
- /package/src/identity/{hub → manager}/shared/txGuard.ts +0 -0
- /package/src/identity/{hub → manager}/transfer/progress.ts +0 -0
- /package/src/identity/{hub → manager}/transfer/state.ts +0 -0
|
@@ -36,7 +36,8 @@ import {
|
|
|
36
36
|
requestBrowserWalletSignatureAndTransaction,
|
|
37
37
|
} from '../../wallet/browserWallet.js'
|
|
38
38
|
import { initialAgentState, PREFLIGHT_AGENT_URI } from '../profile/identity.js'
|
|
39
|
-
import
|
|
39
|
+
import { mergeImportedNotes } from './importScan.js'
|
|
40
|
+
import type { Step } from '../reducer.js'
|
|
40
41
|
import type { EffectCallbacks } from '../shared/effects/types.js'
|
|
41
42
|
import { awaitConfirmedReceipt } from '../shared/effects/receipts.js'
|
|
42
43
|
import { assertVerifiedPin } from '../shared/effects/profilePrep.js'
|
|
@@ -63,8 +64,9 @@ export async function runCreatePreflight(
|
|
|
63
64
|
const resolution = step.network
|
|
64
65
|
? registryResolutionForNetwork(step.network)
|
|
65
66
|
: registryConfigFromConfig(config)
|
|
67
|
+
const carryNotes = step.importNotes ? { importNotes: step.importNotes } : {}
|
|
66
68
|
if (!resolution.config) {
|
|
67
|
-
callbacks.onStep({ kind: 'create-registry', name: step.name, description: step.description, resolution, custodyMode: step.custodyMode })
|
|
69
|
+
callbacks.onStep({ kind: 'create-registry', name: step.name, description: step.description, resolution, custodyMode: step.custodyMode, ...carryNotes })
|
|
68
70
|
return
|
|
69
71
|
}
|
|
70
72
|
const apiUrl = DEFAULT_IPFS_API_URL
|
|
@@ -79,14 +81,15 @@ export async function runCreatePreflight(
|
|
|
79
81
|
registry: resolution.config,
|
|
80
82
|
custodyMode: step.custodyMode,
|
|
81
83
|
error: (err as Error).message,
|
|
84
|
+
...carryNotes,
|
|
82
85
|
})
|
|
83
86
|
return
|
|
84
87
|
}
|
|
85
88
|
if (isPinataUploadUrl(apiUrl) && !jwt) {
|
|
86
|
-
callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode })
|
|
89
|
+
callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode, ...carryNotes })
|
|
87
90
|
return
|
|
88
91
|
}
|
|
89
|
-
callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode, pinataJwt: jwt })
|
|
92
|
+
callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode, pinataJwt: jwt, ...carryNotes })
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
function registryResolutionForNetwork(network: SelectableNetwork): RegistryResolution {
|
|
@@ -136,7 +139,9 @@ export async function runCreateSigning(
|
|
|
136
139
|
registry: step.registry,
|
|
137
140
|
state,
|
|
138
141
|
})
|
|
139
|
-
const continuityFiles =
|
|
142
|
+
const continuityFiles = step.importNotes?.length
|
|
143
|
+
? mergeImportedNotes(defaultContinuityFiles(draftIdentity), step.importNotes)
|
|
144
|
+
: defaultContinuityFiles(draftIdentity)
|
|
140
145
|
const publicProfile = defaultPublicSkillsProfile(draftIdentity)
|
|
141
146
|
const agentCardJson = serializeAgentCard(createAgentCard(publicProfile))
|
|
142
147
|
const agentCardPin = await addToIpfs(DEFAULT_IPFS_API_URL, agentCardJson, fetch, { pinataJwt: step.pinataJwt })
|
|
@@ -231,8 +236,11 @@ export async function runCreateSigning(
|
|
|
231
236
|
backup,
|
|
232
237
|
agentCard: result.prepared.agentCard,
|
|
233
238
|
}
|
|
239
|
+
const finalContinuityFiles = step.importNotes?.length
|
|
240
|
+
? mergeImportedNotes(defaultContinuityFiles(nextIdentity), step.importNotes)
|
|
241
|
+
: defaultContinuityFiles(nextIdentity)
|
|
234
242
|
await writeIdentityMarkdownScaffold(nextIdentity, {
|
|
235
|
-
...
|
|
243
|
+
...finalContinuityFiles,
|
|
236
244
|
'agent-card.json': result.prepared.agentCardJson,
|
|
237
245
|
})
|
|
238
246
|
await recordPublishedContinuitySnapshot({ identity: nextIdentity, label: 'initial published snapshot' }).catch(() => null)
|
|
@@ -264,18 +272,19 @@ export async function runRegistrySubmit(
|
|
|
264
272
|
onConfigChange(next)
|
|
265
273
|
}
|
|
266
274
|
const apiUrl = DEFAULT_IPFS_API_URL
|
|
275
|
+
const carryNotes = step.importNotes ? { importNotes: step.importNotes } : {}
|
|
267
276
|
let jwt: string | undefined
|
|
268
277
|
try {
|
|
269
278
|
jwt = isPinataUploadUrl(apiUrl) ? await resolveValidatedPinataJwt() : undefined
|
|
270
279
|
} catch (err: unknown) {
|
|
271
|
-
callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, error: (err as Error).message })
|
|
280
|
+
callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, error: (err as Error).message, ...carryNotes })
|
|
272
281
|
return
|
|
273
282
|
}
|
|
274
283
|
if (isPinataUploadUrl(apiUrl) && !jwt) {
|
|
275
|
-
callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode })
|
|
284
|
+
callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, ...carryNotes })
|
|
276
285
|
return
|
|
277
286
|
}
|
|
278
|
-
callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, pinataJwt: jwt })
|
|
287
|
+
callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, pinataJwt: jwt, ...carryNotes })
|
|
279
288
|
}
|
|
280
289
|
|
|
281
290
|
export async function runStorageSubmit(
|
|
@@ -284,7 +293,7 @@ export async function runStorageSubmit(
|
|
|
284
293
|
callbacks: EffectCallbacks,
|
|
285
294
|
): Promise<void> {
|
|
286
295
|
const { jwt: pinataJwt } = await savePinataJwt(input)
|
|
287
|
-
callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: step.registry, custodyMode: step.custodyMode, pinataJwt })
|
|
296
|
+
callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: step.registry, custodyMode: step.custodyMode, pinataJwt, ...(step.importNotes ? { importNotes: step.importNotes } : {}) })
|
|
288
297
|
}
|
|
289
298
|
|
|
290
299
|
function identityDraftForBackup(args: {
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import type { EthagentIdentity } from '../../../storage/config.js'
|
|
4
|
+
import type { ContinuityFiles } from '../../continuity/envelope.js'
|
|
5
|
+
import { defaultContinuityFiles } from '../../continuity/storage.js'
|
|
6
|
+
import { extractOutsideManaged } from '../../../cli/syncAdapters/managedBlock.js'
|
|
7
|
+
import { BUILT_IN_ADAPTERS } from '../../../cli/syncAdapters/index.js'
|
|
8
|
+
|
|
9
|
+
export type ImportCandidate = {
|
|
10
|
+
source: string
|
|
11
|
+
raw: string
|
|
12
|
+
contentLines: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const MIN_SUBSTANTIVE_CHARS = 120
|
|
16
|
+
const MIN_CONTENT_LINES = 5
|
|
17
|
+
|
|
18
|
+
function stripIdentityBlocks(text: string): string {
|
|
19
|
+
return text.replace(/<!--\s*ethagent:identity:start\s*-->[\s\S]*?<!--\s*ethagent:identity:end\s*-->/g, '')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function substantiveLines(text: string): string[] {
|
|
23
|
+
return stripIdentityBlocks(text)
|
|
24
|
+
.split('\n')
|
|
25
|
+
.map(line => line.trim())
|
|
26
|
+
.filter(line => line.length > 0)
|
|
27
|
+
.filter(line => !line.startsWith('#'))
|
|
28
|
+
.filter(line => !(line.startsWith('<!--') && line.endsWith('-->')))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const LEGACY_SCAFFOLD_LINES = [
|
|
32
|
+
'The standing voice, collaboration style, and behavior this agent keeps across sessions and models.',
|
|
33
|
+
'- Voice: <e.g., direct, concise, no filler>',
|
|
34
|
+
'- Tone: <e.g., warm but professional>',
|
|
35
|
+
'- Communication style: <e.g., bullet lists for technical work, prose for narrative>',
|
|
36
|
+
'Owner-approved working principles. Decisions that should be made the same way every time.',
|
|
37
|
+
'- <principle: e.g., always confirm before destructive operations>',
|
|
38
|
+
'- <principle: e.g., bias toward editing existing code over creating new files>',
|
|
39
|
+
'- <principle: e.g., never hide errors, always surface them clearly>',
|
|
40
|
+
'What this agent must never do, regardless of how it is asked.',
|
|
41
|
+
'- <boundary: e.g., never bypass authentication or authorization checks>',
|
|
42
|
+
'- <boundary: e.g., never commit secrets to source control>',
|
|
43
|
+
'Long-lived owner preferences that survive sessions and model switches. Capture how the user works.',
|
|
44
|
+
'- Communication: <e.g., prefers concise summaries over walls of text>',
|
|
45
|
+
'- Tooling: <e.g., VS Code, zsh, TypeScript over JavaScript>',
|
|
46
|
+
'- Workflow: <e.g., reviews PRs in the morning, deploys on Fridays>',
|
|
47
|
+
'- Repository: <url or local path>',
|
|
48
|
+
'- Stack: <languages, frameworks, key libraries>',
|
|
49
|
+
'- Conventions: <e.g., conventional commits, semver, branch naming>',
|
|
50
|
+
'- Active workstream: <YYYY-MM-DD what you are focused on>',
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
const SCAFFOLD_LINES: Set<string> = (() => {
|
|
54
|
+
const scaffold = defaultContinuityFiles({
|
|
55
|
+
source: 'erc8004',
|
|
56
|
+
address: '0x0000000000000000000000000000000000000000',
|
|
57
|
+
} as EthagentIdentity)
|
|
58
|
+
return new Set([
|
|
59
|
+
...substantiveLines(scaffold['SOUL.md']),
|
|
60
|
+
...substantiveLines(scaffold['MEMORY.md']),
|
|
61
|
+
...LEGACY_SCAFFOLD_LINES,
|
|
62
|
+
])
|
|
63
|
+
})()
|
|
64
|
+
|
|
65
|
+
function localOnlyLines(text: string): string[] {
|
|
66
|
+
return substantiveLines(text).filter(line => !SCAFFOLD_LINES.has(line))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function isValuableImport(text: string): boolean {
|
|
70
|
+
const lines = localOnlyLines(text)
|
|
71
|
+
if (lines.length === 0) return false
|
|
72
|
+
const chars = lines.join('').replace(/\s/g, '').length
|
|
73
|
+
return chars >= MIN_SUBSTANTIVE_CHARS || lines.length >= MIN_CONTENT_LINES
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function scanImportCandidates(): Promise<ImportCandidate[]> {
|
|
77
|
+
const out: ImportCandidate[] = []
|
|
78
|
+
for (const adapter of BUILT_IN_ADAPTERS) {
|
|
79
|
+
if (!adapter.managedFilePaths) continue
|
|
80
|
+
const detected = await adapter.detect().catch(() => false)
|
|
81
|
+
if (!detected) continue
|
|
82
|
+
const filePath = adapter.managedFilePaths()[0]
|
|
83
|
+
if (!filePath) continue
|
|
84
|
+
let content: string
|
|
85
|
+
try {
|
|
86
|
+
content = await fs.readFile(filePath, 'utf8')
|
|
87
|
+
} catch {
|
|
88
|
+
continue
|
|
89
|
+
}
|
|
90
|
+
const outside = extractOutsideManaged(content)
|
|
91
|
+
if (!isValuableImport(outside)) continue
|
|
92
|
+
out.push({
|
|
93
|
+
source: path.basename(filePath),
|
|
94
|
+
raw: outside.trim(),
|
|
95
|
+
contentLines: localOnlyLines(outside).length,
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
return out
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function mergeImportedNotes(
|
|
102
|
+
base: ContinuityFiles,
|
|
103
|
+
candidates: ImportCandidate[],
|
|
104
|
+
now = new Date(),
|
|
105
|
+
): ContinuityFiles {
|
|
106
|
+
if (candidates.length === 0) return base
|
|
107
|
+
const dateStr = now.toISOString().slice(0, 10)
|
|
108
|
+
const sources = candidates.map(candidate => candidate.source).join(', ')
|
|
109
|
+
const lines: string[] = [
|
|
110
|
+
`## Imported from ${sources} (${dateStr})`,
|
|
111
|
+
'',
|
|
112
|
+
'Captured from your existing assistant notes at mint time. Reorganize into the sections above as you like.',
|
|
113
|
+
'',
|
|
114
|
+
]
|
|
115
|
+
for (const candidate of candidates) {
|
|
116
|
+
if (candidates.length > 1) lines.push(`### ${candidate.source}`, '')
|
|
117
|
+
lines.push(candidate.raw, '')
|
|
118
|
+
}
|
|
119
|
+
const importedSection = lines.join('\n').trim()
|
|
120
|
+
const memory = `${base['MEMORY.md'].replace(/\n+$/, '')}\n\n${importedSection}\n`
|
|
121
|
+
return { 'SOUL.md': base['SOUL.md'], 'MEMORY.md': memory }
|
|
122
|
+
}
|
|
@@ -4,7 +4,7 @@ import { Box, Text } from 'ink'
|
|
|
4
4
|
import { Surface } from '../../../ui/Surface.js'
|
|
5
5
|
import { Select } from '../../../ui/Select.js'
|
|
6
6
|
import { theme } from '../../../ui/theme.js'
|
|
7
|
-
import type { ProfileUpdates, Step } from '../
|
|
7
|
+
import type { ProfileUpdates, Step } from '../reducer.js'
|
|
8
8
|
import {
|
|
9
9
|
displayCustodyMode,
|
|
10
10
|
identityOwnerAddress,
|
|
@@ -29,8 +29,6 @@ interface CustodyEditFlowProps {
|
|
|
29
29
|
onSetStep: (step: Step) => void
|
|
30
30
|
onSwitchToAdvanced: (returnTo: Step, profileUpdates: ProfileUpdates) => void
|
|
31
31
|
onSwitchToSimple: (returnTo: Step, profileUpdates: ProfileUpdates) => void
|
|
32
|
-
onWithdrawToken: (returnTo: Step) => void
|
|
33
|
-
onReturnToVault: (returnTo: Step, vaultAddress: Address) => void
|
|
34
32
|
onResumeAdvanced: (returnTo: Step) => void
|
|
35
33
|
onManageOperatorWallets: () => void
|
|
36
34
|
onPrepareTransfer: () => void
|
|
@@ -50,8 +48,6 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
|
|
|
50
48
|
onSetStep,
|
|
51
49
|
onSwitchToAdvanced,
|
|
52
50
|
onSwitchToSimple,
|
|
53
|
-
onWithdrawToken,
|
|
54
|
-
onReturnToVault,
|
|
55
51
|
onResumeAdvanced,
|
|
56
52
|
onManageOperatorWallets,
|
|
57
53
|
onPrepareTransfer,
|
|
@@ -72,68 +68,49 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
|
|
|
72
68
|
const tokenOwner = identity.ownerAddress ?? identity.address
|
|
73
69
|
|
|
74
70
|
if (step.kind === 'custody-model') {
|
|
75
|
-
type Action = 'switch-advanced' | 'switch-simple' | 'resume-advanced' | 'cancel-advanced' | '
|
|
71
|
+
type Action = 'switch-advanced' | 'switch-simple' | 'resume-advanced' | 'cancel-advanced' | 'manage-operator-wallets' | 'back'
|
|
76
72
|
const onChainCustody = reconciliation?.custody
|
|
77
73
|
const midFlow = onChainCustody === 'mid-flow-uri-pending'
|
|
78
74
|
const isAdvanced = onChainCustody === 'advanced' || midFlow || custodyMode === 'advanced'
|
|
79
75
|
const vaultHolds = onChainCustody === 'advanced' || midFlow
|
|
80
76
|
const subtitle = midFlow
|
|
81
|
-
? 'Advanced setup pending.
|
|
77
|
+
? 'Advanced setup pending.'
|
|
82
78
|
: isAdvanced
|
|
83
|
-
? 'Advanced
|
|
84
|
-
: 'Simple
|
|
79
|
+
? 'Advanced custody active.'
|
|
80
|
+
: 'Simple custody active.'
|
|
85
81
|
const modeLabel = midFlow ? 'Advanced (setup pending)' : displayCustodyMode(isAdvanced ? 'advanced' : 'simple')
|
|
86
82
|
const options: Array<{ value: Action; role?: 'section' | 'utility'; label: string; hint?: string }> = []
|
|
87
83
|
if (midFlow) {
|
|
88
|
-
options.push({ value: 'resume-advanced', role: 'section', label: 'Resume Setup' })
|
|
89
84
|
options.push({
|
|
90
85
|
value: 'resume-advanced',
|
|
91
86
|
label: 'Resume Advanced Setup',
|
|
92
|
-
hint: 'Sign once to publish onchain and finish the Vault switch.',
|
|
93
87
|
})
|
|
94
88
|
options.push({
|
|
95
89
|
value: 'cancel-advanced',
|
|
96
90
|
label: 'Cancel Advanced Setup',
|
|
97
|
-
hint: 'Unwrap the token back to the owner wallet and revert to simple.',
|
|
98
91
|
})
|
|
99
92
|
}
|
|
100
|
-
options.push({ value: 'switch-advanced', role: 'section', label: 'Custody' })
|
|
101
93
|
if (!isAdvanced) {
|
|
102
94
|
options.push({
|
|
103
95
|
value: 'switch-advanced',
|
|
104
96
|
label: 'Switch to Advanced',
|
|
105
|
-
hint: '
|
|
97
|
+
hint: 'Operators publish',
|
|
106
98
|
})
|
|
107
99
|
} else {
|
|
108
100
|
if (!midFlow) {
|
|
109
101
|
options.push({
|
|
110
102
|
value: 'switch-simple',
|
|
111
103
|
label: 'Switch to Simple',
|
|
112
|
-
hint: '
|
|
104
|
+
hint: 'Remove Vault',
|
|
113
105
|
})
|
|
114
106
|
}
|
|
115
|
-
if (vaultHolds) {
|
|
116
|
-
options.push({
|
|
117
|
-
value: 'withdraw-token',
|
|
118
|
-
label: 'Withdraw Token',
|
|
119
|
-
hint: 'Unwrap this token to the owner wallet. Vault setup stays for easy redeposit.',
|
|
120
|
-
})
|
|
121
|
-
} else if (vaultAddress) {
|
|
122
|
-
options.push({
|
|
123
|
-
value: 'return-to-vault',
|
|
124
|
-
label: 'Return Token to Vault',
|
|
125
|
-
hint: 'Redeposit this token to its Vault. No redeploy, no operator re-add.',
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
options.push({ value: 'manage-operator-wallets', role: 'section', label: 'Operators' })
|
|
129
107
|
options.push({
|
|
130
108
|
value: 'manage-operator-wallets',
|
|
131
109
|
label: 'Manage Operators',
|
|
132
|
-
hint: 'Add or revoke
|
|
110
|
+
hint: 'Add or revoke',
|
|
133
111
|
})
|
|
134
112
|
}
|
|
135
|
-
options.push({ value: 'back',
|
|
136
|
-
options.push({ value: 'back', label: 'Back', hint: 'Return to Identity Hub', role: 'utility' })
|
|
113
|
+
options.push({ value: 'back', label: 'Back', role: 'utility' })
|
|
137
114
|
const notice = step.kind === 'custody-model' ? step.notice : undefined
|
|
138
115
|
return (
|
|
139
116
|
<Surface title="Custody Mode" subtitle={subtitle} footer={footerHint('enter select · esc back')}>
|
|
@@ -182,11 +159,6 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
|
|
|
182
159
|
onSubmit={choice => {
|
|
183
160
|
if (choice === 'back') return onBack()
|
|
184
161
|
if (choice === 'manage-operator-wallets') return onManageOperatorWallets()
|
|
185
|
-
if (choice === 'withdraw-token') return onWithdrawToken(returnTo ?? { kind: 'menu' })
|
|
186
|
-
if (choice === 'return-to-vault') {
|
|
187
|
-
if (!vaultAddress) return
|
|
188
|
-
return onReturnToVault(returnTo ?? { kind: 'menu' }, vaultAddress)
|
|
189
|
-
}
|
|
190
162
|
if (choice === 'resume-advanced') return onResumeAdvanced(returnTo ?? { kind: 'menu' })
|
|
191
163
|
if (choice === 'cancel-advanced') {
|
|
192
164
|
onSetStep({ kind: 'custody-simple-confirm', identity, registry, returnTo })
|
|
@@ -213,31 +185,20 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
|
|
|
213
185
|
return (
|
|
214
186
|
<Surface
|
|
215
187
|
title="Switch to Advanced"
|
|
216
|
-
subtitle="
|
|
188
|
+
subtitle="Token goes into a Vault. Operators update onchain without your sig each time."
|
|
217
189
|
footer={footerHint('enter confirm · esc back')}
|
|
218
190
|
>
|
|
219
191
|
<Box flexDirection="column">
|
|
220
192
|
<Row label="Token" value={tokenLabel} />
|
|
221
193
|
{agentName ? <Row label="Name" value={agentName} /> : null}
|
|
222
194
|
<Row label="Owner Wallet" value={shortAddress(ownerAddress || tokenOwner)} />
|
|
223
|
-
<Text color={theme.textSubtle}>You sign once now to deposit token #{identity.agentId ?? 'unknown'} into a dedicated Vault.</Text>
|
|
224
|
-
<Text color={theme.textSubtle}>This vault can hold only this ERC-8004 token.</Text>
|
|
225
|
-
<Text color={theme.textSubtle}>Other agent tokens use their own vaults.</Text>
|
|
226
|
-
<Text color={theme.textSubtle}>After that, operator wallets you authorize can publish updates for this agent.</Text>
|
|
227
|
-
<Box marginTop={1} flexDirection="column">
|
|
228
|
-
<Text color={theme.accentBlue}>Want a different wallet to be the owner?</Text>
|
|
229
|
-
<Text color={theme.textSubtle}>Move the token there first via Prepare Token Transfer; your continuity files come along.</Text>
|
|
230
|
-
</Box>
|
|
231
195
|
</Box>
|
|
232
196
|
<Box marginTop={1}>
|
|
233
197
|
<Select<Action>
|
|
234
198
|
options={[
|
|
235
|
-
{ value: 'confirm',
|
|
236
|
-
{ value: '
|
|
237
|
-
{ value: '
|
|
238
|
-
{ value: 'transfer', label: 'Prepare Token Transfer', hint: 'Move the token to a different wallet first, with snapshot handoff' },
|
|
239
|
-
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
240
|
-
{ value: 'back', label: 'No, Go Back', hint: 'Return without changing custody', role: 'utility' },
|
|
199
|
+
{ value: 'confirm', label: 'Yes, Switch to Advanced' },
|
|
200
|
+
{ value: 'transfer', label: 'Prepare Token Transfer' },
|
|
201
|
+
{ value: 'back', label: 'Back', role: 'utility' },
|
|
241
202
|
]}
|
|
242
203
|
hintLayout="inline"
|
|
243
204
|
onSubmit={choice => {
|
|
@@ -262,24 +223,19 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
|
|
|
262
223
|
return (
|
|
263
224
|
<Surface
|
|
264
225
|
title="Switch to Simple"
|
|
265
|
-
subtitle="
|
|
226
|
+
subtitle="Withdraws token from Vault to owner wallet."
|
|
266
227
|
footer={footerHint('enter confirm · esc back')}
|
|
267
228
|
>
|
|
268
229
|
<Box flexDirection="column">
|
|
269
230
|
<Row label="Token" value={tokenLabel} />
|
|
270
231
|
{agentName ? <Row label="Name" value={agentName} /> : null}
|
|
271
|
-
<Text>
|
|
272
|
-
<Text color={theme.accentBlue}>Operators lose decrypt access on future snapshots immediately.</Text>
|
|
273
|
-
<Text color={theme.textSubtle}>Operator approvals are cleared from local state for future snapshots. Revoke onchain via Manage Operators first if needed.</Text>
|
|
274
|
-
<Text color={theme.textSubtle}>This switch calls the Vault unwrap function for this token, so the owner wallet must sign the transaction.</Text>
|
|
232
|
+
<Text color={theme.accentError}>Operators lose access immediately.</Text>
|
|
275
233
|
</Box>
|
|
276
234
|
<Box marginTop={1}>
|
|
277
235
|
<Select<Action>
|
|
278
236
|
options={[
|
|
279
|
-
{ value: 'confirm',
|
|
280
|
-
{ value: '
|
|
281
|
-
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
282
|
-
{ value: 'back', label: 'No, Go Back', hint: 'Return without changing custody', role: 'utility' },
|
|
237
|
+
{ value: 'confirm', label: 'Yes, Switch to Simple' },
|
|
238
|
+
{ value: 'back', label: 'Back', role: 'utility' },
|
|
283
239
|
]}
|
|
284
240
|
hintLayout="inline"
|
|
285
241
|
onSubmit={choice => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Address } from 'viem'
|
|
2
2
|
import { createErc8004PublicClient } from '../../registry/erc8004.js'
|
|
3
3
|
import { discoverPriorVaultFromTokenOwner, isAgentInVault } from '../../registry/vault.js'
|
|
4
|
-
import type { ProfileUpdates, Step } from '../
|
|
4
|
+
import type { ProfileUpdates, Step } from '../reducer.js'
|
|
5
5
|
import { isCustodyEditStep } from './CustodyEditFlow.js'
|
|
6
6
|
import { resolveVaultAddress } from './transactions.js'
|
|
7
7
|
import type { CustodyFlowDeps } from './types.js'
|
|
@@ -17,7 +17,6 @@ export function createCustodyFlowActions({
|
|
|
17
17
|
beginVaultDeposit: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
|
|
18
18
|
beginVaultUnwrap: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
|
|
19
19
|
beginWithdrawToken: (currentStep: Step, returnTo: Step, returnContext?: 'ens' | 'simple-exit') => void
|
|
20
|
-
beginReturnToVault: (currentStep: Step, returnTo: Step, vaultAddress: Address) => void
|
|
21
20
|
} {
|
|
22
21
|
const beginVaultDeposit = (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates): void => {
|
|
23
22
|
if (!isCustodyEditStep(currentStep) || currentStep.kind !== 'custody-advanced-confirm') return
|
|
@@ -210,23 +209,10 @@ export function createCustodyFlowActions({
|
|
|
210
209
|
})()
|
|
211
210
|
}
|
|
212
211
|
|
|
213
|
-
const beginReturnToVault = (currentStep: Step, returnTo: Step, vaultAddress: Address): void => {
|
|
214
|
-
if (!isCustodyEditStep(currentStep)) return
|
|
215
|
-
setStep({
|
|
216
|
-
kind: 'custody-vault-deposit-tx',
|
|
217
|
-
identity: currentStep.identity,
|
|
218
|
-
registry: currentStep.registry,
|
|
219
|
-
vaultAddress,
|
|
220
|
-
profileUpdates: withVaultProfileUpdates({}, vaultAddress),
|
|
221
|
-
returnTo,
|
|
222
|
-
})
|
|
223
|
-
}
|
|
224
|
-
|
|
225
212
|
return {
|
|
226
213
|
beginVaultDeposit,
|
|
227
214
|
beginVaultUnwrap,
|
|
228
215
|
beginWithdrawToken,
|
|
229
|
-
beginReturnToVault,
|
|
230
216
|
}
|
|
231
217
|
}
|
|
232
218
|
|
|
@@ -5,7 +5,7 @@ import { Select } from '../../../ui/Select.js'
|
|
|
5
5
|
import { theme } from '../../../ui/theme.js'
|
|
6
6
|
import { WalletApprovalScreen } from '../shared/components/WalletApprovalScreen.js'
|
|
7
7
|
import { shortAddress } from '../shared/model/format.js'
|
|
8
|
-
import type { Step } from '../
|
|
8
|
+
import type { Step } from '../reducer.js'
|
|
9
9
|
import type { CustodyFlowDeps } from './types.js'
|
|
10
10
|
import { chainLabel, humanOwnerAddress } from './helpers.js'
|
|
11
11
|
|
|
@@ -25,9 +25,9 @@ export function renderCustodyStep({
|
|
|
25
25
|
return (
|
|
26
26
|
<WalletApprovalScreen
|
|
27
27
|
title="Deploy Vault"
|
|
28
|
-
subtitle={`Deploying
|
|
28
|
+
subtitle={`Deploying Vault on ${chainLabel(step.registry.chainId)}.`}
|
|
29
29
|
walletSession={walletSession}
|
|
30
|
-
label="waiting for
|
|
30
|
+
label="waiting for wallet to deploy Vault..."
|
|
31
31
|
onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
32
32
|
/>
|
|
33
33
|
)
|
|
@@ -36,9 +36,9 @@ export function renderCustodyStep({
|
|
|
36
36
|
return (
|
|
37
37
|
<WalletApprovalScreen
|
|
38
38
|
title="Deposit Token Into Vault"
|
|
39
|
-
subtitle={`
|
|
39
|
+
subtitle={`Depositing token #${step.identity.agentId ?? ''} into its Vault.`}
|
|
40
40
|
walletSession={walletSession}
|
|
41
|
-
label="waiting for
|
|
41
|
+
label="waiting for wallet to deposit token..."
|
|
42
42
|
onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
43
43
|
/>
|
|
44
44
|
)
|
|
@@ -49,13 +49,10 @@ export function renderCustodyStep({
|
|
|
49
49
|
<Surface
|
|
50
50
|
title="Checking Vault"
|
|
51
51
|
subtitle={targetAgentId
|
|
52
|
-
? `
|
|
52
|
+
? `Checking Vault on ${chainLabel(step.registry.chainId)}.`
|
|
53
53
|
: `Checking this identity's recorded Vault on ${chainLabel(step.registry.chainId)}.`}
|
|
54
54
|
footer={<Text color={theme.dim}>esc cancel</Text>}
|
|
55
55
|
>
|
|
56
|
-
<Box marginTop={1}>
|
|
57
|
-
<Text color={theme.textSubtle}>Reading vault state from onchain...</Text>
|
|
58
|
-
</Box>
|
|
59
56
|
</Surface>
|
|
60
57
|
)
|
|
61
58
|
}
|
|
@@ -64,9 +61,9 @@ export function renderCustodyStep({
|
|
|
64
61
|
return (
|
|
65
62
|
<WalletApprovalScreen
|
|
66
63
|
title="Withdraw Token"
|
|
67
|
-
subtitle={`
|
|
64
|
+
subtitle={`Withdraws token #${targetAgentId} from its Vault.`}
|
|
68
65
|
walletSession={walletSession}
|
|
69
|
-
label="waiting for
|
|
66
|
+
label="waiting for wallet to withdraw token..."
|
|
70
67
|
onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
71
68
|
/>
|
|
72
69
|
)
|
|
@@ -76,21 +73,19 @@ export function renderCustodyStep({
|
|
|
76
73
|
const options = step.tokens.map(t => ({
|
|
77
74
|
value: t.agentId,
|
|
78
75
|
label: `Token #${t.agentId}${activeId && t.agentId === activeId ? ' (active)' : ''}`,
|
|
79
|
-
hint: 'Withdraw
|
|
76
|
+
hint: 'Withdraw to owner wallet',
|
|
80
77
|
}))
|
|
81
78
|
return (
|
|
82
79
|
<Surface
|
|
83
80
|
title="Pick a Vaulted Token"
|
|
84
|
-
subtitle={
|
|
81
|
+
subtitle={`${step.tokens.length} vaulted tokens on ${chainLabel(step.registry.chainId)}.`}
|
|
85
82
|
footer={<Text color={theme.dim}>enter select · esc back</Text>}
|
|
86
83
|
>
|
|
87
84
|
<Box marginTop={1}>
|
|
88
85
|
<Select<string>
|
|
89
86
|
options={[
|
|
90
|
-
{ value: 'header', role: 'section', label: 'Vaulted Tokens' },
|
|
91
87
|
...options,
|
|
92
|
-
{ value: 'cancel',
|
|
93
|
-
{ value: 'cancel', label: 'Back', hint: 'Return to Custody Mode', role: 'utility' },
|
|
88
|
+
{ value: 'cancel', label: 'Back', role: 'utility' },
|
|
94
89
|
]}
|
|
95
90
|
hintLayout="inline"
|
|
96
91
|
onSubmit={choice => {
|
|
@@ -135,23 +130,14 @@ export function renderCustodyStep({
|
|
|
135
130
|
return (
|
|
136
131
|
<Surface
|
|
137
132
|
title="Token Returned to Owner Wallet"
|
|
138
|
-
subtitle={`Token returned to ${shortAddress(step.recipient)}
|
|
133
|
+
subtitle={`Token returned to ${shortAddress(step.recipient)}.`}
|
|
139
134
|
footer={<Text color={theme.dim}>enter select · esc back</Text>}
|
|
140
135
|
>
|
|
141
|
-
<Box flexDirection="column">
|
|
142
|
-
<Text color={theme.textSubtle}>
|
|
143
|
-
{step.returnContext === 'ens'
|
|
144
|
-
? 'Use the token with your owner wallet to set ENS records, then return it to the vault to resume Advanced custody.'
|
|
145
|
-
: 'Use the token with your owner wallet for whatever you need, then return it to the vault when finished.'}
|
|
146
|
-
</Text>
|
|
147
|
-
</Box>
|
|
148
136
|
<Box marginTop={1}>
|
|
149
137
|
<Select<'return-to-vault' | 'keep-out'>
|
|
150
138
|
options={[
|
|
151
|
-
{ value: 'return-to-vault',
|
|
152
|
-
{ value: '
|
|
153
|
-
{ value: 'keep-out', role: 'section', label: 'Later' },
|
|
154
|
-
{ value: 'keep-out', label: 'Keep Out For Now', hint: 'Token stays with the owner wallet; redeposit any time from Custody Mode', role: 'utility' },
|
|
139
|
+
{ value: 'return-to-vault', label: 'Return Token to Vault', hint: 'Redeposit' },
|
|
140
|
+
{ value: 'keep-out', label: 'Keep Out For Now', role: 'utility' },
|
|
155
141
|
]}
|
|
156
142
|
hintLayout="inline"
|
|
157
143
|
onSubmit={choice => {
|
|
@@ -168,9 +154,9 @@ export function renderCustodyStep({
|
|
|
168
154
|
return (
|
|
169
155
|
<WalletApprovalScreen
|
|
170
156
|
title="Unwrap Token From Vault"
|
|
171
|
-
subtitle={`
|
|
157
|
+
subtitle={`Unwrapping token #${step.identity.agentId ?? ''} from Vault.`}
|
|
172
158
|
walletSession={walletSession}
|
|
173
|
-
label="waiting for
|
|
159
|
+
label="waiting for wallet to unwrap token..."
|
|
174
160
|
onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
175
161
|
/>
|
|
176
162
|
)
|
|
@@ -182,20 +168,17 @@ export function renderCustodyStep({
|
|
|
182
168
|
return (
|
|
183
169
|
<Surface
|
|
184
170
|
title="Advanced Custody Active"
|
|
185
|
-
subtitle="
|
|
171
|
+
subtitle="Token held in its Vault. Operators rotate the URI onchain."
|
|
186
172
|
footer={<Text color={theme.dim}>enter continues</Text>}
|
|
187
173
|
>
|
|
188
174
|
<Box flexDirection="column">
|
|
189
175
|
{step.vaultAddress ? <Row label="Vault" value={shortAddress(step.vaultAddress)} /> : null}
|
|
190
176
|
<Row label="Owner Wallet" value={shortAddress(ownerWallet)} />
|
|
191
177
|
<Row label="Operator Wallets" value={operatorCount === 1 ? '1 approved' : `${operatorCount} approved`} />
|
|
192
|
-
<Box marginTop={1}>
|
|
193
|
-
<Text color={theme.textSubtle}>Use Manage Operators to add or revoke operator wallets. Use Withdraw Token to pull this token out of its vault temporarily without dismantling advanced custody.</Text>
|
|
194
|
-
</Box>
|
|
195
178
|
</Box>
|
|
196
179
|
<Box marginTop={1}>
|
|
197
180
|
<Select<'continue'>
|
|
198
|
-
options={[{ value: 'continue', label: '
|
|
181
|
+
options={[{ value: 'continue', label: 'Done' }]}
|
|
199
182
|
onSubmit={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
200
183
|
onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
201
184
|
/>
|
|
@@ -208,18 +191,15 @@ export function renderCustodyStep({
|
|
|
208
191
|
return (
|
|
209
192
|
<Surface
|
|
210
193
|
title="Simple Custody Active"
|
|
211
|
-
subtitle=
|
|
194
|
+
subtitle="Token back in owner wallet."
|
|
212
195
|
footer={<Text color={theme.dim}>enter continues</Text>}
|
|
213
196
|
>
|
|
214
197
|
<Box flexDirection="column">
|
|
215
198
|
<Row label="Owner Wallet" value={shortAddress(ownerWallet)} />
|
|
216
|
-
<Box marginTop={1}>
|
|
217
|
-
<Text color={theme.textSubtle}>Future URI rotations require an owner wallet signature per edit. Switch back to Advanced from Custody Mode at any time.</Text>
|
|
218
|
-
</Box>
|
|
219
199
|
</Box>
|
|
220
200
|
<Box marginTop={1}>
|
|
221
201
|
<Select<'continue'>
|
|
222
|
-
options={[{ value: 'continue', label: '
|
|
202
|
+
options={[{ value: 'continue', label: 'Done' }]}
|
|
223
203
|
onSubmit={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
224
204
|
onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
|
|
225
205
|
/>
|
|
@@ -116,6 +116,7 @@ async function runVaultDepositTransactionInner(args: {
|
|
|
116
116
|
if (!identity.agentId) {
|
|
117
117
|
throw new Error('Cannot deposit token to Vault: agent token ID is missing')
|
|
118
118
|
}
|
|
119
|
+
await assertVaultBytecode(createErc8004PublicClient(registry), vaultAddress)
|
|
119
120
|
const tokenOwner = getAddress(identity.ownerAddress ?? identity.address)
|
|
120
121
|
await assertVaultCanAcceptAgent({
|
|
121
122
|
registry,
|
|
@@ -3,7 +3,7 @@ import type { Address } from 'viem'
|
|
|
3
3
|
import type { EthagentConfig, EthagentIdentity } from '../../../storage/config.js'
|
|
4
4
|
import type { Erc8004RegistryConfig } from '../../registry/erc8004.js'
|
|
5
5
|
import type { EffectCallbacks } from '../shared/effects/types.js'
|
|
6
|
-
import type { ProfileUpdates, Step } from '../
|
|
6
|
+
import type { ProfileUpdates, Step } from '../reducer.js'
|
|
7
7
|
import type { WalletApprovalScreen } from '../shared/components/WalletApprovalScreen.js'
|
|
8
8
|
|
|
9
9
|
export type GuardOwnership = (
|
|
@@ -36,7 +36,6 @@ export interface CustodyFlow {
|
|
|
36
36
|
beginVaultDeposit: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
|
|
37
37
|
beginVaultUnwrap: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
|
|
38
38
|
beginWithdrawToken: (currentStep: Step, returnTo: Step, returnContext?: 'ens' | 'simple-exit') => void
|
|
39
|
-
beginReturnToVault: (currentStep: Step, returnTo: Step, vaultAddress: Address) => void
|
|
40
39
|
renderCustodyStep: () => React.ReactElement | null
|
|
41
40
|
renderRebackupSubtitle: (
|
|
42
41
|
defaultSubtitle: React.ReactNode,
|
|
@@ -2,7 +2,7 @@ import { useEffect } from 'react'
|
|
|
2
2
|
import { createErc8004PublicClient } from '../../registry/erc8004.js'
|
|
3
3
|
import { confirmAgentInVault } from '../../registry/vault.js'
|
|
4
4
|
import { invalidateOwnershipCache } from '../shared/reconciliation/index.js'
|
|
5
|
-
import type { ProfileUpdates } from '../
|
|
5
|
+
import type { ProfileUpdates } from '../reducer.js'
|
|
6
6
|
import type { CustodyFlowDeps } from './types.js'
|
|
7
7
|
import { humanOwnerAddress } from './helpers.js'
|
|
8
8
|
import {
|