ethagent 3.3.3 → 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 -259
- 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
|
@@ -19,7 +19,7 @@ import { FlowTimeline } from '../shared/components/FlowTimeline.js'
|
|
|
19
19
|
import { OPEN_BROWSER_HINT } from '../shared/components/WalletApprovalScreen.js'
|
|
20
20
|
import { readCustodyMode } from '../custody/state.js'
|
|
21
21
|
import { shortAddress } from '../shared/model/format.js'
|
|
22
|
-
import type { ProfileUpdates } from '../
|
|
22
|
+
import type { ProfileUpdates } from '../reducer.js'
|
|
23
23
|
import {
|
|
24
24
|
normalizeApprovedOperatorWallets,
|
|
25
25
|
removeApprovedOperatorWallet,
|
|
@@ -150,19 +150,17 @@ export const OperatorWalletsScreen: React.FC<OperatorWalletsScreenProps> = ({
|
|
|
150
150
|
return (
|
|
151
151
|
<Surface
|
|
152
152
|
title="Operator Wallets"
|
|
153
|
-
subtitle="
|
|
153
|
+
subtitle="Set up Advanced custody first."
|
|
154
154
|
footer={footerHint('enter select · esc back')}
|
|
155
155
|
>
|
|
156
156
|
<Box flexDirection="column">
|
|
157
|
-
<Text color={theme.dim}>Switch to Advanced custody from the Custody Mode menu to capture an owner wallet.</Text>
|
|
158
|
-
<Text color={theme.dim}>Operator wallets can be changed later and never receive token control.</Text>
|
|
159
157
|
{phase.kind === 'main' && phase.error ? <Text color={theme.accentError}>{phase.error}</Text> : null}
|
|
160
158
|
</Box>
|
|
161
159
|
<Box marginTop={1}>
|
|
162
160
|
<Select<'back'>
|
|
163
161
|
options={[
|
|
164
162
|
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
165
|
-
{ value: 'back', label: 'Back',
|
|
163
|
+
{ value: 'back', label: 'Back', role: 'utility' },
|
|
166
164
|
]}
|
|
167
165
|
hintLayout="inline"
|
|
168
166
|
onSubmit={() => onBack()}
|
|
@@ -180,7 +178,6 @@ export const OperatorWalletsScreen: React.FC<OperatorWalletsScreenProps> = ({
|
|
|
180
178
|
subtitle={
|
|
181
179
|
<Box flexDirection="column">
|
|
182
180
|
<FlowTimeline steps={['Verify Operator', 'Sign Backup', 'Publish Snapshot', 'Approve ENS', 'Approve Vault']} current={1} />
|
|
183
|
-
<Text color={theme.dim}>Operator wallet signs restore access. Owner wallet then re-attests the backup, publishes the new snapshot, and authorizes the operator onchain (ENS + vault).</Text>
|
|
184
181
|
</Box>
|
|
185
182
|
}
|
|
186
183
|
walletSession={walletSession}
|
|
@@ -202,7 +199,7 @@ export const OperatorWalletsScreen: React.FC<OperatorWalletsScreenProps> = ({
|
|
|
202
199
|
return (
|
|
203
200
|
<Surface
|
|
204
201
|
title="Operator Wallets"
|
|
205
|
-
subtitle="Owner wallet controls this list.
|
|
202
|
+
subtitle="Owner wallet controls this list."
|
|
206
203
|
footer={footerHint('enter select · esc back')}
|
|
207
204
|
>
|
|
208
205
|
<Box flexDirection="column">
|
|
@@ -284,7 +281,7 @@ function operatorOptions(args: {
|
|
|
284
281
|
}): Array<SelectOption<OperatorAction>> {
|
|
285
282
|
const options: Array<SelectOption<OperatorAction>> = [
|
|
286
283
|
{ value: 'add-browser', role: 'section', label: 'Operator Wallets' },
|
|
287
|
-
{ value: 'add-browser', label: 'Add Wallet'
|
|
284
|
+
{ value: 'add-browser', label: 'Add Wallet' },
|
|
288
285
|
]
|
|
289
286
|
if (args.records[0]) options.push({ value: `remove:${args.records[0].address}`, role: 'section', label: 'Operator Wallets' })
|
|
290
287
|
for (const record of args.records) {
|
|
@@ -293,27 +290,23 @@ function operatorOptions(args: {
|
|
|
293
290
|
options.push({
|
|
294
291
|
value: `activate:${record.address}`,
|
|
295
292
|
label: `Set Active: ${shortAddress(record.address)}`,
|
|
296
|
-
hint: 'Make this the active operator wallet (owner wallet signs)',
|
|
297
293
|
})
|
|
298
294
|
}
|
|
299
295
|
options.push({
|
|
300
296
|
value: `remove:${record.address}`,
|
|
301
297
|
label: `Unlink ${shortAddress(record.address)}${active ? ' (active)' : ''}`,
|
|
302
|
-
hint:
|
|
303
|
-
? 'Active operator wallet. Unlinking clears the active slot; pick a new active from the list.'
|
|
304
|
-
: 'Remove this wallet from the approved list (owner wallet signs)',
|
|
298
|
+
...(active ? {} : { hint: 'Remove' }),
|
|
305
299
|
})
|
|
306
300
|
}
|
|
307
301
|
if (args.records.length > 1) {
|
|
308
302
|
options.push({
|
|
309
303
|
value: 'remove-all',
|
|
310
304
|
label: 'Unlink All Operator Wallets',
|
|
311
|
-
hint: 'Remove every approved operator wallet (owner wallet signs)',
|
|
312
305
|
})
|
|
313
306
|
}
|
|
314
307
|
options.push(
|
|
315
308
|
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
316
|
-
{ value: 'back', label: 'Back',
|
|
309
|
+
{ value: 'back', label: 'Back', role: 'utility' },
|
|
317
310
|
)
|
|
318
311
|
return options
|
|
319
312
|
}
|
|
@@ -332,15 +325,17 @@ const WalletWaitSurface: React.FC<{
|
|
|
332
325
|
})
|
|
333
326
|
return (
|
|
334
327
|
<Surface title={title} subtitle={subtitle} footer={footerHint('esc cancels')}>
|
|
335
|
-
<Box marginTop={1}>
|
|
336
|
-
<Spinner label={walletSession ? 'waiting for wallet signature...' : 'opening wallet request...'} />
|
|
337
|
-
</Box>
|
|
338
328
|
{walletSession ? (
|
|
339
329
|
<Box flexDirection="column">
|
|
340
|
-
<Text color={theme.
|
|
330
|
+
<Text color={theme.accentBlue} underline>{walletSession.url}</Text>
|
|
341
331
|
<Text color={theme.dim}>{OPEN_BROWSER_HINT}</Text>
|
|
332
|
+
<Box marginTop={1}>
|
|
333
|
+
<Spinner label="waiting for operator wallet signature..." />
|
|
334
|
+
</Box>
|
|
342
335
|
</Box>
|
|
343
|
-
) :
|
|
336
|
+
) : (
|
|
337
|
+
<Spinner label="opening wallet request..." />
|
|
338
|
+
)}
|
|
344
339
|
</Surface>
|
|
345
340
|
)
|
|
346
341
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getAddress, type Address } from 'viem'
|
|
2
2
|
import type { AgentEnsRecords, AgentRecordDiff } from '../../ens/agentRecords.js'
|
|
3
|
-
import type {
|
|
3
|
+
import type { EnsSetupBlockedPlan } from '../../ens/ensAutomation.js'
|
|
4
4
|
import type { CustodyMode } from '../custody/state.js'
|
|
5
5
|
|
|
6
6
|
export function abbreviateHexBlobs(input: string): string {
|
|
@@ -52,19 +52,6 @@ export function modeSwitchHeading(
|
|
|
52
52
|
return 'Automation'
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
export function advancedSubdomainStatusText(action: EnsRegistryAction): string {
|
|
56
|
-
switch (action) {
|
|
57
|
-
case 'create-subdomain':
|
|
58
|
-
case 'create-wrapped-subdomain':
|
|
59
|
-
return 'Subdomain check: the owner wallet can create this agent ENS name during setup.'
|
|
60
|
-
case 'set-resolver':
|
|
61
|
-
case 'set-wrapped-resolver':
|
|
62
|
-
return 'Subdomain check: the owner wallet can prepare this ENS name during setup.'
|
|
63
|
-
case 'none':
|
|
64
|
-
return 'Subdomain check: this ENS name is ready.'
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
55
|
export function networkLabelForChainId(chainId: number): string {
|
|
69
56
|
switch (chainId) {
|
|
70
57
|
case 1: return 'Ethereum Mainnet'
|
|
@@ -3,19 +3,29 @@ import { Box, Text } from 'ink'
|
|
|
3
3
|
import { Surface } from '../../../ui/Surface.js'
|
|
4
4
|
import { Select } from '../../../ui/Select.js'
|
|
5
5
|
import { TextInput } from '../../../ui/TextInput.js'
|
|
6
|
+
import { TextArea } from '../../../ui/TextArea.js'
|
|
6
7
|
import { theme } from '../../../ui/theme.js'
|
|
7
8
|
import type { AgentEnsRecordState, AgentEnsRecords } from '../../ens/agentRecords.js'
|
|
8
9
|
import type { EnsSetupPlan } from '../../ens/ensAutomation.js'
|
|
9
|
-
import type { Step } from '../
|
|
10
|
+
import type { Step } from '../reducer.js'
|
|
10
11
|
import { readIdentityStateString } from '../custody/state.js'
|
|
11
|
-
import { FlowTimeline } from '../shared/components/FlowTimeline.js'
|
|
12
12
|
import { validateAgentIconReference } from '../../profile/agentIcon.js'
|
|
13
13
|
import { EnsEditFlow, type EnsLinkOptions } from '../ens/EnsEditFlow.js'
|
|
14
14
|
import type { AgentReconciliation } from '../shared/reconciliation/index.js'
|
|
15
15
|
|
|
16
|
+
type EditProfileStepKind =
|
|
17
|
+
| 'edit-profile-menu'
|
|
18
|
+
| 'edit-profile-name'
|
|
19
|
+
| 'edit-profile-description'
|
|
20
|
+
| 'edit-profile-image'
|
|
21
|
+
| 'edit-profile-review'
|
|
22
|
+
| 'edit-profile-ens'
|
|
23
|
+
|
|
16
24
|
type EditProfileFlowProps = {
|
|
17
|
-
step: Extract<Step, { kind:
|
|
25
|
+
step: Extract<Step, { kind: EditProfileStepKind }>
|
|
18
26
|
reconciliation: AgentReconciliation
|
|
27
|
+
onSelectField: (field: 'name' | 'description' | 'image') => void
|
|
28
|
+
onSaveProfile: () => void
|
|
19
29
|
onNameSubmit: (name: string) => void
|
|
20
30
|
onDescriptionSubmit: (description: string) => void
|
|
21
31
|
onIconSubmit: (iconPath?: string) => void
|
|
@@ -28,16 +38,16 @@ type EditProfileFlowProps = {
|
|
|
28
38
|
onManageOperatorWalletAccess: () => void
|
|
29
39
|
onBack: () => void
|
|
30
40
|
onMenu: () => void
|
|
41
|
+
onBackToEditMenu: () => void
|
|
31
42
|
}
|
|
32
43
|
|
|
33
|
-
const footerHint = (hint: string) => <Text color={theme.
|
|
34
|
-
export const EDIT_PROFILE_STEPS = ['Name', 'Description', 'Icon', 'Review', 'Save']
|
|
35
|
-
const EDIT_NEXT_FOOTER = 'enter next · esc back'
|
|
36
|
-
const EDIT_DESCRIPTION_FOOTER = 'enter next · shift+enter newline · esc back'
|
|
44
|
+
const footerHint = (hint: string) => <Text color={theme.menuStatus}>{hint}</Text>
|
|
37
45
|
|
|
38
46
|
export const EditProfileFlow: React.FC<EditProfileFlowProps> = ({
|
|
39
47
|
step,
|
|
40
48
|
reconciliation,
|
|
49
|
+
onSelectField,
|
|
50
|
+
onSaveProfile,
|
|
41
51
|
onNameSubmit,
|
|
42
52
|
onDescriptionSubmit,
|
|
43
53
|
onIconSubmit,
|
|
@@ -50,16 +60,17 @@ export const EditProfileFlow: React.FC<EditProfileFlowProps> = ({
|
|
|
50
60
|
onManageOperatorWalletAccess,
|
|
51
61
|
onBack,
|
|
52
62
|
onMenu,
|
|
63
|
+
onBackToEditMenu,
|
|
53
64
|
}) => {
|
|
65
|
+
if (step.kind === 'edit-profile-menu') {
|
|
66
|
+
return <EditProfileMenuStep step={step} onSelectField={onSelectField} onSaveProfile={onSaveProfile} onBack={onBack} />
|
|
67
|
+
}
|
|
68
|
+
|
|
54
69
|
if (step.kind === 'edit-profile-name') {
|
|
55
70
|
const currentName = step.name ?? readIdentityStateString(step.identity.state, 'name')
|
|
56
71
|
return (
|
|
57
|
-
<Surface
|
|
58
|
-
|
|
59
|
-
subtitle={<FlowTimeline steps={EDIT_PROFILE_STEPS} current={1} />}
|
|
60
|
-
footer={footerHint(EDIT_NEXT_FOOTER)}
|
|
61
|
-
>
|
|
62
|
-
<Text color={theme.dim}>Saved: {readIdentityStateString(step.identity.state, 'name') || '(unnamed)'}</Text>
|
|
72
|
+
<Surface title="Edit Name" footer={footerHint('enter save · esc back')}>
|
|
73
|
+
<Text color={theme.menuStatus}>Saved: {readIdentityStateString(step.identity.state, 'name') || '(unnamed)'}</Text>
|
|
63
74
|
<Box marginTop={1}>
|
|
64
75
|
<TextInput
|
|
65
76
|
key="edit-profile-name"
|
|
@@ -67,7 +78,7 @@ export const EditProfileFlow: React.FC<EditProfileFlowProps> = ({
|
|
|
67
78
|
placeholder="agent name"
|
|
68
79
|
validate={value => value.trim().length >= 2 ? null : 'name must be at least 2 characters'}
|
|
69
80
|
onSubmit={value => onNameSubmit(value.trim())}
|
|
70
|
-
onCancel={
|
|
81
|
+
onCancel={onBackToEditMenu}
|
|
71
82
|
/>
|
|
72
83
|
</Box>
|
|
73
84
|
</Surface>
|
|
@@ -75,17 +86,11 @@ export const EditProfileFlow: React.FC<EditProfileFlowProps> = ({
|
|
|
75
86
|
}
|
|
76
87
|
|
|
77
88
|
if (step.kind === 'edit-profile-image') {
|
|
78
|
-
return <AgentIconStep step={step} onIconSubmit={onIconSubmit} onIconPick={onIconPick} onBack={onBack} />
|
|
89
|
+
return <AgentIconStep step={step} onIconSubmit={onIconSubmit} onIconPick={onIconPick} onBack={onBack} onMenu={onBackToEditMenu} />
|
|
79
90
|
}
|
|
80
91
|
|
|
81
92
|
if (step.kind === 'edit-profile-review') {
|
|
82
|
-
return
|
|
83
|
-
<EditProfileReviewStep
|
|
84
|
-
step={step}
|
|
85
|
-
onSave={onReviewSave}
|
|
86
|
-
onBack={onBack}
|
|
87
|
-
/>
|
|
88
|
-
)
|
|
93
|
+
return <EditProfileReviewStep step={step} onSave={onReviewSave} onBack={onBackToEditMenu} />
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
if (step.kind === 'edit-profile-ens') {
|
|
@@ -108,52 +113,92 @@ export const EditProfileFlow: React.FC<EditProfileFlowProps> = ({
|
|
|
108
113
|
const currentDescription = readIdentityStateString(step.identity.state, 'description')
|
|
109
114
|
const draftDescription = step.description ?? currentDescription
|
|
110
115
|
return (
|
|
111
|
-
<Surface
|
|
112
|
-
|
|
113
|
-
subtitle={<FlowTimeline steps={EDIT_PROFILE_STEPS} current={2} />}
|
|
114
|
-
footer={footerHint(EDIT_DESCRIPTION_FOOTER)}
|
|
115
|
-
>
|
|
116
|
-
<Text color={theme.dim}>Saved: {currentDescription || '(no description)'}</Text>
|
|
116
|
+
<Surface title="Edit Description">
|
|
117
|
+
<Text color={theme.menuStatus}>Saved: {currentDescription || '(no description)'}</Text>
|
|
117
118
|
<Box marginTop={1}>
|
|
118
|
-
<
|
|
119
|
+
<TextArea
|
|
119
120
|
key="edit-profile-description"
|
|
120
121
|
initialValue={draftDescription}
|
|
121
|
-
placeholder="
|
|
122
|
-
allowEmpty
|
|
123
|
-
multiline
|
|
122
|
+
placeholder="describe this agent"
|
|
124
123
|
onSubmit={value => onDescriptionSubmit(value.trim())}
|
|
125
|
-
onCancel={
|
|
124
|
+
onCancel={onBackToEditMenu}
|
|
126
125
|
/>
|
|
127
126
|
</Box>
|
|
128
127
|
</Surface>
|
|
129
128
|
)
|
|
130
129
|
}
|
|
131
130
|
|
|
131
|
+
const EditProfileMenuStep: React.FC<{
|
|
132
|
+
step: Extract<Step, { kind: 'edit-profile-menu' }>
|
|
133
|
+
onSelectField: (field: 'name' | 'description' | 'image') => void
|
|
134
|
+
onSaveProfile: () => void
|
|
135
|
+
onBack: () => void
|
|
136
|
+
}> = ({ step, onSelectField, onSaveProfile, onBack }) => {
|
|
137
|
+
const savedName = readIdentityStateString(step.identity.state, 'name')
|
|
138
|
+
const savedDescription = readIdentityStateString(step.identity.state, 'description')
|
|
139
|
+
const savedIcon = readIdentityStateString(step.identity.state, 'imageUrl')
|
|
140
|
+
|
|
141
|
+
const draftName = step.name ?? savedName
|
|
142
|
+
const draftDescription = step.description ?? savedDescription
|
|
143
|
+
const draftIcon = describeDraftIcon(step.imagePath, savedIcon)
|
|
144
|
+
|
|
145
|
+
const nameHint = draftName || '(unnamed)'
|
|
146
|
+
const descriptionHint = draftDescription || '(no description)'
|
|
147
|
+
const iconHint = step.imagePath !== undefined
|
|
148
|
+
? `${draftIcon} (draft)`
|
|
149
|
+
: savedIcon
|
|
150
|
+
? draftIcon
|
|
151
|
+
: '(no icon)'
|
|
152
|
+
|
|
153
|
+
const dirty = step.name !== undefined || step.description !== undefined || step.imagePath !== undefined
|
|
154
|
+
const saveHint = dirty ? 'Publish public profile and update the token URI' : 'No changes to save'
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<Surface title="Edit Profile" subtitle="Save publishes all fields together." footer={footerHint('enter select · esc back')}>
|
|
158
|
+
<Select<'name' | 'description' | 'image' | 'save' | 'back'>
|
|
159
|
+
options={[
|
|
160
|
+
{ value: 'name', label: 'Name', hint: nameHint },
|
|
161
|
+
{ value: 'description', label: 'Description', hint: descriptionHint },
|
|
162
|
+
{ value: 'image', label: 'Icon', hint: iconHint },
|
|
163
|
+
{ value: 'save', label: 'Save Profile', hint: saveHint, disabled: !dirty },
|
|
164
|
+
{ value: 'back', label: 'Back', role: 'utility' },
|
|
165
|
+
]}
|
|
166
|
+
hintLayout="inline"
|
|
167
|
+
onSubmit={choice => {
|
|
168
|
+
if (choice === 'name') return onSelectField('name')
|
|
169
|
+
if (choice === 'description') return onSelectField('description')
|
|
170
|
+
if (choice === 'image') return onSelectField('image')
|
|
171
|
+
if (choice === 'save') return onSaveProfile()
|
|
172
|
+
return onBack()
|
|
173
|
+
}}
|
|
174
|
+
onCancel={onBack}
|
|
175
|
+
/>
|
|
176
|
+
</Surface>
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
132
180
|
const AgentIconStep: React.FC<{
|
|
133
181
|
step: Extract<Step, { kind: 'edit-profile-image' }>
|
|
134
182
|
onIconSubmit: (iconPath?: string) => void
|
|
135
183
|
onIconPick: () => void
|
|
136
184
|
onBack: () => void
|
|
137
|
-
|
|
185
|
+
onMenu: () => void
|
|
186
|
+
}> = ({ step, onIconSubmit, onIconPick, onBack, onMenu }) => {
|
|
138
187
|
const [entryMode, setEntryMode] = React.useState(false)
|
|
139
188
|
const currentIcon = readIdentityStateString(step.identity.state, 'imageUrl')
|
|
140
189
|
const selectedIcon = describeDraftIcon(step.imagePath, currentIcon)
|
|
141
190
|
|
|
142
191
|
if (entryMode) {
|
|
143
192
|
return (
|
|
144
|
-
<Surface
|
|
145
|
-
|
|
146
|
-
subtitle={<FlowTimeline steps={EDIT_PROFILE_STEPS} current={3} />}
|
|
147
|
-
footer={footerHint(EDIT_NEXT_FOOTER)}
|
|
148
|
-
>
|
|
149
|
-
<Text color={theme.dim}>Current: {currentIcon ? shortIconReference(currentIcon) : '(no icon)'}</Text>
|
|
193
|
+
<Surface title="Edit Icon" footer={footerHint('enter save · esc back')}>
|
|
194
|
+
<Text color={theme.menuStatus}>Current: {currentIcon ? shortIconReference(currentIcon) : '(no icon)'}</Text>
|
|
150
195
|
<Box marginTop={1}>
|
|
151
196
|
<TextInput
|
|
152
197
|
key="edit-profile-icon-entry"
|
|
153
198
|
placeholder="https://.../icon.png or C:\\path\\icon.png"
|
|
154
199
|
validate={validateAgentIconReference}
|
|
155
200
|
onSubmit={value => onIconSubmit(value.trim())}
|
|
156
|
-
onCancel={
|
|
201
|
+
onCancel={() => setEntryMode(false)}
|
|
157
202
|
/>
|
|
158
203
|
</Box>
|
|
159
204
|
</Surface>
|
|
@@ -161,26 +206,19 @@ const AgentIconStep: React.FC<{
|
|
|
161
206
|
}
|
|
162
207
|
|
|
163
208
|
return (
|
|
164
|
-
<Surface
|
|
165
|
-
title="Edit Profile"
|
|
166
|
-
subtitle={<FlowTimeline steps={EDIT_PROFILE_STEPS} current={3} />}
|
|
167
|
-
footer={footerHint('enter select · esc back')}
|
|
168
|
-
>
|
|
209
|
+
<Surface title="Edit Icon" footer={footerHint('enter select · esc back')}>
|
|
169
210
|
<Box flexDirection="column">
|
|
170
|
-
<Text color={theme.
|
|
211
|
+
<Text color={theme.menuStatus}>Agent Icon: {selectedIcon}</Text>
|
|
171
212
|
{step.error ? <Text color={theme.accentError}>{step.error}</Text> : null}
|
|
172
213
|
</Box>
|
|
173
214
|
<Box marginTop={1}>
|
|
174
215
|
<Select<'choose' | 'enter' | 'skip' | 'delete' | 'back'>
|
|
175
216
|
options={[
|
|
176
|
-
{ value: 'choose',
|
|
177
|
-
{ value: '
|
|
178
|
-
{ value: '
|
|
179
|
-
{ value: '
|
|
180
|
-
{ value: '
|
|
181
|
-
{ value: 'delete', label: 'Remove Agent Icon', hint: 'Clear the public profile icon', disabled: !currentIcon },
|
|
182
|
-
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
183
|
-
{ value: 'back', label: 'Back', hint: 'Return to description', role: 'utility' },
|
|
217
|
+
{ value: 'choose', label: 'Choose Local File', hint: 'Open the file picker' },
|
|
218
|
+
{ value: 'enter', label: 'Enter URL Or Path', hint: 'https, ipfs, or local path' },
|
|
219
|
+
{ value: 'skip', label: currentIcon ? 'Keep Current Icon' : 'No Icon' },
|
|
220
|
+
{ value: 'delete', label: 'Remove Agent Icon', disabled: !currentIcon },
|
|
221
|
+
{ value: 'back', label: 'Back', role: 'utility' },
|
|
184
222
|
]}
|
|
185
223
|
hintLayout="inline"
|
|
186
224
|
onSubmit={choice => {
|
|
@@ -188,9 +226,9 @@ const AgentIconStep: React.FC<{
|
|
|
188
226
|
if (choice === 'enter') { setEntryMode(true); return }
|
|
189
227
|
if (choice === 'delete') return onIconSubmit('delete')
|
|
190
228
|
if (choice === 'skip') return onIconSubmit(undefined)
|
|
191
|
-
return
|
|
229
|
+
return onMenu()
|
|
192
230
|
}}
|
|
193
|
-
onCancel={
|
|
231
|
+
onCancel={onMenu}
|
|
194
232
|
/>
|
|
195
233
|
</Box>
|
|
196
234
|
</Surface>
|
|
@@ -204,11 +242,7 @@ const EditProfileReviewStep: React.FC<{
|
|
|
204
242
|
}> = ({ step, onSave, onBack }) => {
|
|
205
243
|
const currentIcon = readIdentityStateString(step.identity.state, 'imageUrl')
|
|
206
244
|
return (
|
|
207
|
-
<Surface
|
|
208
|
-
title="Edit Profile"
|
|
209
|
-
subtitle={<FlowTimeline steps={EDIT_PROFILE_STEPS} current={4} />}
|
|
210
|
-
footer={footerHint('enter save · esc back')}
|
|
211
|
-
>
|
|
245
|
+
<Surface title="Review Public Profile" footer={footerHint('enter save · esc back')}>
|
|
212
246
|
<Box flexDirection="column">
|
|
213
247
|
<ReviewRow label="Name" value={step.name || '(unnamed)'} />
|
|
214
248
|
<ReviewRow label="Description" value={step.description || '(no description)'} />
|
|
@@ -217,9 +251,8 @@ const EditProfileReviewStep: React.FC<{
|
|
|
217
251
|
<Box marginTop={1}>
|
|
218
252
|
<Select<'save' | 'back'>
|
|
219
253
|
options={[
|
|
220
|
-
{ value: 'save', label: 'Save
|
|
221
|
-
{ value: 'back',
|
|
222
|
-
{ value: 'back', label: 'Back', hint: 'Return to Agent Icon', role: 'utility' },
|
|
254
|
+
{ value: 'save', label: 'Save Profile', hint: 'Publish and update URI' },
|
|
255
|
+
{ value: 'back', label: 'Back', role: 'utility' },
|
|
223
256
|
]}
|
|
224
257
|
hintLayout="inline"
|
|
225
258
|
onSubmit={choice => choice === 'save' ? onSave() : onBack()}
|
|
@@ -235,7 +268,7 @@ const ReviewRow: React.FC<{ label: string; value: string }> = ({ label, value })
|
|
|
235
268
|
return (
|
|
236
269
|
<Box flexDirection="row">
|
|
237
270
|
<Box width={13} flexShrink={0}>
|
|
238
|
-
<Text color={theme.
|
|
271
|
+
<Text color={theme.menuStatus}>{label}</Text>
|
|
239
272
|
</Box>
|
|
240
273
|
<Box flexDirection="column" flexGrow={1}>
|
|
241
274
|
{lines.map((line, i) => (
|
|
@@ -2,7 +2,6 @@ import { getAddress, type Address } from 'viem'
|
|
|
2
2
|
import type { EthagentIdentity } from '../../../storage/config.js'
|
|
3
3
|
import {
|
|
4
4
|
createWalletRestoreAccessChallenge,
|
|
5
|
-
serializeContinuitySnapshotEnvelope,
|
|
6
5
|
type WalletChallengePurpose,
|
|
7
6
|
} from '../../continuity/envelope.js'
|
|
8
7
|
import {
|
|
@@ -23,10 +22,9 @@ import { resolveValidatedPinataJwt, savePinataJwt } from '../../storage/pinataJw
|
|
|
23
22
|
import {
|
|
24
23
|
openBrowserWalletSession,
|
|
25
24
|
requestBrowserWalletSignatureAndTransaction,
|
|
26
|
-
type BrowserWalletSignature,
|
|
27
25
|
type WalletPurpose,
|
|
28
26
|
} from '../../wallet/browserWallet.js'
|
|
29
|
-
import type { ProfileUpdates, Step } from '../
|
|
27
|
+
import type { ProfileUpdates, Step } from '../reducer.js'
|
|
30
28
|
import { acquireTxGuard, releaseTxGuard } from '../shared/txGuard.js'
|
|
31
29
|
import type { EffectCallbacks } from '../shared/effects/types.js'
|
|
32
30
|
import { awaitConfirmedReceipt } from '../shared/effects/receipts.js'
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from '../../registry/erc8004.js'
|
|
21
21
|
import { VAULT_ABI } from '../../registry/vault.js'
|
|
22
22
|
import type { BrowserWalletSignature } from '../../wallet/browserWallet.js'
|
|
23
|
-
import type { Step } from '../
|
|
23
|
+
import type { Step } from '../reducer.js'
|
|
24
24
|
import {
|
|
25
25
|
assertVerifiedPin,
|
|
26
26
|
deriveAgentName,
|
|
@@ -6,7 +6,7 @@ import { clearOwnerAddressField, clearVaultAddressField, readOwnerAddressField,
|
|
|
6
6
|
import { validateAdvancedEnsRelationship } from '../ens/advancedEnsValidation.js'
|
|
7
7
|
import { readCustodyMode } from '../custody/state.js'
|
|
8
8
|
import { ensValidationReasonText } from '../ens/state.js'
|
|
9
|
-
import type { ProfileUpdates } from '../
|
|
9
|
+
import type { ProfileUpdates } from '../reducer.js'
|
|
10
10
|
import {
|
|
11
11
|
assertActiveOperatorIsApproved,
|
|
12
12
|
mergeApprovedOperatorWallets,
|
|
@@ -7,9 +7,10 @@ import type { ContinuitySnapshotEnvelope } from '../continuity/envelope.js'
|
|
|
7
7
|
import type { AgentEnsRecordState, AgentEnsRecords } from '../ens/agentRecords.js'
|
|
8
8
|
import type { EnsSetupPlan } from '../ens/ensAutomation.js'
|
|
9
9
|
import type { WalletPurpose } from '../wallet/browserWallet.js'
|
|
10
|
-
import type {
|
|
10
|
+
import type { IdentityManagerErrorView } from './shared/model/errors.js'
|
|
11
11
|
import type { ApprovedOperatorWalletInput } from './shared/operatorWallets.js'
|
|
12
12
|
import type { CustodyMode } from './custody/state.js'
|
|
13
|
+
import type { ImportCandidate } from './create/importScan.js'
|
|
13
14
|
|
|
14
15
|
export type RestorePurpose = 'restore' | 'switch'
|
|
15
16
|
type RestoreNotFoundReason = 'no-owner-or-operator' | 'search-incomplete' | 'cancelled'
|
|
@@ -29,19 +30,22 @@ export type ProfileUpdates = {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
type RestorableBackupEnvelope = AgentStateBackupEnvelope | ContinuitySnapshotEnvelope
|
|
33
|
+
type RestoreFetchingStep = { kind: 'restore-fetching'; cid: string; apiUrl: string; candidate: Erc8004AgentCandidate; requesterAddress?: string; purpose?: RestorePurpose }
|
|
32
34
|
|
|
33
35
|
export type Step =
|
|
34
36
|
| { kind: 'menu' }
|
|
37
|
+
| { kind: 'operation-complete'; message: string }
|
|
35
38
|
| { kind: 'replace-confirm'; next: 'create' | 'restore' }
|
|
36
39
|
| { kind: 'create-name'; name?: string; error?: string }
|
|
37
40
|
| { kind: 'create-description'; name: string; description?: string }
|
|
38
41
|
| { kind: 'create-network'; name: string; description: string }
|
|
39
42
|
| { kind: 'create-custody'; name: string; description: string; network?: SelectableNetwork }
|
|
40
|
-
| { kind: 'create-
|
|
41
|
-
| { kind: 'create-
|
|
42
|
-
| { kind: 'create-
|
|
43
|
-
| { kind: 'create-
|
|
44
|
-
| { kind: '
|
|
43
|
+
| { kind: 'create-import'; name: string; description: string; network?: SelectableNetwork; custodyMode: CustodyMode; candidates?: ImportCandidate[] }
|
|
44
|
+
| { kind: 'create-preflight'; name: string; description: string; network?: SelectableNetwork; custodyMode: CustodyMode; importNotes?: ImportCandidate[] }
|
|
45
|
+
| { kind: 'create-registry'; name: string; description: string; resolution: RegistryResolution; custodyMode: CustodyMode; error?: string; importNotes?: ImportCandidate[] }
|
|
46
|
+
| { kind: 'create-signing'; name: string; description: string; registry: Erc8004RegistryConfig; custodyMode: CustodyMode; pinataJwt?: string; importNotes?: ImportCandidate[] }
|
|
47
|
+
| { kind: 'create-storage'; name: string; description: string; registry: Erc8004RegistryConfig; custodyMode: CustodyMode; error?: string; pinataJwt?: string; importNotes?: ImportCandidate[] }
|
|
48
|
+
| { kind: 'first-run-ens-prompt'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; origin?: 'create' | 'restore' }
|
|
45
49
|
| { kind: 'restore-wallet'; purpose?: RestorePurpose }
|
|
46
50
|
| { kind: 'restore-network'; ownerHandle: string; purpose?: RestorePurpose }
|
|
47
51
|
| { kind: 'restore-registry'; ownerHandle: string; error?: string; purpose?: RestorePurpose }
|
|
@@ -51,7 +55,7 @@ export type Step =
|
|
|
51
55
|
| { kind: 'restore-token-id-input'; ownerHandle: string; registry: Erc8004RegistryConfig; purpose?: RestorePurpose; busy?: boolean; error?: string }
|
|
52
56
|
| { kind: 'restore-not-found'; ownerHandle: string; registry: Erc8004RegistryConfig; requesterAddress?: string; reason: RestoreNotFoundReason; purpose?: RestorePurpose }
|
|
53
57
|
| { kind: 'restore-select-token'; ownerHandle: string; registry: Erc8004RegistryConfig; candidates: Erc8004AgentCandidate[]; requesterAddress?: string; purpose?: RestorePurpose }
|
|
54
|
-
|
|
|
58
|
+
| RestoreFetchingStep
|
|
55
59
|
| { kind: 'restore-authorizing'; cid: string; apiUrl: string; envelope: RestorableBackupEnvelope; candidate: Erc8004AgentCandidate; requesterAddress?: string; purpose?: RestorePurpose }
|
|
56
60
|
| { kind: 'rebackup-signing'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; pinataJwt?: string; profileUpdates?: ProfileUpdates; returnTo?: Step; walletPurpose?: WalletPurpose; vaultAddress?: `0x${string}` }
|
|
57
61
|
| { kind: 'rebackup-storage'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; error?: string; pinataJwt?: string; profileUpdates?: ProfileUpdates; returnTo?: Step; walletPurpose?: WalletPurpose; vaultAddress?: `0x${string}` }
|
|
@@ -67,18 +71,17 @@ export type Step =
|
|
|
67
71
|
| { kind: 'rebackup-confirm'; back: Step }
|
|
68
72
|
| { kind: 'recovery-refetch-confirm'; back: Step }
|
|
69
73
|
| { kind: 'recovery-refetching'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; back: Step }
|
|
74
|
+
| { kind: 'continuity-overwrite-confirm'; action: 'restore'; next: RestoreFetchingStep; back: Step }
|
|
70
75
|
| { kind: 'rebackup-start'; back: Step }
|
|
76
|
+
| { kind: 'edit-profile-menu'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; name?: string; description?: string; imagePath?: string; returnTo?: Step }
|
|
71
77
|
| { kind: 'edit-profile-name'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; name?: string; description?: string; imagePath?: string; returnTo?: Step }
|
|
72
|
-
| { kind: 'edit-profile-description'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; name
|
|
73
|
-
| { kind: 'edit-profile-image'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; name
|
|
78
|
+
| { kind: 'edit-profile-description'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; name?: string; description?: string; imagePath?: string; returnTo?: Step }
|
|
79
|
+
| { kind: 'edit-profile-image'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; name?: string; description?: string; imagePath?: string; error?: string; returnTo?: Step }
|
|
74
80
|
| { kind: 'edit-profile-review'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; name: string; description: string; imagePath?: string; returnTo?: Step }
|
|
75
81
|
| { kind: 'edit-profile-ens'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; returnTo?: Step; initialView?: 'advanced' }
|
|
76
82
|
| { kind: 'ens-records-tx'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; fullName: string; records: AgentEnsRecords; currentRecords?: AgentEnsRecordState; ownerAddress?: string; returnTo?: Step; clearRecords?: boolean }
|
|
77
83
|
| { kind: 'ens-setup-registry-tx'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; setup: EnsSetupPlan; returnTo?: Step }
|
|
78
84
|
| { kind: 'ens-setup-records-tx'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; setup: EnsSetupPlan; returnTo?: Step; registryTxHash?: string }
|
|
79
|
-
| { kind: 'ens-clear-flow-running'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; fullName: string; ownerAddress: `0x${string}`; records: AgentEnsRecords; currentRecords?: AgentEnsRecordState; pinataJwt?: string; returnTo?: Step }
|
|
80
|
-
| { kind: 'ens-update-flow-running'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; fullName: string; ownerAddress: `0x${string}`; records: AgentEnsRecords; currentRecords?: AgentEnsRecordState; pinataJwt?: string; returnTo?: Step }
|
|
81
|
-
| { kind: 'ens-link-flow-running'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; setup: EnsSetupPlan; pinataJwt?: string; returnTo?: Step }
|
|
82
85
|
| { kind: 'manage-ens-operators'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; returnTo?: Step; notice?: string; error?: string }
|
|
83
86
|
| { kind: 'custody-model'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; returnTo?: Step; notice?: string }
|
|
84
87
|
| { kind: 'custody-advanced-confirm'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; returnTo?: Step }
|
|
@@ -103,14 +106,14 @@ export type Step =
|
|
|
103
106
|
| { kind: 'details' }
|
|
104
107
|
| { kind: 'save-prompt'; back: Step }
|
|
105
108
|
| { kind: 'busy'; label: string }
|
|
106
|
-
| { kind: 'error'; error:
|
|
109
|
+
| { kind: 'error'; error: IdentityManagerErrorView; back: Step }
|
|
107
110
|
| { kind: 'identity-unlinked'; identity: EthagentIdentity; registry: Erc8004RegistryConfig; onChainOwner?: string; back: Step }
|
|
108
111
|
|
|
109
112
|
export type Action =
|
|
110
113
|
| { type: 'setStep'; step: Step }
|
|
111
114
|
| { type: 'back'; from: Step }
|
|
112
115
|
|
|
113
|
-
export function
|
|
116
|
+
export function identityManagerReducer(state: Step, action: Action): Step {
|
|
114
117
|
switch (action.type) {
|
|
115
118
|
case 'setStep':
|
|
116
119
|
return action.step
|
|
@@ -131,6 +134,8 @@ function backStep(from: Step): Step {
|
|
|
131
134
|
return { kind: 'create-description', name: from.name, description: from.description }
|
|
132
135
|
case 'create-custody':
|
|
133
136
|
return { kind: 'create-network', name: from.name, description: from.description }
|
|
137
|
+
case 'create-import':
|
|
138
|
+
return { kind: 'create-custody', name: from.name, description: from.description, ...(from.network ? { network: from.network } : {}) }
|
|
134
139
|
case 'create-preflight':
|
|
135
140
|
return { kind: 'create-custody', name: from.name, description: from.description, ...(from.network ? { network: from.network } : {}) }
|
|
136
141
|
case 'create-registry':
|
|
@@ -192,8 +197,12 @@ function backStep(from: Step): Step {
|
|
|
192
197
|
case 'recovery-refetch-confirm':
|
|
193
198
|
case 'recovery-refetching':
|
|
194
199
|
return { kind: 'menu' }
|
|
195
|
-
case '
|
|
200
|
+
case 'continuity-overwrite-confirm':
|
|
201
|
+
return from.back
|
|
202
|
+
case 'edit-profile-menu':
|
|
196
203
|
return from.returnTo ?? { kind: 'continuity-public' }
|
|
204
|
+
case 'edit-profile-name':
|
|
205
|
+
return { kind: 'edit-profile-menu', identity: from.identity, registry: from.registry, name: from.name, description: from.description, imagePath: from.imagePath, returnTo: from.returnTo }
|
|
197
206
|
case 'edit-profile-description':
|
|
198
207
|
return { kind: 'edit-profile-name', identity: from.identity, registry: from.registry, name: from.name, description: from.description, imagePath: from.imagePath, returnTo: from.returnTo }
|
|
199
208
|
case 'edit-profile-image':
|
|
@@ -213,17 +222,6 @@ function backStep(from: Step): Step {
|
|
|
213
222
|
returnTo: from.returnTo,
|
|
214
223
|
...(from.setup.mode === 'advanced' ? { initialView: 'advanced' as const } : {}),
|
|
215
224
|
}
|
|
216
|
-
case 'ens-clear-flow-running':
|
|
217
|
-
case 'ens-update-flow-running':
|
|
218
|
-
return { kind: 'edit-profile-ens', identity: from.identity, registry: from.registry, returnTo: from.returnTo }
|
|
219
|
-
case 'ens-link-flow-running':
|
|
220
|
-
return {
|
|
221
|
-
kind: 'edit-profile-ens',
|
|
222
|
-
identity: from.identity,
|
|
223
|
-
registry: from.registry,
|
|
224
|
-
returnTo: from.returnTo,
|
|
225
|
-
...(from.setup.mode === 'advanced' ? { initialView: 'advanced' as const } : {}),
|
|
226
|
-
}
|
|
227
225
|
case 'manage-ens-operators':
|
|
228
226
|
return from.returnTo ?? { kind: 'menu' }
|
|
229
227
|
case 'custody-model':
|
|
@@ -276,6 +274,7 @@ export function createStepNumber(step: Step): number {
|
|
|
276
274
|
return 3
|
|
277
275
|
case 'create-custody':
|
|
278
276
|
return 4
|
|
277
|
+
case 'create-import':
|
|
279
278
|
case 'create-preflight':
|
|
280
279
|
case 'create-storage':
|
|
281
280
|
case 'create-registry':
|