ethagent 1.1.2 → 2.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/LICENSE +21 -21
- package/README.md +126 -30
- package/package.json +7 -2
- package/src/app/FirstRun.tsx +190 -146
- package/src/app/FirstRunTimeline.tsx +47 -0
- package/src/app/input/AppInputProvider.tsx +1 -1
- package/src/app/keybindings/KeybindingProvider.tsx +1 -1
- package/src/chat/ChatBottomPane.tsx +0 -1
- package/src/chat/ChatInput.tsx +6 -6
- package/src/chat/ChatScreen.tsx +35 -15
- package/src/chat/ContextLimitView.tsx +4 -4
- package/src/chat/ContinuityEditReviewView.tsx +10 -22
- package/src/chat/CopyPicker.tsx +0 -1
- package/src/chat/MessageList.tsx +62 -45
- package/src/chat/PermissionPrompt.tsx +13 -9
- package/src/chat/PlanApprovalView.tsx +3 -3
- package/src/chat/ResumeView.tsx +1 -4
- package/src/chat/RewindView.tsx +2 -2
- package/src/chat/chatInputState.ts +1 -1
- package/src/chat/chatScreenUtils.ts +22 -11
- package/src/chat/chatSessionState.ts +2 -2
- package/src/chat/chatTurnOrchestrator.ts +16 -81
- package/src/chat/commands.ts +1 -1
- package/src/chat/textCursor.ts +1 -1
- package/src/chat/transcriptViewport.ts +2 -7
- package/src/cli/ResetConfirmView.tsx +1 -1
- package/src/cli/main.tsx +9 -3
- package/src/cli/preview.tsx +0 -5
- package/src/cli/updateNotice.ts +4 -2
- package/src/identity/continuity/editor.ts +7 -107
- package/src/identity/continuity/envelope.ts +1048 -40
- package/src/identity/continuity/history.ts +4 -4
- package/src/identity/continuity/localBackup.ts +249 -0
- package/src/identity/continuity/privateEdit/apply.ts +170 -0
- package/src/identity/continuity/privateEdit/diff.ts +82 -0
- package/src/identity/continuity/privateEdit/files.ts +23 -0
- package/src/identity/continuity/privateEdit/types.ts +28 -0
- package/src/identity/continuity/privateEdit.ts +10 -298
- package/src/identity/continuity/publicSkills.ts +8 -9
- package/src/identity/continuity/snapshots.ts +17 -6
- package/src/identity/continuity/storage/defaults.ts +111 -0
- package/src/identity/continuity/storage/files.ts +72 -0
- package/src/identity/continuity/storage/markdown.ts +81 -0
- package/src/identity/continuity/storage/paths.ts +24 -0
- package/src/identity/continuity/storage/scaffold.ts +124 -0
- package/src/identity/continuity/storage/status.ts +86 -0
- package/src/identity/continuity/storage/types.ts +27 -0
- package/src/identity/continuity/storage.ts +32 -507
- package/src/identity/continuity/zipWriter.ts +95 -0
- package/src/identity/crypto/backupEnvelope.ts +14 -247
- package/src/identity/crypto/eth.ts +7 -7
- package/src/identity/ens/agentRecords.ts +96 -0
- package/src/identity/ens/ensAutomation/contracts.ts +38 -0
- package/src/identity/ens/ensAutomation/delete.ts +80 -0
- package/src/identity/ens/ensAutomation/names.ts +14 -0
- package/src/identity/ens/ensAutomation/operators.ts +29 -0
- package/src/identity/ens/ensAutomation/read.ts +114 -0
- package/src/identity/ens/ensAutomation/root.ts +63 -0
- package/src/identity/ens/ensAutomation/setup.ts +284 -0
- package/src/identity/ens/ensAutomation/transactions.ts +107 -0
- package/src/identity/ens/ensAutomation/types.ts +126 -0
- package/src/identity/ens/ensAutomation.ts +29 -0
- package/src/identity/ens/ensLookup/client.ts +43 -0
- package/src/identity/ens/ensLookup/constants.ts +26 -0
- package/src/identity/ens/ensLookup/discovery.ts +70 -0
- package/src/identity/ens/ensLookup/names.ts +34 -0
- package/src/identity/ens/ensLookup/records.ts +45 -0
- package/src/identity/ens/ensLookup/resolve.ts +75 -0
- package/src/identity/ens/ensLookup/tokenReference.ts +17 -0
- package/src/identity/ens/ensLookup/types.ts +38 -0
- package/src/identity/ens/ensLookup/validation.ts +72 -0
- package/src/identity/ens/ensLookup.ts +19 -0
- package/src/identity/ens/ensRegistration.ts +199 -0
- package/src/identity/ens/resolverDelegation.ts +48 -0
- package/src/identity/hub/IdentityHub.tsx +13 -817
- package/src/identity/hub/OperationalRoutes.tsx +370 -0
- package/src/identity/hub/Routes.tsx +361 -0
- package/src/identity/hub/advancedEnsValidation.ts +45 -0
- package/src/identity/hub/{screens → components}/DetailsScreen.tsx +14 -8
- package/src/identity/hub/{screens → components}/ErrorScreen.tsx +15 -5
- package/src/identity/hub/components/FlowTimeline.tsx +27 -0
- package/src/identity/hub/components/IdentitySummary.tsx +190 -0
- package/src/identity/hub/components/MenuScreen.tsx +237 -0
- package/src/identity/hub/{screens → components}/NetworkScreen.tsx +3 -3
- package/src/identity/hub/{screens/RebackupStorageScreen.tsx → components/PinataJwtInput.tsx} +21 -18
- package/src/identity/hub/components/UnlinkedIdentityScreen.tsx +76 -0
- package/src/identity/hub/{screens → components}/WalletApprovalScreen.tsx +9 -8
- package/src/identity/hub/components/menuFlagsFromReconciliation.ts +68 -0
- package/src/identity/hub/effects/create.ts +310 -0
- package/src/identity/hub/effects/ens/flows.ts +218 -0
- package/src/identity/hub/effects/ens/index.ts +11 -0
- package/src/identity/hub/effects/ens/transactions.ts +239 -0
- package/src/identity/hub/effects/index.ts +74 -0
- package/src/identity/hub/effects/profile/profileState.ts +173 -0
- package/src/identity/hub/effects/publicProfile/index.ts +5 -0
- package/src/identity/hub/effects/publicProfile/runPublicProfileSave.ts +646 -0
- package/src/identity/hub/effects/rebackup/index.ts +7 -0
- package/src/identity/hub/effects/rebackup/operatorVault.ts +378 -0
- package/src/identity/hub/effects/rebackup/runRebackup.ts +451 -0
- package/src/identity/hub/effects/receipts.ts +46 -0
- package/src/identity/hub/effects/restore/apply.ts +112 -0
- package/src/identity/hub/effects/restore/auth.ts +159 -0
- package/src/identity/hub/effects/restore/discover.ts +86 -0
- package/src/identity/hub/effects/restore/envelopes.ts +21 -0
- package/src/identity/hub/effects/restore/fetch.ts +25 -0
- package/src/identity/hub/effects/restore/index.ts +22 -0
- package/src/identity/hub/effects/restore/recovery.ts +135 -0
- package/src/identity/hub/effects/restore/resolve.ts +102 -0
- package/src/identity/hub/effects/restore/restoreEffects.ts +22 -0
- package/src/identity/hub/effects/restore/shared.ts +91 -0
- package/src/identity/hub/effects/restoreAdmin.ts +93 -0
- package/src/identity/hub/effects/shared/profilePrep.ts +139 -0
- package/src/identity/hub/effects/shared/snapshot.ts +336 -0
- package/src/identity/hub/effects/shared/sync.ts +190 -0
- package/src/identity/hub/effects/token-transfer/index.ts +6 -0
- package/src/identity/hub/effects/token-transfer/progress.ts +59 -0
- package/src/identity/hub/effects/token-transfer/runTokenTransfer.ts +299 -0
- package/src/identity/hub/effects/types.ts +53 -0
- package/src/identity/hub/effects/vault/preflight.ts +50 -0
- package/src/identity/hub/flows/continuity/ContinuityDashboardScreen.tsx +170 -0
- package/src/identity/hub/flows/continuity/RebackupStorageScreen.tsx +28 -0
- package/src/identity/hub/{screens → flows/continuity}/RecoveryConfirmScreen.tsx +28 -19
- package/src/identity/hub/flows/continuity/SavePromptScreen.tsx +49 -0
- package/src/identity/hub/{screens → flows/create}/CreateFlow.tsx +61 -62
- package/src/identity/hub/flows/custody/CustodyEditFlow.tsx +347 -0
- package/src/identity/hub/flows/custody/custodyEffects.ts +321 -0
- package/src/identity/hub/flows/custody/custodyFlowActions.ts +236 -0
- package/src/identity/hub/flows/custody/custodyFlowEffects.ts +163 -0
- package/src/identity/hub/flows/custody/custodyFlowHelpers.ts +25 -0
- package/src/identity/hub/flows/custody/custodyFlowRoutes.tsx +239 -0
- package/src/identity/hub/flows/custody/custodyFlowTypes.ts +45 -0
- package/src/identity/hub/flows/custody/useCustodyFlow.tsx +25 -0
- package/src/identity/hub/flows/ens/EnsEditAdvancedScreens.tsx +336 -0
- package/src/identity/hub/flows/ens/EnsEditFlow.tsx +397 -0
- package/src/identity/hub/flows/ens/EnsEditMaintenanceScreens.tsx +332 -0
- package/src/identity/hub/flows/ens/EnsEditReviewScreens.tsx +471 -0
- package/src/identity/hub/flows/ens/EnsEditRunners.tsx +198 -0
- package/src/identity/hub/flows/ens/EnsEditShared.tsx +162 -0
- package/src/identity/hub/flows/ens/EnsEditSimpleScreens.tsx +518 -0
- package/src/identity/hub/flows/ens/IdentityHubEnsFlow.tsx +299 -0
- package/src/identity/hub/flows/ens/OperatorWalletsScreen.tsx +398 -0
- package/src/identity/hub/flows/ens/ensEditCopy.ts +117 -0
- package/src/identity/hub/flows/ens/ensEditTypes.ts +91 -0
- package/src/identity/hub/flows/profile/EditProfileFlow.tsx +271 -0
- package/src/identity/hub/flows/restore/RestoreFlow.tsx +324 -0
- package/src/identity/hub/flows/restore/useRestoreFlowEffects.ts +77 -0
- package/src/identity/hub/{screens → flows/settings}/StorageCredentialScreen.tsx +23 -44
- package/src/identity/hub/flows/token-transfer/IdentityHubTokenTransferFlow.tsx +162 -0
- package/src/identity/hub/flows/token-transfer/TokenTransferScreens.tsx +256 -0
- package/src/identity/hub/identityHubReducer.ts +164 -99
- package/src/identity/hub/model/continuity.ts +94 -0
- package/src/identity/hub/model/copy.ts +35 -0
- package/src/identity/hub/model/custody.ts +54 -0
- package/src/identity/hub/model/ens.ts +49 -0
- package/src/identity/hub/model/errors.ts +140 -0
- package/src/identity/hub/model/format.ts +15 -0
- package/src/identity/hub/model/identity.ts +94 -0
- package/src/identity/hub/model/network.ts +32 -0
- package/src/identity/hub/model/transfer.ts +57 -0
- package/src/identity/hub/operatorWallets.ts +131 -0
- package/src/identity/hub/reconciliation/agentReconciliation/hook.ts +46 -0
- package/src/identity/hub/reconciliation/agentReconciliation/ownership.ts +129 -0
- package/src/identity/hub/reconciliation/agentReconciliation/run.ts +302 -0
- package/src/identity/hub/reconciliation/agentReconciliation/types.ts +17 -0
- package/src/identity/hub/reconciliation/index.ts +21 -0
- package/src/identity/hub/reconciliation/useAgentReconciliation.ts +10 -0
- package/src/identity/hub/reconciliation/walletSetup.ts +220 -0
- package/src/identity/hub/txGuard.ts +51 -0
- package/src/identity/hub/types.ts +17 -0
- package/src/identity/hub/useIdentityHubContinuity.ts +136 -0
- package/src/identity/hub/useIdentityHubController.ts +396 -0
- package/src/identity/hub/useIdentityHubSideEffects.ts +309 -0
- package/src/identity/hub/utils.ts +79 -0
- package/src/identity/identityCompat.ts +34 -0
- package/src/identity/profile/agentIcon.ts +61 -0
- package/src/identity/profile/imagePicker.ts +12 -12
- package/src/identity/registry/erc8004/abi.ts +14 -0
- package/src/identity/registry/erc8004/chains.ts +150 -0
- package/src/identity/registry/erc8004/client.ts +11 -0
- package/src/identity/registry/erc8004/discovery.ts +511 -0
- package/src/identity/registry/erc8004/metadata.ts +335 -0
- package/src/identity/registry/erc8004/ownership.ts +121 -0
- package/src/identity/registry/erc8004/preflight.ts +123 -0
- package/src/identity/registry/erc8004/transactions.ts +77 -0
- package/src/identity/registry/erc8004/types.ts +88 -0
- package/src/identity/registry/erc8004/uri.ts +59 -0
- package/src/identity/registry/erc8004/utils.ts +58 -0
- package/src/identity/registry/erc8004.ts +53 -1106
- package/src/identity/registry/fieldParsers.ts +28 -0
- package/src/identity/registry/operatorVault/bytecode.ts +98 -0
- package/src/identity/registry/operatorVault/constants.ts +38 -0
- package/src/identity/registry/operatorVault/read.ts +246 -0
- package/src/identity/registry/operatorVault/transactions.ts +81 -0
- package/src/identity/registry/operatorVault.ts +44 -0
- package/src/identity/storage/ipfs.ts +26 -24
- package/src/identity/wallet/browserWallet/gas.ts +41 -0
- package/src/identity/wallet/browserWallet/html.ts +106 -0
- package/src/identity/wallet/browserWallet/http.ts +28 -0
- package/src/identity/wallet/browserWallet/requestServer.ts +106 -0
- package/src/identity/wallet/browserWallet/requests.ts +191 -0
- package/src/identity/wallet/browserWallet/session.ts +325 -0
- package/src/identity/wallet/browserWallet/types.ts +192 -0
- package/src/identity/wallet/browserWallet/validation.ts +74 -0
- package/src/identity/wallet/browserWallet.ts +30 -393
- package/src/identity/wallet/page/constants.ts +5 -0
- package/src/identity/wallet/page/controller.ts +251 -0
- package/src/identity/wallet/page/copy.ts +340 -0
- package/src/identity/wallet/page/grainient.ts +278 -0
- package/src/identity/wallet/page/html.ts +28 -0
- package/src/identity/wallet/page/markup.ts +50 -0
- package/src/identity/wallet/page/state.ts +9 -0
- package/src/identity/wallet/page/styles/base.ts +259 -0
- package/src/identity/wallet/page/styles/components.ts +262 -0
- package/src/identity/wallet/page/styles/index.ts +5 -0
- package/src/identity/wallet/page/styles/responsive.ts +247 -0
- package/src/identity/wallet/page/types.ts +47 -0
- package/src/identity/wallet/page/view.ts +535 -0
- package/src/identity/wallet/page/walletProvider.ts +70 -0
- package/src/identity/wallet/page.tsx +38 -0
- package/src/identity/wallet/walletPurposeCompat.ts +27 -0
- package/src/mcp/manager.ts +0 -1
- package/src/models/ModelPicker.tsx +36 -30
- package/src/models/catalog.ts +5 -2
- package/src/models/huggingface.ts +9 -9
- package/src/models/llamacpp.ts +13 -13
- package/src/models/modelDisplay.ts +75 -0
- package/src/models/modelPickerOptions.ts +16 -3
- package/src/models/modelRecommendation.ts +0 -1
- package/src/providers/errors.ts +16 -0
- package/src/providers/gemini.ts +252 -39
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +1 -1
- package/src/runtime/sessionMode.ts +1 -1
- package/src/runtime/systemPrompt.ts +2 -0
- package/src/runtime/toolExecution.ts +18 -22
- package/src/runtime/toolIntent.ts +0 -20
- package/src/runtime/turn.ts +0 -92
- package/src/storage/atomicWrite.ts +4 -1
- package/src/storage/config.ts +181 -5
- package/src/storage/identity.ts +9 -3
- package/src/storage/secrets.ts +2 -2
- package/src/tools/bashSafety.ts +8 -0
- package/src/tools/changeDirectoryTool.ts +1 -1
- package/src/tools/deleteFileTool.ts +4 -4
- package/src/tools/editTool.ts +4 -4
- package/src/tools/editUtils.ts +5 -5
- package/src/tools/privateContinuityEditTool.ts +4 -5
- package/src/tools/privateContinuityReadTool.ts +1 -2
- package/src/tools/registry.ts +30 -0
- package/src/tools/writeFileTool.ts +5 -5
- package/src/ui/BrandSplash.tsx +20 -85
- package/src/ui/ProgressBar.tsx +3 -5
- package/src/ui/Select.tsx +20 -8
- package/src/ui/Spinner.tsx +38 -3
- package/src/ui/Surface.tsx +2 -2
- package/src/ui/TextInput.tsx +63 -20
- package/src/ui/theme.ts +7 -34
- package/src/utils/openExternal.ts +21 -0
- package/src/utils/withRetry.ts +47 -3
- package/src/identity/hub/identityHubEffects.ts +0 -937
- package/src/identity/hub/identityHubModel.ts +0 -371
- package/src/identity/hub/screens/ContinuityDashboardScreen.tsx +0 -156
- package/src/identity/hub/screens/EditProfileFlow.tsx +0 -146
- package/src/identity/hub/screens/IdentitySummary.tsx +0 -106
- package/src/identity/hub/screens/MenuScreen.tsx +0 -117
- package/src/identity/hub/screens/RestoreFlow.tsx +0 -206
- package/src/identity/wallet/wallet-page/wallet.html +0 -1202
- /package/src/identity/hub/{screens → components}/BusyScreen.tsx +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Box, Text } from 'ink'
|
|
3
|
+
import { Surface } from '../../../../ui/Surface.js'
|
|
4
|
+
import { Select } from '../../../../ui/Select.js'
|
|
5
|
+
import { theme } from '../../../../ui/theme.js'
|
|
6
|
+
import type { EthagentConfig, EthagentIdentity } from '../../../../storage/config.js'
|
|
7
|
+
import type { ContinuityWorkingTreeStatus } from '../../../continuity/storage.js'
|
|
8
|
+
import { IdentitySummary } from '../../components/IdentitySummary.js'
|
|
9
|
+
import { changedContinuitySnapshotFiles } from '../../model/continuity.js'
|
|
10
|
+
import { readIdentityStateString } from '../../model/custody.js'
|
|
11
|
+
import { shortCid } from '../../model/format.js'
|
|
12
|
+
|
|
13
|
+
type PrivateAction = 'soul' | 'memory' | 'skills' | 'export-backup' | 'back'
|
|
14
|
+
type PublicAction = 'edit' | 'back'
|
|
15
|
+
|
|
16
|
+
interface CommonProps {
|
|
17
|
+
identity?: EthagentIdentity
|
|
18
|
+
config?: EthagentConfig
|
|
19
|
+
workingStatus?: ContinuityWorkingTreeStatus | null
|
|
20
|
+
ready: boolean
|
|
21
|
+
notice?: string
|
|
22
|
+
editorOpened?: boolean
|
|
23
|
+
footer: React.ReactNode
|
|
24
|
+
onBack: () => void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const SaveFromHubHint: React.FC<{ workingStatus?: ContinuityWorkingTreeStatus | null }> = ({ workingStatus }) => {
|
|
28
|
+
const needsBackup = workingStatus?.publishState === 'local-changes'
|
|
29
|
+
|| workingStatus?.publishState === 'not-published'
|
|
30
|
+
|| workingStatus?.publishState === 'verify-needed'
|
|
31
|
+
if (!needsBackup) return null
|
|
32
|
+
const files = changedContinuitySnapshotFiles(workingStatus)
|
|
33
|
+
return (
|
|
34
|
+
<Box marginTop={1} flexDirection="column">
|
|
35
|
+
<Text color={theme.accentError} bold>
|
|
36
|
+
Unsaved changes
|
|
37
|
+
{files.length > 0 ? `: ${files.join(', ')}` : ''}
|
|
38
|
+
</Text>
|
|
39
|
+
<Text color={theme.dim}>Use Save Snapshot Now in the Identity Hub menu, or relaunch ethagent.</Text>
|
|
40
|
+
</Box>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const PrivateContinuityScreen: React.FC<CommonProps & {
|
|
45
|
+
onOpenSoul: () => void
|
|
46
|
+
onOpenMemory: () => void
|
|
47
|
+
onOpenSkills: () => void
|
|
48
|
+
onExportBackup: () => void
|
|
49
|
+
}> = ({
|
|
50
|
+
identity,
|
|
51
|
+
config,
|
|
52
|
+
workingStatus,
|
|
53
|
+
ready,
|
|
54
|
+
notice,
|
|
55
|
+
editorOpened,
|
|
56
|
+
footer,
|
|
57
|
+
onOpenSoul,
|
|
58
|
+
onOpenMemory,
|
|
59
|
+
onOpenSkills,
|
|
60
|
+
onExportBackup,
|
|
61
|
+
onBack,
|
|
62
|
+
}) => (
|
|
63
|
+
<Surface title="Soul, Memory, and Skills" subtitle={notice ?? privateSubtitle(ready)} footer={footer}>
|
|
64
|
+
<IdentitySummary identity={identity} config={config} workingStatus={workingStatus} hideLocalChanges />
|
|
65
|
+
<PrivateRows identity={identity} ready={ready} />
|
|
66
|
+
<SaveFromHubHint workingStatus={workingStatus} />
|
|
67
|
+
{editorOpened && (
|
|
68
|
+
<Box marginTop={1}>
|
|
69
|
+
<Text color={theme.accentPeriwinkle}>Save with ctrl+s in your editor</Text>
|
|
70
|
+
</Box>
|
|
71
|
+
)}
|
|
72
|
+
<Box marginTop={1}>
|
|
73
|
+
<Select<PrivateAction>
|
|
74
|
+
options={[
|
|
75
|
+
{ value: 'soul', role: 'section', label: 'Private Continuity' },
|
|
76
|
+
{ value: 'soul', label: 'Edit Soul', hint: 'Voice, behavior, and operating preferences', disabled: !ready },
|
|
77
|
+
{ value: 'memory', label: 'Edit Memory', hint: 'Durable owner memory for this agent', disabled: !ready },
|
|
78
|
+
{ value: 'skills', role: 'section', label: 'Public Capabilities' },
|
|
79
|
+
{ value: 'skills', label: 'Edit skills.json', hint: 'Machine-readable capabilities for discovery', disabled: !ready },
|
|
80
|
+
{ value: 'export-backup', role: 'section', label: 'Local Backup' },
|
|
81
|
+
{ value: 'export-backup', label: 'Save Local Backup', hint: 'Bundle SOUL.md, MEMORY.md, skills.json into a zip you can keep anywhere', disabled: !ready },
|
|
82
|
+
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
83
|
+
{ value: 'back', label: 'Back', hint: 'Return to Identity Hub menu', role: 'utility' },
|
|
84
|
+
]}
|
|
85
|
+
hintLayout="inline"
|
|
86
|
+
onSubmit={choice => {
|
|
87
|
+
if (choice === 'soul') return onOpenSoul()
|
|
88
|
+
if (choice === 'memory') return onOpenMemory()
|
|
89
|
+
if (choice === 'skills') return onOpenSkills()
|
|
90
|
+
if (choice === 'export-backup') return onExportBackup()
|
|
91
|
+
return onBack()
|
|
92
|
+
}}
|
|
93
|
+
onCancel={onBack}
|
|
94
|
+
/>
|
|
95
|
+
</Box>
|
|
96
|
+
</Surface>
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
export const PublicProfileScreen: React.FC<CommonProps & {
|
|
100
|
+
onEditProfile: () => void
|
|
101
|
+
}> = ({ identity, config, workingStatus, notice, editorOpened, footer, onEditProfile, onBack }) => {
|
|
102
|
+
return (
|
|
103
|
+
<Surface title="Public Profile" subtitle={notice ?? 'Manage the public name, description, icon, and Agent Card.'} footer={footer}>
|
|
104
|
+
<IdentitySummary identity={identity} config={config} workingStatus={workingStatus} hideLocalChanges />
|
|
105
|
+
<PublicProfileRows identity={identity} />
|
|
106
|
+
<SaveFromHubHint workingStatus={workingStatus} />
|
|
107
|
+
{editorOpened && (
|
|
108
|
+
<Box marginTop={1}>
|
|
109
|
+
<Text color={theme.accentPeriwinkle}>Save with ctrl+s in your editor</Text>
|
|
110
|
+
</Box>
|
|
111
|
+
)}
|
|
112
|
+
<Box marginTop={1}>
|
|
113
|
+
<Select<PublicAction>
|
|
114
|
+
options={[
|
|
115
|
+
{ value: 'edit', role: 'section', label: 'Profile' },
|
|
116
|
+
{ value: 'edit', label: 'Edit Name, Description, Icon', hint: 'Update public profile fields used in the Agent Card' },
|
|
117
|
+
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
118
|
+
{ value: 'back', label: 'Back', hint: 'Return to Identity Hub menu', role: 'utility' },
|
|
119
|
+
]}
|
|
120
|
+
hintLayout="inline"
|
|
121
|
+
onSubmit={choice => {
|
|
122
|
+
if (choice === 'edit') return onEditProfile()
|
|
123
|
+
return onBack()
|
|
124
|
+
}}
|
|
125
|
+
onCancel={onBack}
|
|
126
|
+
/>
|
|
127
|
+
</Box>
|
|
128
|
+
</Surface>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const PrivateRows: React.FC<{ identity?: EthagentIdentity; ready: boolean }> = ({ identity, ready }) => (
|
|
133
|
+
<Box flexDirection="column" marginTop={1}>
|
|
134
|
+
<Text>
|
|
135
|
+
<Text color={theme.dim}>{'Private'.padEnd(13)}</Text>
|
|
136
|
+
<Text color={ready ? theme.text : theme.dim}>{ready ? 'Local Files Ready' : 'Missing Local Working Files'}</Text>
|
|
137
|
+
</Text>
|
|
138
|
+
<Text>
|
|
139
|
+
<Text color={theme.dim}>{'Snapshot'.padEnd(13)}</Text>
|
|
140
|
+
<Text color={identity?.backup?.cid ? theme.text : theme.dim}>{identity?.backup?.cid ? shortCid(identity.backup.cid) : 'Not Saved Yet'}</Text>
|
|
141
|
+
</Text>
|
|
142
|
+
<Text>
|
|
143
|
+
<Text color={theme.dim}>{'Skills'.padEnd(13)}</Text>
|
|
144
|
+
<Text color={identity?.publicSkills?.cid ? theme.text : theme.dim}>{identity?.publicSkills?.cid ? shortCid(identity.publicSkills.cid) : 'Not Saved'}</Text>
|
|
145
|
+
</Text>
|
|
146
|
+
</Box>
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
const PublicProfileRows: React.FC<{ identity?: EthagentIdentity }> = ({ identity }) => (
|
|
150
|
+
<Box flexDirection="column" marginTop={1}>
|
|
151
|
+
<Text>
|
|
152
|
+
<Text color={theme.dim}>{publicProfileLabel('Agent Card')}</Text>
|
|
153
|
+
<Text color={identity?.publicSkills?.agentCardCid ? theme.text : theme.dim}>{identity?.publicSkills?.agentCardCid ? shortCid(identity.publicSkills.agentCardCid) : 'Not Saved'}</Text>
|
|
154
|
+
</Text>
|
|
155
|
+
<Text>
|
|
156
|
+
<Text color={theme.dim}>{publicProfileLabel('Agent Icon')}</Text>
|
|
157
|
+
<Text color={readIdentityStateString(identity?.state, 'imageUrl') ? theme.text : theme.dim}>{readIdentityStateString(identity?.state, 'imageUrl') ? 'Attached' : 'Not Attached'}</Text>
|
|
158
|
+
</Text>
|
|
159
|
+
</Box>
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
function publicProfileLabel(label: string): string {
|
|
163
|
+
return label.padEnd(16)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function privateSubtitle(ready: boolean): string {
|
|
167
|
+
return ready
|
|
168
|
+
? 'Edit local continuity files. Public skills are saved with the same snapshot.'
|
|
169
|
+
: 'Use "Refetch Latest Snapshot" from the Identity Hub menu to recover files.'
|
|
170
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { PinataJwtInput } from '../../components/PinataJwtInput.js'
|
|
3
|
+
import type { Step } from '../../identityHubReducer.js'
|
|
4
|
+
|
|
5
|
+
interface RebackupStorageScreenProps {
|
|
6
|
+
step: Extract<Step, { kind: 'rebackup-storage' | 'public-profile-storage' }>
|
|
7
|
+
footer: React.ReactNode
|
|
8
|
+
title?: string
|
|
9
|
+
subtitle?: string
|
|
10
|
+
onSubmit: (input: string) => void
|
|
11
|
+
onCancel: () => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const RebackupStorageScreen: React.FC<RebackupStorageScreenProps> = ({ step, footer, title, subtitle, onSubmit, onCancel }) => {
|
|
15
|
+
const publicOnly = step.kind === 'public-profile-storage'
|
|
16
|
+
return (
|
|
17
|
+
<PinataJwtInput
|
|
18
|
+
inputKey="rebackup-storage"
|
|
19
|
+
title={title}
|
|
20
|
+
subtitle={step.error ?? subtitle ?? (publicOnly
|
|
21
|
+
? 'Save a Pinata JWT so ethagent can pin the public profile to IPFS.'
|
|
22
|
+
: 'Save a Pinata JWT so ethagent can pin encrypted state to IPFS.')}
|
|
23
|
+
footer={footer}
|
|
24
|
+
onSubmit={onSubmit}
|
|
25
|
+
onCancel={onCancel}
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Box, Text } from 'ink'
|
|
3
|
-
import { Surface } from '
|
|
4
|
-
import { Select } from '
|
|
5
|
-
import { theme } from '
|
|
6
|
-
import { localChangeStatusView, type LocalChangeStatusView } from '
|
|
3
|
+
import { Surface } from '../../../../ui/Surface.js'
|
|
4
|
+
import { Select } from '../../../../ui/Select.js'
|
|
5
|
+
import { theme } from '../../../../ui/theme.js'
|
|
6
|
+
import { localChangeStatusView, type LocalChangeStatusView } from '../../model/continuity.js'
|
|
7
7
|
|
|
8
|
-
import type { ContinuityWorkingTreeStatus } from '
|
|
8
|
+
import type { ContinuityWorkingTreeStatus } from '../../../continuity/storage.js'
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
type RecoveryConfirmMode = 'publish' | 'refetch'
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
interface RecoveryConfirmScreenProps {
|
|
13
13
|
mode: RecoveryConfirmMode
|
|
14
14
|
workingStatus?: ContinuityWorkingTreeStatus | null
|
|
15
|
+
pendingPublish?: boolean
|
|
15
16
|
footer: React.ReactNode
|
|
16
17
|
onConfirm: () => void
|
|
17
18
|
onBack: () => void
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
export const RecoveryConfirmScreen: React.FC<RecoveryConfirmScreenProps> = ({ mode, workingStatus, footer, onConfirm, onBack }) => {
|
|
21
|
+
export const RecoveryConfirmScreen: React.FC<RecoveryConfirmScreenProps> = ({ mode, workingStatus, pendingPublish, footer, onConfirm, onBack }) => {
|
|
21
22
|
const isPublish = mode === 'publish'
|
|
22
23
|
const title = isPublish ? 'Save Snapshot?' : 'Refetch Latest From Chain?'
|
|
23
24
|
const subtitle = isPublish
|
|
24
|
-
? 'Saves
|
|
25
|
-
: 'This overwrites local files with the
|
|
25
|
+
? 'Saves SOUL.md, MEMORY.md, skills.json, and profile changes.'
|
|
26
|
+
: 'This overwrites local files with the onchain version.'
|
|
26
27
|
|
|
27
|
-
const headlineColor =
|
|
28
|
+
const headlineColor = theme.accentPeriwinkle
|
|
28
29
|
const headline = isPublish
|
|
29
|
-
? 'Saving updates the
|
|
30
|
-
: 'Refetching replaces
|
|
30
|
+
? 'Saving updates the onchain pointer for this agent.'
|
|
31
|
+
: 'Refetching replaces SOUL.md, MEMORY.md, and skills.json with what is onchain.'
|
|
31
32
|
const detail = isPublish
|
|
32
|
-
? '
|
|
33
|
+
? 'Your local continuity files and profile edits become the saved state. The previous snapshot pointer is overwritten.'
|
|
33
34
|
: 'Unsaved local edits will be lost. Use this when local files are missing or out of sync with the latest saved snapshot.'
|
|
34
35
|
|
|
35
36
|
const localChangeStatus = localChangeStatusView(workingStatus)
|
|
@@ -44,22 +45,28 @@ export const RecoveryConfirmScreen: React.FC<RecoveryConfirmScreenProps> = ({ mo
|
|
|
44
45
|
<SaveSnapshotStatusLine status={localChangeStatus} />
|
|
45
46
|
</Box>
|
|
46
47
|
)}
|
|
48
|
+
{!isPublish && pendingPublish ? (
|
|
49
|
+
<Box marginTop={1} flexDirection="column">
|
|
50
|
+
<Text color={theme.accentError} bold>Local snapshot is ahead of chain.</Text>
|
|
51
|
+
<Text color={theme.textSubtle}>Local edits have not yet been rotated to the onchain pointer. Refetching discards them and reverts to the last published snapshot.</Text>
|
|
52
|
+
</Box>
|
|
53
|
+
) : null}
|
|
47
54
|
{!isPublish && (
|
|
48
55
|
<Box marginTop={1}>
|
|
49
|
-
<Text color={theme.
|
|
56
|
+
<Text color={theme.accentPeriwinkle}>Overwrite your local files?</Text>
|
|
50
57
|
</Box>
|
|
51
58
|
)}
|
|
52
59
|
</Box>
|
|
53
60
|
<Box marginTop={1}>
|
|
54
61
|
<Select<'confirm' | 'back'>
|
|
55
62
|
options={[
|
|
56
|
-
{ value: 'confirm', role: 'section',
|
|
63
|
+
{ value: 'confirm', role: 'section', label: isPublish ? 'Save' : 'Refetch' },
|
|
57
64
|
{
|
|
58
65
|
value: 'confirm',
|
|
59
66
|
label: isPublish ? 'Yes, Save Snapshot Now' : 'Yes, Refetch From Chain',
|
|
60
67
|
hint: isPublish ? 'Sign and save the encrypted snapshot' : 'Wallet decrypts and overwrites local files',
|
|
61
68
|
},
|
|
62
|
-
{ value: 'back', role: 'section',
|
|
69
|
+
{ value: 'back', role: 'section', label: 'Cancel' },
|
|
63
70
|
{
|
|
64
71
|
value: 'back',
|
|
65
72
|
label: 'No, Go Back',
|
|
@@ -84,12 +91,14 @@ const SaveSnapshotStatusLine: React.FC<{ status: LocalChangeStatusView }> = ({ s
|
|
|
84
91
|
return (
|
|
85
92
|
<Text>
|
|
86
93
|
<Text color={theme.textSubtle}>Local changes detected: </Text>
|
|
87
|
-
<Text color=
|
|
94
|
+
<Text color={theme.accentError} bold>{status.files.length > 0 ? status.files.join(', ') : 'local files differ from saved snapshot'}</Text>
|
|
88
95
|
</Text>
|
|
89
96
|
)
|
|
90
97
|
}
|
|
91
98
|
|
|
92
|
-
|
|
99
|
+
if (!status.detail) return null
|
|
100
|
+
|
|
101
|
+
const color = status.tone === 'ok' || status.tone === 'warn' ? theme.accentPeriwinkle : theme.dim
|
|
93
102
|
const label = status.detail === 'None detected' ? 'No local changes detected.' : status.detail
|
|
94
103
|
return <Text color={color}>{label}</Text>
|
|
95
104
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Box, Text } from 'ink'
|
|
3
|
+
import { Surface } from '../../../../ui/Surface.js'
|
|
4
|
+
import { Select } from '../../../../ui/Select.js'
|
|
5
|
+
import { theme } from '../../../../ui/theme.js'
|
|
6
|
+
import type { ContinuityWorkingTreeStatus } from '../../../continuity/storage.js'
|
|
7
|
+
import { changedContinuitySnapshotFiles } from '../../model/continuity.js'
|
|
8
|
+
|
|
9
|
+
type SavePromptAction = 'save-now' | 'later'
|
|
10
|
+
|
|
11
|
+
interface SavePromptScreenProps {
|
|
12
|
+
workingStatus?: ContinuityWorkingTreeStatus | null
|
|
13
|
+
footer: React.ReactNode
|
|
14
|
+
onSelect: (action: SavePromptAction) => void
|
|
15
|
+
onCancel: () => void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const SavePromptScreen: React.FC<SavePromptScreenProps> = ({ workingStatus, footer, onSelect, onCancel }) => {
|
|
19
|
+
const files = changedContinuitySnapshotFiles(workingStatus)
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Surface
|
|
23
|
+
title="Save your identity changes?"
|
|
24
|
+
subtitle="Unsaved local edits since the last snapshot."
|
|
25
|
+
footer={footer}
|
|
26
|
+
tone="primary"
|
|
27
|
+
>
|
|
28
|
+
<Box flexDirection="column">
|
|
29
|
+
{files.length > 0 ? (
|
|
30
|
+
<Text color={theme.textSubtle}>Changed: <Text color={theme.accentError} bold>{files.join(', ')}</Text></Text>
|
|
31
|
+
) : (
|
|
32
|
+
<Text color={theme.accentPeriwinkle}>Local files differ from the saved snapshot.</Text>
|
|
33
|
+
)}
|
|
34
|
+
</Box>
|
|
35
|
+
<Box marginTop={1}>
|
|
36
|
+
<Select<SavePromptAction>
|
|
37
|
+
options={[
|
|
38
|
+
{ value: 'save-now', role: 'section', label: 'Save' },
|
|
39
|
+
{ value: 'save-now', label: 'Save now', hint: 'Sign once and save the encrypted snapshot' },
|
|
40
|
+
{ value: 'later', label: 'Not now', hint: 'Ask again on the next ethagent launch', role: 'utility' },
|
|
41
|
+
]}
|
|
42
|
+
hintLayout="inline"
|
|
43
|
+
onSubmit={onSelect}
|
|
44
|
+
onCancel={onCancel}
|
|
45
|
+
/>
|
|
46
|
+
</Box>
|
|
47
|
+
</Surface>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -1,34 +1,18 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Box, Text } from 'ink'
|
|
3
|
-
import { Surface } from '
|
|
4
|
-
import { Select } from '
|
|
5
|
-
import { TextInput } from '
|
|
6
|
-
import { theme } from '
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
const PINATA_API_KEYS_URL = 'https://app.pinata.cloud/developers/api-keys'
|
|
17
|
-
|
|
18
|
-
type StepIndicatorProps = {
|
|
19
|
-
steps: string[]
|
|
20
|
-
current: number
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const StepIndicator: React.FC<StepIndicatorProps> = ({ steps, current }) => {
|
|
24
|
-
const parts = steps.map((step, index) => {
|
|
25
|
-
const n = index + 1
|
|
26
|
-
const active = n === current
|
|
27
|
-
const done = n < current
|
|
28
|
-
return `${done ? 'done' : n}. ${step}${active ? ' <' : ''}`
|
|
29
|
-
})
|
|
30
|
-
return <Text color={theme.dim}>{parts.join(' · ')}</Text>
|
|
31
|
-
}
|
|
3
|
+
import { Surface } from '../../../../ui/Surface.js'
|
|
4
|
+
import { Select } from '../../../../ui/Select.js'
|
|
5
|
+
import { TextInput } from '../../../../ui/TextInput.js'
|
|
6
|
+
import { theme } from '../../../../ui/theme.js'
|
|
7
|
+
import { normalizeErc8004RegistryConfig } from '../../../registry/erc8004.js'
|
|
8
|
+
import { networkLabel } from '../../model/network.js'
|
|
9
|
+
import type { Step } from '../../identityHubReducer.js'
|
|
10
|
+
import { createStepNumber, CREATE_STEP_LABELS } from '../../identityHubReducer.js'
|
|
11
|
+
import { WalletApprovalScreen } from '../../components/WalletApprovalScreen.js'
|
|
12
|
+
import { BusyScreen } from '../../components/BusyScreen.js'
|
|
13
|
+
import { FlowTimeline } from '../../components/FlowTimeline.js'
|
|
14
|
+
import { PinataJwtInput } from '../../components/PinataJwtInput.js'
|
|
15
|
+
import type { BrowserWalletReady } from '../../../wallet/browserWallet.js'
|
|
32
16
|
|
|
33
17
|
type CreateFlowProps = {
|
|
34
18
|
step: Extract<Step, {
|
|
@@ -36,6 +20,7 @@ type CreateFlowProps = {
|
|
|
36
20
|
| 'replace-confirm'
|
|
37
21
|
| 'create-name'
|
|
38
22
|
| 'create-description'
|
|
23
|
+
| 'create-custody'
|
|
39
24
|
| 'create-preflight'
|
|
40
25
|
| 'create-registry'
|
|
41
26
|
| 'create-signing'
|
|
@@ -45,9 +30,9 @@ type CreateFlowProps = {
|
|
|
45
30
|
onSetStep: (step: Step) => void
|
|
46
31
|
onNameSubmit: (name: string) => void
|
|
47
32
|
onDescriptionSubmit: (name: string, description: string) => void
|
|
33
|
+
onCustodySubmit: (custodyMode: 'simple' | 'advanced') => void
|
|
48
34
|
onRegistrySubmit: (value: string) => void
|
|
49
35
|
onStorageSubmit: (input: string) => void
|
|
50
|
-
onStorageError: (error: string) => void
|
|
51
36
|
onBack: () => void
|
|
52
37
|
onMenu: () => void
|
|
53
38
|
}
|
|
@@ -58,6 +43,7 @@ export const CreateFlow: React.FC<CreateFlowProps> = ({
|
|
|
58
43
|
onSetStep,
|
|
59
44
|
onNameSubmit,
|
|
60
45
|
onDescriptionSubmit,
|
|
46
|
+
onCustodySubmit,
|
|
61
47
|
onRegistrySubmit,
|
|
62
48
|
onStorageSubmit,
|
|
63
49
|
onBack,
|
|
@@ -65,7 +51,7 @@ export const CreateFlow: React.FC<CreateFlowProps> = ({
|
|
|
65
51
|
}) => {
|
|
66
52
|
const stepNum = createStepNumber(step)
|
|
67
53
|
const indicator = stepNum > 0
|
|
68
|
-
? <
|
|
54
|
+
? <FlowTimeline steps={[...CREATE_STEP_LABELS]} current={stepNum} />
|
|
69
55
|
: null
|
|
70
56
|
|
|
71
57
|
if (step.kind === 'replace-confirm') {
|
|
@@ -81,9 +67,9 @@ export const CreateFlow: React.FC<CreateFlowProps> = ({
|
|
|
81
67
|
</Box>
|
|
82
68
|
<Select<'replace' | 'back'>
|
|
83
69
|
options={[
|
|
84
|
-
{ value: 'back', role: 'section',
|
|
70
|
+
{ value: 'back', role: 'section', label: 'Current Identity' },
|
|
85
71
|
{ value: 'back', label: 'Keep Current Agent', hint: 'Return without minting anything', role: 'utility' },
|
|
86
|
-
{ value: 'replace', role: 'section',
|
|
72
|
+
{ value: 'replace', role: 'section', label: 'New Identity' },
|
|
87
73
|
{ value: 'replace', label: 'Mint and Use New Agent', hint: 'Create separate token and make it active' },
|
|
88
74
|
]}
|
|
89
75
|
hintLayout="inline"
|
|
@@ -100,9 +86,10 @@ export const CreateFlow: React.FC<CreateFlowProps> = ({
|
|
|
100
86
|
if (step.kind === 'create-name') {
|
|
101
87
|
return (
|
|
102
88
|
<Surface title="Name Your Agent" subtitle={indicator} footer="enter continues · esc back">
|
|
103
|
-
{step.error ? <Text color=
|
|
89
|
+
{step.error ? <Text color={theme.accentError}>{step.error}</Text> : null}
|
|
104
90
|
<TextInput
|
|
105
91
|
key="agent-name"
|
|
92
|
+
initialValue={step.name ?? ''}
|
|
106
93
|
placeholder="agent name"
|
|
107
94
|
validate={value => value.trim().length >= 2 ? null : 'name must be at least 2 characters'}
|
|
108
95
|
onSubmit={name => onNameSubmit(name.trim())}
|
|
@@ -114,11 +101,14 @@ export const CreateFlow: React.FC<CreateFlowProps> = ({
|
|
|
114
101
|
|
|
115
102
|
if (step.kind === 'create-description') {
|
|
116
103
|
return (
|
|
117
|
-
<Surface title="Describe Your Agent" subtitle={indicator} footer="enter
|
|
104
|
+
<Surface title="Describe Your Agent" subtitle={indicator} footer="enter next · shift+enter newline · esc back">
|
|
118
105
|
<Text color={theme.dim}>Optional. One short sentence is enough.</Text>
|
|
119
106
|
<TextInput
|
|
120
107
|
key="agent-description"
|
|
108
|
+
initialValue={step.description ?? ''}
|
|
121
109
|
placeholder="description"
|
|
110
|
+
allowEmpty
|
|
111
|
+
multiline
|
|
122
112
|
onSubmit={description => onDescriptionSubmit(step.name, description.trim())}
|
|
123
113
|
onCancel={onBack}
|
|
124
114
|
/>
|
|
@@ -126,6 +116,28 @@ export const CreateFlow: React.FC<CreateFlowProps> = ({
|
|
|
126
116
|
)
|
|
127
117
|
}
|
|
128
118
|
|
|
119
|
+
if (step.kind === 'create-custody') {
|
|
120
|
+
return (
|
|
121
|
+
<Surface title="Pick Custody Mode" subtitle={indicator} footer="enter continues · esc back">
|
|
122
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
123
|
+
<Text color={theme.dim}>Custody decides who controls the ERC-8004 token and who can rotate the URI pointer.</Text>
|
|
124
|
+
<Text color={theme.dim}>You can switch later from Identity Hub.</Text>
|
|
125
|
+
</Box>
|
|
126
|
+
<Select<'simple' | 'advanced'>
|
|
127
|
+
options={[
|
|
128
|
+
{ value: 'simple', role: 'section', label: 'Simple (Recommended)' },
|
|
129
|
+
{ value: 'simple', label: 'Simple', hint: 'One wallet owns the token, signs every save, and rotates the URI directly' },
|
|
130
|
+
{ value: 'advanced', role: 'section', label: 'Advanced' },
|
|
131
|
+
{ value: 'advanced', label: 'Advanced', hint: 'Operator delegation vault holds the token; owner wallet controls vault, operator wallets get URI-rotation permission' },
|
|
132
|
+
]}
|
|
133
|
+
hintLayout="inline"
|
|
134
|
+
onSubmit={onCustodySubmit}
|
|
135
|
+
onCancel={onBack}
|
|
136
|
+
/>
|
|
137
|
+
</Surface>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
129
141
|
if (step.kind === 'create-preflight') {
|
|
130
142
|
return (
|
|
131
143
|
<BusyScreen
|
|
@@ -164,43 +176,30 @@ export const CreateFlow: React.FC<CreateFlowProps> = ({
|
|
|
164
176
|
}
|
|
165
177
|
|
|
166
178
|
if (step.kind === 'create-signing') {
|
|
179
|
+
const isAdvanced = step.custodyMode === 'advanced'
|
|
167
180
|
return (
|
|
168
181
|
<WalletApprovalScreen
|
|
169
|
-
title=
|
|
170
|
-
subtitle=
|
|
182
|
+
title={isAdvanced ? 'Connect Owner Wallet' : 'Sign in Wallet'}
|
|
183
|
+
subtitle={
|
|
184
|
+
isAdvanced
|
|
185
|
+
? 'This wallet will own the agent token and control the delegation vault. Operator wallets are configured after minting.'
|
|
186
|
+
: 'One browser flow signs, saves the IPFS backup, and submits the token transaction.'
|
|
187
|
+
}
|
|
171
188
|
walletSession={walletSession}
|
|
172
|
-
label=
|
|
189
|
+
label={isAdvanced ? 'waiting for owner wallet...' : 'waiting for wallet signature...'}
|
|
173
190
|
onCancel={onBack}
|
|
174
191
|
/>
|
|
175
192
|
)
|
|
176
193
|
}
|
|
177
194
|
|
|
178
195
|
return (
|
|
179
|
-
<
|
|
196
|
+
<PinataJwtInput
|
|
197
|
+
inputKey="create-storage"
|
|
180
198
|
title="Connect IPFS Storage"
|
|
181
|
-
subtitle={step.error ??
|
|
199
|
+
subtitle={step.error ?? undefined}
|
|
182
200
|
footer="enter continues · esc back"
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
<Text color={theme.accentPrimary} underline>{PINATA_API_KEYS_URL}</Text>
|
|
187
|
-
</Text>
|
|
188
|
-
<Text color={theme.dim}>Saved encrypted on this device · used only for IPFS pinning</Text>
|
|
189
|
-
<TextInput
|
|
190
|
-
key="create-storage"
|
|
191
|
-
isSecret
|
|
192
|
-
placeholder="Pinata JWT"
|
|
193
|
-
validate={v => {
|
|
194
|
-
try {
|
|
195
|
-
extractPinataJwt(v)
|
|
196
|
-
return null
|
|
197
|
-
} catch (err: unknown) {
|
|
198
|
-
return (err as Error).message
|
|
199
|
-
}
|
|
200
|
-
}}
|
|
201
|
-
onSubmit={onStorageSubmit}
|
|
202
|
-
onCancel={onBack}
|
|
203
|
-
/>
|
|
204
|
-
</Surface>
|
|
201
|
+
onSubmit={onStorageSubmit}
|
|
202
|
+
onCancel={onBack}
|
|
203
|
+
/>
|
|
205
204
|
)
|
|
206
205
|
}
|