ethagent 2.1.1 → 2.3.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/package.json +2 -1
- package/src/app/FirstRun.tsx +1 -7
- package/src/app/FirstRunTimeline.tsx +1 -1
- package/src/auth/openaiOAuth/credentials.ts +47 -0
- package/src/auth/openaiOAuth/crypto.ts +23 -0
- package/src/auth/openaiOAuth/index.ts +238 -0
- package/src/auth/openaiOAuth/landingPage.ts +125 -0
- package/src/auth/openaiOAuth/listener.ts +151 -0
- package/src/auth/openaiOAuth/refresh.ts +70 -0
- package/src/auth/openaiOAuth/shared.ts +115 -0
- package/src/chat/ChatBottomPane.tsx +20 -11
- package/src/chat/ChatScreen.tsx +160 -35
- package/src/chat/ConversationStack.tsx +1 -1
- package/src/chat/MessageList.tsx +185 -72
- package/src/chat/SessionStatus.tsx +3 -1
- package/src/chat/chatScreenUtils.ts +11 -15
- package/src/chat/chatSessionState.ts +3 -2
- package/src/chat/chatTurnOrchestrator.ts +1 -7
- package/src/chat/commands.ts +28 -27
- package/src/chat/display/DiffView.tsx +193 -0
- package/src/chat/display/SyntaxText.tsx +192 -0
- package/src/chat/display/toolCallDisplay.ts +103 -0
- package/src/chat/display/toolResultDisplay.ts +19 -0
- package/src/chat/{ChatInput.tsx → input/ChatInput.tsx} +36 -23
- package/src/chat/{TranscriptView.tsx → transcript/TranscriptView.tsx} +24 -50
- package/src/chat/{transcriptViewport.ts → transcript/transcriptViewport.ts} +12 -30
- package/src/chat/{ContextLimitView.tsx → views/ContextLimitView.tsx} +3 -3
- package/src/chat/{ContinuityEditReviewView.tsx → views/ContinuityEditReviewView.tsx} +11 -3
- package/src/chat/{CopyPicker.tsx → views/CopyPicker.tsx} +4 -5
- package/src/chat/{PermissionPrompt.tsx → views/PermissionPrompt.tsx} +16 -17
- package/src/chat/{PermissionsView.tsx → views/PermissionsView.tsx} +6 -6
- package/src/chat/{PlanApprovalView.tsx → views/PlanApprovalView.tsx} +4 -4
- package/src/chat/{ResumeView.tsx → views/ResumeView.tsx} +35 -35
- package/src/chat/views/RewindView.tsx +410 -0
- package/src/identity/continuity/privateEdit/diff.ts +2 -78
- package/src/identity/ens/agentRecords.ts +5 -19
- package/src/identity/ens/ensAutomation/setup.ts +0 -1
- package/src/identity/ens/ensAutomation/types.ts +0 -1
- package/src/identity/hub/OperationalRoutes.tsx +23 -32
- package/src/identity/hub/Routes.tsx +13 -13
- package/src/identity/hub/{flows/continuity → continuity}/ContinuityDashboardScreen.tsx +9 -9
- package/src/identity/hub/{flows/continuity → continuity}/RebackupStorageScreen.tsx +2 -2
- package/src/identity/hub/{flows/continuity → continuity}/RecoveryConfirmScreen.tsx +5 -5
- package/src/identity/hub/{flows/continuity → continuity}/SavePromptScreen.tsx +5 -5
- package/src/identity/hub/{effects/rebackup/runRebackup.ts → continuity/effects.ts} +19 -19
- package/src/identity/hub/{effects/rebackup → continuity}/index.ts +1 -1
- package/src/identity/hub/{effects/shared → continuity}/snapshot.ts +8 -8
- package/src/identity/hub/{effects/rebackup → continuity}/vault.ts +15 -15
- package/src/identity/hub/{flows/create → create}/CreateFlow.tsx +13 -13
- package/src/identity/hub/{effects/create.ts → create/effects.ts} +4 -4
- package/src/identity/hub/{flows/custody → custody}/CustodyEditFlow.tsx +10 -48
- package/src/identity/hub/{flows/custody/custodyFlowActions.ts → custody/actions.ts} +11 -9
- package/src/identity/hub/{flows/custody/custodyFlowHelpers.ts → custody/helpers.ts} +4 -4
- package/src/identity/hub/{effects/vault → custody}/preflight.ts +5 -5
- package/src/identity/hub/{flows/custody/custodyFlowRoutes.tsx → custody/routes.tsx} +8 -8
- package/src/identity/hub/{flows/custody/custodyEffects.ts → custody/transactions.ts} +9 -9
- package/src/identity/hub/{flows/custody/custodyFlowTypes.ts → custody/types.ts} +6 -6
- package/src/identity/hub/{flows/custody/custodyFlowEffects.ts → custody/useCustodyEffects.ts} +7 -7
- package/src/identity/hub/{flows/custody → custody}/useCustodyFlow.tsx +5 -5
- package/src/identity/hub/ens/EnsEditAdvancedScreens.tsx +241 -0
- package/src/identity/hub/{flows/ens → ens}/EnsEditFlow.tsx +27 -82
- package/src/identity/hub/{flows/ens → ens}/EnsEditMaintenanceScreens.tsx +25 -65
- package/src/identity/hub/{flows/ens → ens}/EnsEditReviewScreens.tsx +12 -30
- package/src/identity/hub/ens/EnsEditRunners.tsx +62 -0
- package/src/identity/hub/{flows/ens → ens}/EnsEditShared.tsx +15 -14
- package/src/identity/hub/{flows/ens → ens}/EnsEditSimpleScreens.tsx +68 -217
- package/src/identity/hub/{flows/ens/IdentityHubEnsFlow.tsx → ens/EnsFlow.tsx} +18 -11
- package/src/identity/hub/{flows/ens/OperatorWalletsScreen.tsx → ens/EnsOperatorWalletsScreen.tsx} +17 -48
- package/src/identity/hub/{advancedEnsValidation.ts → ens/advancedEnsValidation.ts} +2 -2
- package/src/identity/hub/{flows/ens/ensEditCopy.ts → ens/editCopy.ts} +4 -4
- package/src/identity/hub/{effects/ens/flows.ts → ens/effects.ts} +7 -7
- package/src/identity/hub/{effects/ens → ens}/index.ts +1 -1
- package/src/identity/hub/{model/ens.ts → ens/state.ts} +1 -1
- package/src/identity/hub/{effects/ens → ens}/transactions.ts +232 -232
- package/src/identity/hub/{flows/ens/ensEditTypes.ts → ens/types.ts} +12 -26
- package/src/identity/hub/identityHubReducer.ts +3 -3
- package/src/identity/hub/{flows/profile → profile}/EditProfileFlow.tsx +17 -10
- package/src/identity/hub/{effects/publicProfile/runPublicProfileSave.ts → profile/effects.ts} +55 -177
- package/src/identity/hub/{model → profile}/identity.ts +3 -3
- package/src/identity/hub/{effects/profile/profileState.ts → profile/state.ts} +181 -173
- package/src/identity/hub/{flows/restore → restore}/RestoreFlow.tsx +21 -21
- package/src/identity/hub/{effects/restore → restore}/apply.ts +10 -10
- package/src/identity/hub/{effects/restore → restore}/auth.ts +7 -7
- package/src/identity/hub/{effects/restore → restore}/discover.ts +6 -6
- package/src/identity/hub/{effects/restore → restore}/envelopes.ts +2 -2
- package/src/identity/hub/{effects/restore → restore}/fetch.ts +3 -3
- package/src/identity/hub/{effects/restore/shared.ts → restore/helpers.ts} +6 -6
- package/src/identity/hub/{effects/restore → restore}/recovery.ts +10 -10
- package/src/identity/hub/{effects/restore → restore}/resolve.ts +4 -4
- package/src/identity/hub/restore/restoreAdmin.ts +34 -0
- package/src/identity/hub/{flows/restore/useRestoreFlowEffects.ts → restore/useRestoreEffects.ts} +5 -5
- package/src/identity/hub/{flows/settings → settings}/StorageCredentialScreen.tsx +5 -5
- package/src/identity/hub/{components → shared/components}/BusyScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/DetailsScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/ErrorScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/FlowTimeline.tsx +1 -1
- package/src/identity/hub/{components → shared/components}/IdentitySummary.tsx +16 -11
- package/src/identity/hub/{components → shared/components}/MenuScreen.tsx +8 -9
- package/src/identity/hub/{components → shared/components}/NetworkScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/PinataJwtInput.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/UnlinkedIdentityScreen.tsx +5 -5
- package/src/identity/hub/{components → shared/components}/WalletApprovalScreen.tsx +6 -6
- package/src/identity/hub/{components → shared/components}/menuFlagsFromReconciliation.ts +2 -4
- package/src/identity/hub/{effects/shared → shared/effects}/profilePrep.ts +1 -1
- package/src/identity/hub/{effects → shared/effects}/receipts.ts +2 -2
- package/src/identity/hub/{effects/shared → shared/effects}/sync.ts +6 -47
- package/src/identity/hub/{effects → shared/effects}/types.ts +3 -3
- package/src/identity/hub/{model → shared/model}/copy.ts +2 -2
- package/src/identity/hub/{model → shared/model}/errors.ts +5 -5
- package/src/identity/hub/{model → shared/model}/network.ts +3 -3
- package/src/identity/hub/{operatorWallets.ts → shared/operatorWallets.ts} +1 -1
- package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/hook.ts +1 -2
- package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/ownership.ts +2 -2
- package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/run.ts +7 -40
- package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/types.ts +0 -4
- package/src/identity/hub/{reconciliation → shared/reconciliation}/index.ts +0 -7
- package/src/identity/hub/shared/reconciliation/walletSetup.ts +27 -0
- package/src/identity/hub/{utils.ts → shared/utils.ts} +5 -5
- package/src/identity/hub/{flows/token-transfer/IdentityHubTokenTransferFlow.tsx → transfer/TokenTransferFlow.tsx} +8 -8
- package/src/identity/hub/{flows/token-transfer → transfer}/TokenTransferScreens.tsx +14 -14
- package/src/identity/hub/{effects/token-transfer/runTokenTransfer.ts → transfer/effects.ts} +16 -16
- package/src/identity/hub/{effects/token-transfer → transfer}/progress.ts +1 -1
- package/src/identity/hub/useIdentityHubController.ts +11 -11
- package/src/identity/hub/useIdentityHubSideEffects.ts +11 -11
- package/src/identity/wallet/browserWallet/types.ts +0 -5
- package/src/identity/wallet/page/copy.ts +1 -31
- package/src/identity/wallet/walletPurposeCompat.ts +0 -2
- package/src/models/ModelPicker.tsx +248 -8
- package/src/models/catalog.ts +29 -1
- package/src/models/modelPickerOptions.ts +12 -10
- package/src/models/providerDisplay.ts +16 -0
- package/src/providers/errors.ts +6 -4
- package/src/providers/openai-chat.ts +2 -1
- package/src/providers/openai-responses-format.ts +156 -0
- package/src/providers/openai-responses.ts +276 -0
- package/src/providers/registry.ts +85 -8
- package/src/runtime/sessionMode.ts +1 -1
- package/src/runtime/systemPrompt.ts +4 -2
- package/src/runtime/toolExecution.ts +9 -6
- package/src/runtime/turn.ts +29 -1
- package/src/storage/rewind.ts +20 -0
- package/src/storage/secrets.ts +4 -1
- package/src/storage/sessions.ts +2 -1
- package/src/tools/bashSafety.ts +7 -3
- package/src/tools/bashTool.ts +1 -1
- package/src/tools/contracts.ts +3 -0
- package/src/tools/deleteFileTool.ts +8 -3
- package/src/tools/editTool.ts +10 -5
- package/src/tools/fileDiff.ts +261 -0
- package/src/tools/privateContinuityEditTool.ts +11 -1
- package/src/tools/writeFileTool.ts +8 -3
- package/src/ui/Spinner.tsx +25 -3
- package/src/ui/TextInput.tsx +2 -2
- package/src/ui/theme.ts +17 -0
- package/src/utils/clipboard.ts +10 -7
- package/src/utils/openExternal.ts +20 -10
- package/src/chat/RewindView.tsx +0 -386
- package/src/chat/toolResultDisplay.ts +0 -8
- package/src/identity/ens/ensRegistration.ts +0 -199
- package/src/identity/hub/effects/index.ts +0 -74
- package/src/identity/hub/effects/publicProfile/index.ts +0 -5
- package/src/identity/hub/effects/restore/restoreEffects.ts +0 -22
- package/src/identity/hub/effects/restoreAdmin.ts +0 -93
- package/src/identity/hub/effects/token-transfer/index.ts +0 -6
- package/src/identity/hub/flows/ens/EnsEditAdvancedScreens.tsx +0 -336
- package/src/identity/hub/flows/ens/EnsEditRunners.tsx +0 -198
- package/src/identity/hub/reconciliation/walletSetup.ts +0 -220
- /package/src/chat/{chatInputState.ts → input/chatInputState.ts} +0 -0
- /package/src/chat/{chatPaste.ts → input/chatPaste.ts} +0 -0
- /package/src/chat/{textCursor.ts → input/textCursor.ts} +0 -0
- /package/src/identity/hub/{model/continuity.ts → continuity/state.ts} +0 -0
- /package/src/identity/hub/{model/custody.ts → custody/state.ts} +0 -0
- /package/src/identity/hub/{effects/restore → restore}/index.ts +0 -0
- /package/src/identity/hub/{model → shared/model}/format.ts +0 -0
- /package/src/identity/hub/{reconciliation → shared/reconciliation}/useAgentReconciliation.ts +0 -0
- /package/src/identity/hub/{txGuard.ts → shared/txGuard.ts} +0 -0
- /package/src/identity/hub/{model/transfer.ts → transfer/state.ts} +0 -0
|
@@ -1,37 +1,28 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Box, Text } from 'ink'
|
|
3
|
-
import {
|
|
4
|
-
import { Surface } from '
|
|
5
|
-
import { Select, type SelectOption } from '
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { theme } from '../../../../ui/theme.js'
|
|
3
|
+
import { type Address } from 'viem'
|
|
4
|
+
import { Surface } from '../../../ui/Surface.js'
|
|
5
|
+
import { Select, type SelectOption } from '../../../ui/Select.js'
|
|
6
|
+
import { Spinner } from '../../../ui/Spinner.js'
|
|
7
|
+
import { theme } from '../../../ui/theme.js'
|
|
9
8
|
import {
|
|
10
|
-
createMainnetClient,
|
|
11
9
|
isEthDomain,
|
|
12
10
|
normalizeEthDomain,
|
|
13
|
-
} from '
|
|
11
|
+
} from '../../ens/ensLookup.js'
|
|
12
|
+
import { isRootEthName } from '../../ens/ensAutomation.js'
|
|
13
|
+
import type { Erc8004RegistryConfig } from '../../registry/erc8004.js'
|
|
14
|
+
import type { BrowserWalletReady } from '../../wallet/browserWallet.js'
|
|
14
15
|
import {
|
|
15
|
-
generateRegistrationSecret,
|
|
16
|
-
ONE_YEAR_SECONDS,
|
|
17
|
-
readNameAvailable,
|
|
18
|
-
readRentPrice,
|
|
19
|
-
validateRegistrableName,
|
|
20
|
-
} from '../../../ens/ensRegistration.js'
|
|
21
|
-
import { isRootEthName } from '../../../ens/ensAutomation.js'
|
|
22
|
-
import type { Erc8004RegistryConfig } from '../../../registry/erc8004.js'
|
|
23
|
-
import type { BrowserWalletReady } from '../../../wallet/browserWallet.js'
|
|
24
|
-
import {
|
|
25
|
-
readIdentityStateString,
|
|
26
16
|
type CustodyMode,
|
|
27
|
-
} from '
|
|
28
|
-
import { shortAddress } from '
|
|
17
|
+
} from '../custody/state.js'
|
|
18
|
+
import { shortAddress } from '../shared/model/format.js'
|
|
29
19
|
import {
|
|
30
20
|
recordsDiffHasChanges,
|
|
31
21
|
type EnsLinkOptions,
|
|
32
|
-
} from './
|
|
22
|
+
} from './editCopy.js'
|
|
23
|
+
import { openExternalUrl } from '../../../utils/openExternal.js'
|
|
24
|
+
import { TextInput } from '../../../ui/TextInput.js'
|
|
33
25
|
import {
|
|
34
|
-
EnsSetupRow,
|
|
35
26
|
EnsStatusBanner,
|
|
36
27
|
footerHint,
|
|
37
28
|
SubdomainEntry,
|
|
@@ -42,17 +33,14 @@ import {
|
|
|
42
33
|
ReviewScreen,
|
|
43
34
|
SimpleEnsIssueScreen,
|
|
44
35
|
} from './EnsEditReviewScreens.js'
|
|
45
|
-
import {
|
|
46
|
-
EscCancel,
|
|
47
|
-
RegisterRootCommitRunner,
|
|
48
|
-
RegisterRootTxRunner,
|
|
49
|
-
RegisterRootWaitScreen,
|
|
50
|
-
} from './EnsEditRunners.js'
|
|
36
|
+
import { EscCancel } from './EnsEditRunners.js'
|
|
51
37
|
import type {
|
|
52
38
|
DiscoveryState,
|
|
53
39
|
EnsEditProps,
|
|
54
40
|
EnsPhase,
|
|
55
|
-
} from './
|
|
41
|
+
} from './types.js'
|
|
42
|
+
|
|
43
|
+
const ENS_DOMAINS_URL = 'https://app.ens.domains'
|
|
56
44
|
|
|
57
45
|
type SimpleScreenProps = {
|
|
58
46
|
phase: EnsPhase
|
|
@@ -69,8 +57,9 @@ type SimpleScreenProps = {
|
|
|
69
57
|
setOperatorWalletSession: (session: BrowserWalletReady | null) => void
|
|
70
58
|
setPhase: (phase: EnsPhase) => void
|
|
71
59
|
cancelDiscoveryToModeSelect: () => void
|
|
72
|
-
runDiscovery: () => void
|
|
60
|
+
runDiscovery: (mode?: 'simple' | 'advanced') => void
|
|
73
61
|
runValidation: (fullName: string, mode: 'simple' | 'advanced', phaseOwnerAddress?: Address, operatorWallet?: Address) => Promise<void>
|
|
62
|
+
runAdvancedRootCheck: (rootName: string) => void
|
|
74
63
|
backToSimpleSubdomain: (fullName: string) => void
|
|
75
64
|
runSimpleCreatePreflight: (fullName: string) => void
|
|
76
65
|
onEnsSetup: EnsEditProps['onEnsSetup']
|
|
@@ -96,6 +85,7 @@ export function renderSimpleEnsPhase({
|
|
|
96
85
|
cancelDiscoveryToModeSelect,
|
|
97
86
|
runDiscovery,
|
|
98
87
|
runValidation,
|
|
88
|
+
runAdvancedRootCheck,
|
|
99
89
|
backToSimpleSubdomain,
|
|
100
90
|
runSimpleCreatePreflight,
|
|
101
91
|
onEnsSetup,
|
|
@@ -126,7 +116,7 @@ export function renderSimpleEnsPhase({
|
|
|
126
116
|
}
|
|
127
117
|
|
|
128
118
|
if (phase.kind === 'pick-parent') {
|
|
129
|
-
type DomainAction = `pick:${string}` | '
|
|
119
|
+
type DomainAction = `pick:${string}` | 'open-ens-domains' | 'manual' | 'retry' | 'back'
|
|
130
120
|
const ownedNames = discovery.status === 'ok' || discovery.status === 'error' ? discovery.names : []
|
|
131
121
|
const errorMessage = discovery.status === 'error' ? 'Root ENS Lookup Failed' : null
|
|
132
122
|
const warningMessage = discovery.status === 'ok' ? discovery.warning : null
|
|
@@ -144,10 +134,10 @@ export function renderSimpleEnsPhase({
|
|
|
144
134
|
})),
|
|
145
135
|
]
|
|
146
136
|
: []),
|
|
147
|
-
{ value: '
|
|
148
|
-
{ value: '
|
|
149
|
-
...(noOwnedNames
|
|
150
|
-
? [{ value: 'retry' as DomainAction, label: 'Scan Again', hint: '
|
|
137
|
+
{ value: 'open-ens-domains' as DomainAction, role: 'section' as const, label: 'No Parent Name?' },
|
|
138
|
+
{ value: 'open-ens-domains' as DomainAction, label: 'Register .eth Name', hint: 'Open the ENS app in your browser; come back when this wallet owns one' },
|
|
139
|
+
...(noOwnedNames || discovery.status === 'ok'
|
|
140
|
+
? [{ value: 'retry' as DomainAction, label: 'Scan Again', hint: 'Re-run root .eth name discovery for this wallet' }]
|
|
151
141
|
: []),
|
|
152
142
|
...(discovery.status === 'error'
|
|
153
143
|
? [
|
|
@@ -159,6 +149,7 @@ export function renderSimpleEnsPhase({
|
|
|
159
149
|
{ value: 'back', label: 'Back', hint: 'Return to setup type', role: 'utility' },
|
|
160
150
|
]
|
|
161
151
|
|
|
152
|
+
const advancedMode = phase.mode === 'advanced'
|
|
162
153
|
return (
|
|
163
154
|
<Surface
|
|
164
155
|
title="Assign ENS Name"
|
|
@@ -166,198 +157,45 @@ export function renderSimpleEnsPhase({
|
|
|
166
157
|
footer={footerHint('enter select · esc back')}
|
|
167
158
|
>
|
|
168
159
|
<EnsStatusBanner identity={identity} noRootEnsName={noOwnedNames} />
|
|
160
|
+
{advancedMode
|
|
161
|
+
? <Text color={theme.dim}>Owner wallet: <Text color={theme.text}>{shortAddress(ownerAddress)}</Text></Text>
|
|
162
|
+
: null}
|
|
169
163
|
{validationError ? <Text color={theme.accentError}>{validationError}</Text> : null}
|
|
164
|
+
{phase.error ? <Text color={theme.accentError}>{phase.error}</Text> : null}
|
|
170
165
|
{errorMessage ? <Text color={theme.accentError}>{errorMessage}: {discovery.status === 'error' ? discovery.message : ''}</Text> : null}
|
|
171
166
|
{warningMessage ? <Text color={theme.accentPeriwinkle}>{warningMessage}</Text> : null}
|
|
167
|
+
{noOwnedNames
|
|
168
|
+
? (
|
|
169
|
+
<Box marginTop={1} flexDirection="column">
|
|
170
|
+
<Text color={theme.dim}>This wallet does not own a parent <Text color={theme.text}>.eth</Text> name yet.</Text>
|
|
171
|
+
<Text color={theme.dim}>Register one at <Text color={theme.text}>{ENS_DOMAINS_URL}</Text>, then come back and Scan Again.</Text>
|
|
172
|
+
</Box>
|
|
173
|
+
)
|
|
174
|
+
: null}
|
|
172
175
|
<Box marginTop={1}>
|
|
173
176
|
<Select<DomainAction>
|
|
174
177
|
options={options}
|
|
175
178
|
hintLayout="inline"
|
|
176
179
|
onSubmit={choice => {
|
|
177
180
|
if (choice === 'back') return setPhase({ kind: 'mode-select' })
|
|
178
|
-
if (choice === 'manual') { setPhase({ kind: 'manual-parent' }); return }
|
|
179
|
-
if (choice === '
|
|
181
|
+
if (choice === 'manual') { setPhase({ kind: 'manual-parent', ...(advancedMode ? { mode: 'advanced' as const } : {}) }); return }
|
|
182
|
+
if (choice === 'open-ens-domains') {
|
|
183
|
+
openExternalUrl(ENS_DOMAINS_URL)
|
|
184
|
+
return
|
|
185
|
+
}
|
|
180
186
|
if (choice === 'retry') {
|
|
181
|
-
runDiscovery()
|
|
187
|
+
runDiscovery(advancedMode ? 'advanced' : 'simple')
|
|
182
188
|
return
|
|
183
189
|
}
|
|
184
190
|
if (choice.startsWith('pick:')) {
|
|
185
191
|
const name = choice.slice('pick:'.length)
|
|
186
|
-
if (name)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
</Surface>
|
|
193
|
-
)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (phase.kind === 'register-root-input') {
|
|
197
|
-
return (
|
|
198
|
-
<Surface
|
|
199
|
-
title="Register an ENS Name"
|
|
200
|
-
subtitle="Pick a name to register on Ethereum mainnet for 1 year. The connected wallet pays and becomes the owner."
|
|
201
|
-
footer={footerHint('enter continues · esc back')}
|
|
202
|
-
>
|
|
203
|
-
{phase.error ? <Text color={theme.accentError}>{phase.error}</Text> : null}
|
|
204
|
-
<Box marginTop={1}>
|
|
205
|
-
<TextInput
|
|
206
|
-
placeholder="myname"
|
|
207
|
-
validate={value => {
|
|
208
|
-
const result = validateRegistrableName(value)
|
|
209
|
-
return result.ok ? null : result.detail
|
|
210
|
-
}}
|
|
211
|
-
onSubmit={value => {
|
|
212
|
-
const result = validateRegistrableName(value)
|
|
213
|
-
if (!result.ok) {
|
|
214
|
-
setPhase({ kind: 'register-root-input', error: result.detail })
|
|
215
|
-
return
|
|
216
|
-
}
|
|
217
|
-
const secret = generateRegistrationSecret()
|
|
218
|
-
setPhase({ kind: 'register-root-pricing', label: result.label, secret, busy: true })
|
|
219
|
-
const client = createMainnetClient()
|
|
220
|
-
Promise.all([
|
|
221
|
-
readNameAvailable(client, result.label),
|
|
222
|
-
readRentPrice(client, result.label, BigInt(ONE_YEAR_SECONDS)),
|
|
223
|
-
])
|
|
224
|
-
.then(([available, price]) => {
|
|
225
|
-
if (!available) {
|
|
226
|
-
setPhase({ kind: 'register-root-input', error: `${result.label}.eth is already registered. Pick a different name.` })
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
setPhase({ kind: 'register-root-pricing', label: result.label, secret, busy: false, price })
|
|
230
|
-
})
|
|
231
|
-
.catch((err: unknown) => {
|
|
232
|
-
setPhase({ kind: 'register-root-input', error: err instanceof Error ? err.message : String(err) })
|
|
233
|
-
})
|
|
234
|
-
}}
|
|
235
|
-
onCancel={() => setPhase({ kind: 'pick-parent' })}
|
|
236
|
-
/>
|
|
237
|
-
</Box>
|
|
238
|
-
</Surface>
|
|
239
|
-
)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (phase.kind === 'register-root-pricing') {
|
|
243
|
-
const fullName = `${phase.label}.eth`
|
|
244
|
-
if (phase.busy || !phase.price) {
|
|
245
|
-
return (
|
|
246
|
-
<Surface
|
|
247
|
-
title="Register an ENS Name"
|
|
248
|
-
subtitle={`Checking availability and price for ${fullName}...`}
|
|
249
|
-
footer={footerHint('esc back')}
|
|
250
|
-
>
|
|
251
|
-
<Box marginTop={1}><Text color={theme.textSubtle}>Reading from Ethereum mainnet...</Text></Box>
|
|
252
|
-
</Surface>
|
|
253
|
-
)
|
|
254
|
-
}
|
|
255
|
-
const totalEth = formatEther(phase.price.total)
|
|
256
|
-
const baseEth = formatEther(phase.price.base)
|
|
257
|
-
const premiumEth = formatEther(phase.price.premium)
|
|
258
|
-
return (
|
|
259
|
-
<Surface
|
|
260
|
-
title="Register an ENS Name"
|
|
261
|
-
subtitle={`${fullName} is available. Review the cost and continue with two transactions.`}
|
|
262
|
-
footer={footerHint('enter select · esc back')}
|
|
263
|
-
>
|
|
264
|
-
<Box flexDirection="column">
|
|
265
|
-
<EnsSetupRow label="Name" value={fullName} />
|
|
266
|
-
<EnsSetupRow label="Owner" value={shortAddress(ownerAddress)} />
|
|
267
|
-
<EnsSetupRow label="Duration" value="1 year" />
|
|
268
|
-
<EnsSetupRow label="Rent" value={`${baseEth} ETH`} />
|
|
269
|
-
{phase.price.premium > 0n ? <EnsSetupRow label="Premium" value={`${premiumEth} ETH`} /> : null}
|
|
270
|
-
<EnsSetupRow label="Total" value={`${totalEth} ETH`} />
|
|
271
|
-
<Box marginTop={1}><Text color={theme.dim}>Two transactions: a commit, a 60-second wait, then the registration. Keep this tab open through both.</Text></Box>
|
|
272
|
-
<Box marginTop={1}><Text color={theme.dim}>Manage renewals on https://app.ens.domains/ before the year is up.</Text></Box>
|
|
273
|
-
</Box>
|
|
274
|
-
<Box marginTop={1}>
|
|
275
|
-
<Select<'commit' | 'pick-different' | 'back'>
|
|
276
|
-
options={[
|
|
277
|
-
{ value: 'commit', role: 'section', label: 'Continue' },
|
|
278
|
-
{ value: 'commit', label: 'Continue to Commit', hint: 'Sign the first transaction' },
|
|
279
|
-
{ value: 'pick-different', label: 'Pick a Different Name', hint: 'Return to name input' },
|
|
280
|
-
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
281
|
-
{ value: 'back', label: 'Back', hint: 'Return to root selection', role: 'utility' },
|
|
282
|
-
]}
|
|
283
|
-
hintLayout="inline"
|
|
284
|
-
onSubmit={choice => {
|
|
285
|
-
if (choice === 'commit') {
|
|
286
|
-
setPhase({ kind: 'register-root-commit-tx', label: phase.label, secret: phase.secret, price: phase.price! })
|
|
287
|
-
return
|
|
192
|
+
if (!name) return
|
|
193
|
+
if (advancedMode) {
|
|
194
|
+
runAdvancedRootCheck(name)
|
|
195
|
+
return
|
|
196
|
+
}
|
|
197
|
+
setPhase({ kind: 'pick-subdomain', parent: name })
|
|
288
198
|
}
|
|
289
|
-
if (choice === 'pick-different') return setPhase({ kind: 'register-root-input' })
|
|
290
|
-
setPhase({ kind: 'pick-parent' })
|
|
291
|
-
}}
|
|
292
|
-
onCancel={() => setPhase({ kind: 'pick-parent' })}
|
|
293
|
-
/>
|
|
294
|
-
</Box>
|
|
295
|
-
</Surface>
|
|
296
|
-
)
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (phase.kind === 'register-root-commit-tx') {
|
|
300
|
-
return (
|
|
301
|
-
<RegisterRootCommitRunner
|
|
302
|
-
phase={phase}
|
|
303
|
-
ownerAddress={ownerAddress}
|
|
304
|
-
walletSession={operatorWalletSession}
|
|
305
|
-
onWalletReady={setOperatorWalletSession}
|
|
306
|
-
onCommitted={() => setPhase({ kind: 'register-root-wait', label: phase.label, secret: phase.secret, price: phase.price, commitMinedAt: Date.now() })}
|
|
307
|
-
onError={msg => setPhase({ kind: 'register-root-input', error: msg })}
|
|
308
|
-
/>
|
|
309
|
-
)
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (phase.kind === 'register-root-wait') {
|
|
313
|
-
return (
|
|
314
|
-
<RegisterRootWaitScreen
|
|
315
|
-
phase={phase}
|
|
316
|
-
onReady={() => setPhase({ kind: 'register-root-tx', label: phase.label, secret: phase.secret, price: phase.price })}
|
|
317
|
-
onCancel={() => setPhase({ kind: 'register-root-input', error: 'Commit cancelled. Names must be re-committed; secrets do not carry over.' })}
|
|
318
|
-
/>
|
|
319
|
-
)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (phase.kind === 'register-root-tx') {
|
|
323
|
-
return (
|
|
324
|
-
<RegisterRootTxRunner
|
|
325
|
-
phase={phase}
|
|
326
|
-
ownerAddress={ownerAddress}
|
|
327
|
-
walletSession={operatorWalletSession}
|
|
328
|
-
onWalletReady={setOperatorWalletSession}
|
|
329
|
-
onRegistered={() => setPhase({ kind: 'register-root-done', fullName: `${phase.label}.eth` })}
|
|
330
|
-
onError={msg => setPhase({ kind: 'register-root-input', error: msg })}
|
|
331
|
-
/>
|
|
332
|
-
)
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (phase.kind === 'register-root-done') {
|
|
336
|
-
return (
|
|
337
|
-
<Surface
|
|
338
|
-
title="ENS Name Registered"
|
|
339
|
-
subtitle={`${phase.fullName} is now owned by ${shortAddress(ownerAddress)}.`}
|
|
340
|
-
footer={footerHint('enter select · esc back')}
|
|
341
|
-
>
|
|
342
|
-
<Box flexDirection="column">
|
|
343
|
-
<Text color={theme.text}>Manage renewals and other settings on https://app.ens.domains/ before the year is up.</Text>
|
|
344
|
-
<Text color={theme.dim}>The name will appear in the picker on the next scan.</Text>
|
|
345
|
-
</Box>
|
|
346
|
-
<Box marginTop={1}>
|
|
347
|
-
<Select<'scan' | 'back'>
|
|
348
|
-
options={[
|
|
349
|
-
{ value: 'scan', role: 'section', label: 'Next' },
|
|
350
|
-
{ value: 'scan', label: 'Scan Again', hint: 'Re-run root ENS name discovery' },
|
|
351
|
-
{ value: 'back', role: 'section', label: 'Navigation' },
|
|
352
|
-
{ value: 'back', label: 'Back to ENS', hint: 'Return to ENS menu', role: 'utility' },
|
|
353
|
-
]}
|
|
354
|
-
hintLayout="inline"
|
|
355
|
-
onSubmit={choice => {
|
|
356
|
-
if (choice === 'scan') {
|
|
357
|
-
runDiscovery()
|
|
358
|
-
return
|
|
359
|
-
}
|
|
360
|
-
setPhase({ kind: 'mode-select' })
|
|
361
199
|
}}
|
|
362
200
|
onCancel={() => setPhase({ kind: 'mode-select' })}
|
|
363
201
|
/>
|
|
@@ -367,6 +205,7 @@ export function renderSimpleEnsPhase({
|
|
|
367
205
|
}
|
|
368
206
|
|
|
369
207
|
if (phase.kind === 'manual-parent') {
|
|
208
|
+
const advancedMode = phase.mode === 'advanced'
|
|
370
209
|
return (
|
|
371
210
|
<Surface
|
|
372
211
|
title="Your Root .eth Name"
|
|
@@ -374,11 +213,15 @@ export function renderSimpleEnsPhase({
|
|
|
374
213
|
footer={footerHint('enter continues · esc back')}
|
|
375
214
|
>
|
|
376
215
|
{statusBanner}
|
|
216
|
+
{advancedMode
|
|
217
|
+
? <Text color={theme.dim}>Owner wallet: <Text color={theme.text}>{shortAddress(ownerAddress)}</Text></Text>
|
|
218
|
+
: null}
|
|
377
219
|
<Box marginTop={1}>
|
|
378
220
|
<Text color={theme.dim}>Only root .eth names on Ethereum mainnet are supported.</Text>
|
|
379
221
|
</Box>
|
|
222
|
+
{phase.error ? <Text color={theme.accentError}>{phase.error}</Text> : null}
|
|
380
223
|
<TextInput
|
|
381
|
-
key=
|
|
224
|
+
key={`edit-ens-parent-manual-${advancedMode ? 'advanced' : 'simple'}`}
|
|
382
225
|
placeholder="e.g. name.eth"
|
|
383
226
|
validate={value => {
|
|
384
227
|
const v = normalizeEthDomain(value)
|
|
@@ -387,8 +230,15 @@ export function renderSimpleEnsPhase({
|
|
|
387
230
|
if (!isRootEthName(v)) return 'Enter a root .eth name, e.g. name.eth'
|
|
388
231
|
return null
|
|
389
232
|
}}
|
|
390
|
-
onSubmit={value =>
|
|
391
|
-
|
|
233
|
+
onSubmit={value => {
|
|
234
|
+
const root = normalizeEthDomain(value)
|
|
235
|
+
if (advancedMode) {
|
|
236
|
+
runAdvancedRootCheck(root)
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
setPhase({ kind: 'pick-subdomain', parent: root })
|
|
240
|
+
}}
|
|
241
|
+
onCancel={() => setPhase({ kind: 'pick-parent', ...(advancedMode ? { mode: 'advanced' as const } : {}) })}
|
|
392
242
|
/>
|
|
393
243
|
</Surface>
|
|
394
244
|
)
|
|
@@ -399,7 +249,8 @@ export function renderSimpleEnsPhase({
|
|
|
399
249
|
<SubdomainEntry
|
|
400
250
|
parent={phase.parent}
|
|
401
251
|
ownerAddress={ownerAddress}
|
|
402
|
-
|
|
252
|
+
initialValue={phase.label}
|
|
253
|
+
placeholder={agentNameSuggestion || 'subdomain name'}
|
|
403
254
|
error={phase.error}
|
|
404
255
|
onConfirm={fullName => { void runValidation(fullName, 'simple') }}
|
|
405
256
|
onBack={() => setPhase({ kind: 'pick-parent' })}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { openImageFilePicker } from '
|
|
3
|
-
import { readOwnerAddressField } from '
|
|
4
|
-
import type { BrowserWalletReady } from '
|
|
5
|
-
import type { ProfileUpdates, Step } from '
|
|
6
|
-
import { readCustodyMode } from '
|
|
7
|
-
import { OperatorWalletsScreen } from './
|
|
2
|
+
import { openImageFilePicker } from '../../profile/imagePicker.js'
|
|
3
|
+
import { readOwnerAddressField } from '../../identityCompat.js'
|
|
4
|
+
import type { BrowserWalletReady } from '../../wallet/browserWallet.js'
|
|
5
|
+
import type { ProfileUpdates, Step } from '../identityHubReducer.js'
|
|
6
|
+
import { readCustodyMode } from '../custody/state.js'
|
|
7
|
+
import { OperatorWalletsScreen } from './EnsOperatorWalletsScreen.js'
|
|
8
8
|
import { EDIT_PROFILE_STEPS, EditProfileFlow } from '../profile/EditProfileFlow.js'
|
|
9
|
-
import { FlowTimeline } from '
|
|
10
|
-
import { WalletApprovalScreen } from '
|
|
9
|
+
import { FlowTimeline } from '../shared/components/FlowTimeline.js'
|
|
10
|
+
import { WalletApprovalScreen } from '../shared/components/WalletApprovalScreen.js'
|
|
11
|
+
import type { AgentReconciliation } from '../shared/reconciliation/index.js'
|
|
11
12
|
|
|
12
13
|
type StepOf<K extends Step['kind']> = Extract<Step, { kind: K }>
|
|
13
14
|
|
|
@@ -24,17 +25,19 @@ type IdentityHubEnsStep = StepOf<
|
|
|
24
25
|
| 'public-profile-signing'
|
|
25
26
|
>
|
|
26
27
|
|
|
27
|
-
type
|
|
28
|
+
type EnsFlowProps = {
|
|
28
29
|
step: IdentityHubEnsStep
|
|
29
30
|
walletSession: BrowserWalletReady | null
|
|
31
|
+
reconciliation: AgentReconciliation
|
|
30
32
|
onSetStep: (step: Step) => void
|
|
31
33
|
onBack: () => void
|
|
32
34
|
onWalletReady: (session: BrowserWalletReady | null) => void
|
|
33
35
|
onTriggerRebackup: (backStep: Step, profileUpdates?: ProfileUpdates) => void
|
|
34
36
|
onTriggerPublicProfileSave: (backStep: Step, profileUpdates: ProfileUpdates) => void
|
|
37
|
+
onWithdrawTokenForEns: (step: Step) => void
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
export function
|
|
40
|
+
export function isEnsStep(step: Step): step is IdentityHubEnsStep {
|
|
38
41
|
return step.kind === 'manage-ens-operators'
|
|
39
42
|
|| step.kind === 'edit-profile-name'
|
|
40
43
|
|| step.kind === 'edit-profile-description'
|
|
@@ -47,14 +50,16 @@ export function isIdentityHubEnsStep(step: Step): step is IdentityHubEnsStep {
|
|
|
47
50
|
|| step.kind === 'public-profile-signing'
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
export const
|
|
53
|
+
export const EnsFlow: React.FC<EnsFlowProps> = ({
|
|
51
54
|
step,
|
|
52
55
|
walletSession,
|
|
56
|
+
reconciliation,
|
|
53
57
|
onSetStep,
|
|
54
58
|
onBack,
|
|
55
59
|
onWalletReady,
|
|
56
60
|
onTriggerRebackup,
|
|
57
61
|
onTriggerPublicProfileSave,
|
|
62
|
+
onWithdrawTokenForEns,
|
|
58
63
|
}) => {
|
|
59
64
|
if (step.kind === 'manage-ens-operators') {
|
|
60
65
|
return (
|
|
@@ -75,6 +80,8 @@ export const IdentityHubEnsFlow: React.FC<IdentityHubEnsFlowProps> = ({
|
|
|
75
80
|
return (
|
|
76
81
|
<EditProfileFlow
|
|
77
82
|
step={step}
|
|
83
|
+
reconciliation={reconciliation}
|
|
84
|
+
onWithdrawToken={() => onWithdrawTokenForEns(step)}
|
|
78
85
|
onNameSubmit={name => {
|
|
79
86
|
if (step.kind !== 'edit-profile-name') return
|
|
80
87
|
onSetStep({
|
package/src/identity/hub/{flows/ens/OperatorWalletsScreen.tsx → ens/EnsOperatorWalletsScreen.tsx}
RENAMED
|
@@ -1,35 +1,31 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Box, Text } from 'ink'
|
|
3
3
|
import { getAddress, isAddress, type Address } from 'viem'
|
|
4
|
-
import { Surface } from '
|
|
5
|
-
import { Select, type SelectOption } from '
|
|
6
|
-
import { Spinner } from '
|
|
7
|
-
import { theme } from '
|
|
8
|
-
import { useAppInput } from '
|
|
9
|
-
import { openExternalUrl } from '
|
|
10
|
-
import type { EthagentIdentity } from '
|
|
11
|
-
import { readOwnerAddressField } from '
|
|
12
|
-
import type { Erc8004RegistryConfig } from '
|
|
4
|
+
import { Surface } from '../../../ui/Surface.js'
|
|
5
|
+
import { Select, type SelectOption } from '../../../ui/Select.js'
|
|
6
|
+
import { Spinner } from '../../../ui/Spinner.js'
|
|
7
|
+
import { theme } from '../../../ui/theme.js'
|
|
8
|
+
import { useAppInput } from '../../../app/input/AppInputProvider.js'
|
|
9
|
+
import { openExternalUrl } from '../../../utils/openExternal.js'
|
|
10
|
+
import type { EthagentIdentity } from '../../../storage/config.js'
|
|
11
|
+
import { readOwnerAddressField } from '../../identityCompat.js'
|
|
12
|
+
import type { Erc8004RegistryConfig } from '../../registry/erc8004.js'
|
|
13
13
|
import {
|
|
14
14
|
createWalletRestoreAccessChallenge,
|
|
15
15
|
createWalletRestoreAccessKey,
|
|
16
|
-
} from '
|
|
17
|
-
import { requestBrowserWalletSignature, type BrowserWalletReady } from '
|
|
18
|
-
import { FlowTimeline } from '
|
|
19
|
-
import { OPEN_BROWSER_HINT } from '
|
|
20
|
-
import { readCustodyMode } from '
|
|
21
|
-
import { shortAddress } from '
|
|
22
|
-
import type { ProfileUpdates } from '
|
|
16
|
+
} from '../../continuity/envelope.js'
|
|
17
|
+
import { requestBrowserWalletSignature, type BrowserWalletReady } from '../../wallet/browserWallet.js'
|
|
18
|
+
import { FlowTimeline } from '../shared/components/FlowTimeline.js'
|
|
19
|
+
import { OPEN_BROWSER_HINT } from '../shared/components/WalletApprovalScreen.js'
|
|
20
|
+
import { readCustodyMode } from '../custody/state.js'
|
|
21
|
+
import { shortAddress } from '../shared/model/format.js'
|
|
22
|
+
import type { ProfileUpdates } from '../identityHubReducer.js'
|
|
23
23
|
import {
|
|
24
24
|
normalizeApprovedOperatorWallets,
|
|
25
25
|
removeApprovedOperatorWallet,
|
|
26
26
|
upsertApprovedOperatorWallet,
|
|
27
27
|
type ApprovedOperatorWalletRecord,
|
|
28
|
-
} from '
|
|
29
|
-
import {
|
|
30
|
-
reconcileWalletSetup,
|
|
31
|
-
type RecordsFixPlan,
|
|
32
|
-
} from '../../reconciliation/index.js'
|
|
28
|
+
} from '../shared/operatorWallets.js'
|
|
33
29
|
|
|
34
30
|
type OperatorPhase =
|
|
35
31
|
| { kind: 'main'; notice?: string; error?: string }
|
|
@@ -71,28 +67,11 @@ export const OperatorWalletsScreen: React.FC<OperatorWalletsScreenProps> = ({
|
|
|
71
67
|
const restoreAccessEpoch = readStateNumber(state, 'restoreAccessEpoch') ?? 0
|
|
72
68
|
const records = normalizeApprovedOperatorWallets(state.approvedOperatorWallets)
|
|
73
69
|
const [phase, setPhase] = React.useState<OperatorPhase>({ kind: 'main', notice, error })
|
|
74
|
-
const [fixPlan, setFixPlan] = React.useState<RecordsFixPlan | null>(null)
|
|
75
70
|
|
|
76
71
|
React.useEffect(() => {
|
|
77
72
|
setPhase(current => current.kind === 'main' ? { kind: 'main', notice, error } : current)
|
|
78
73
|
}, [notice, error])
|
|
79
74
|
|
|
80
|
-
React.useEffect(() => {
|
|
81
|
-
if (custodyMode !== 'advanced' || records.length === 0) {
|
|
82
|
-
setFixPlan(null)
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
let cancelled = false
|
|
86
|
-
reconcileWalletSetup({ identity, registry })
|
|
87
|
-
.then(plan => { if (!cancelled) setFixPlan(plan) })
|
|
88
|
-
.catch(() => { if (!cancelled) setFixPlan(null) })
|
|
89
|
-
return () => { cancelled = true }
|
|
90
|
-
}, [identity, registry, custodyMode, records.length])
|
|
91
|
-
|
|
92
|
-
const driftItems = fixPlan?.items.filter(item =>
|
|
93
|
-
item.kind === 'missing-approval' || item.kind === 'stale-approval',
|
|
94
|
-
) ?? []
|
|
95
|
-
|
|
96
75
|
const saveOperators = React.useCallback((
|
|
97
76
|
approvedOperatorWallets: ApprovedOperatorWalletRecord[],
|
|
98
77
|
activeOperator: Address | '' | undefined,
|
|
@@ -253,16 +232,6 @@ export const OperatorWalletsScreen: React.FC<OperatorWalletsScreenProps> = ({
|
|
|
253
232
|
<Text color={theme.dim}>Add as many operator wallets as needed; unlink any saved wallet here.</Text>
|
|
254
233
|
<Text color={theme.dim}>No approve(), setApprovalForAll(), transferFrom(), or token approval is requested.</Text>
|
|
255
234
|
</Box>
|
|
256
|
-
{driftItems.length > 0
|
|
257
|
-
? (
|
|
258
|
-
<Box marginTop={1} flexDirection="column">
|
|
259
|
-
<Text color="#e8a070">
|
|
260
|
-
{`! ENS resolver drift: ${driftItems.length} operator wallet${driftItems.length === 1 ? '' : 's'} missing onchain approval.`}
|
|
261
|
-
</Text>
|
|
262
|
-
<Text color={theme.dim}>Run "Fix Records" from Custody Mode to re-sync; onchain ENS writes will fail until then.</Text>
|
|
263
|
-
</Box>
|
|
264
|
-
)
|
|
265
|
-
: null}
|
|
266
235
|
{phaseNotice ? <Text color={theme.accentPeriwinkle}>{phaseNotice}</Text> : null}
|
|
267
236
|
{phaseError ? <Text color={theme.accentError}>{phaseError}</Text> : null}
|
|
268
237
|
</Box>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getAddress, type Address, type PublicClient } from 'viem'
|
|
2
|
-
import { validateAgentEnsLink, type DiscoverOptions, type EnsValidation } from '
|
|
2
|
+
import { validateAgentEnsLink, type DiscoverOptions, type EnsValidation } from '../../ens/ensLookup.js'
|
|
3
3
|
import {
|
|
4
4
|
validateErc8004TokenOwner,
|
|
5
5
|
type Erc8004RegistryConfig,
|
|
6
|
-
} from '
|
|
6
|
+
} from '../../registry/erc8004.js'
|
|
7
7
|
|
|
8
8
|
type TokenOwnerReadClient = Pick<PublicClient, 'readContract'>
|
|
9
9
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getAddress, type Address } from 'viem'
|
|
2
|
-
import type { AgentEnsRecords, AgentRecordDiff } from '
|
|
3
|
-
import type { EnsRegistryAction, EnsSetupBlockedPlan } from '
|
|
4
|
-
import type { CustodyMode } from '
|
|
2
|
+
import type { AgentEnsRecords, AgentRecordDiff } from '../../ens/agentRecords.js'
|
|
3
|
+
import type { EnsRegistryAction, EnsSetupBlockedPlan } from '../../ens/ensAutomation.js'
|
|
4
|
+
import type { CustodyMode } from '../custody/state.js'
|
|
5
5
|
|
|
6
6
|
export type EnsLinkOptions = {
|
|
7
7
|
mode: 'simple' | 'advanced'
|
|
@@ -18,7 +18,7 @@ export function recordsHaveCurrentValues(recordsDiff: AgentRecordDiff[]): boolea
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function emptyAgentEnsRecords(): AgentEnsRecords {
|
|
21
|
-
return { token: ''
|
|
21
|
+
return { token: '' }
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function unlinkEnsLinkOptions(savedCustodyMode: CustodyMode | undefined, savedOwnerAddress: string): EnsLinkOptions {
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { Address, PublicClient } from 'viem'
|
|
2
|
-
import type { EthagentIdentity } from '
|
|
3
|
-
import type { AgentEnsRecordState, AgentEnsRecords } from '
|
|
4
|
-
import type { Erc8004RegistryConfig } from '
|
|
2
|
+
import type { EthagentIdentity } from '../../../storage/config.js'
|
|
3
|
+
import type { AgentEnsRecordState, AgentEnsRecords } from '../../ens/agentRecords.js'
|
|
4
|
+
import type { Erc8004RegistryConfig } from '../../registry/erc8004.js'
|
|
5
5
|
import {
|
|
6
6
|
openBrowserWalletSession,
|
|
7
7
|
type WalletPurpose,
|
|
8
|
-
} from '
|
|
9
|
-
import type { ProfileUpdates, Step } from '
|
|
10
|
-
import type { EffectCallbacks, EnsClearProgress, EnsLinkProgress, EnsUpdateProgress } from '../types.js'
|
|
8
|
+
} from '../../wallet/browserWallet.js'
|
|
9
|
+
import type { ProfileUpdates, Step } from '../identityHubReducer.js'
|
|
10
|
+
import type { EffectCallbacks, EnsClearProgress, EnsLinkProgress, EnsUpdateProgress } from '../shared/effects/types.js'
|
|
11
11
|
import {
|
|
12
12
|
runEnsSetupRecordsTransaction,
|
|
13
13
|
runEnsSetupRegistryTransaction,
|
|
14
14
|
runUpdateEnsRecords,
|
|
15
15
|
} from './transactions.js'
|
|
16
|
-
import { runRebackupSigningInSession } from '../
|
|
16
|
+
import { runRebackupSigningInSession } from '../continuity/effects.js'
|
|
17
17
|
|
|
18
18
|
type EnsRecordsFlowArgs = {
|
|
19
19
|
identity: EthagentIdentity
|