import React from 'react' import { Box, Text } from 'ink' import type { Address } from 'viem' import { Surface } from '../../../ui/Surface.js' import { TextInput } from '../../../ui/TextInput.js' import { theme } from '../../../ui/theme.js' import { isEthDomain, sanitizeSubdomainPrefix, } from '../../ens/ensLookup.js' import { displayCustodyMode, readIdentityStateString, type CustodyMode, } from '../custody/state.js' import { ensValidationReasonText } from './state.js' import { shortAddress } from '../shared/model/format.js' import { FieldRow } from '../shared/components/FieldRow.js' import { readValidationFromState } from './editCopy.js' import type { EnsEditProps } from './types.js' export const footerHint = (hint: string) => {hint} import { abbreviateRecordValue } from './editCopy.js' export const renderRecordValue = (value: string) => value ? {abbreviateRecordValue(value)} : Unset export function rootErrorMessage( reason: 'invalid-root' | 'missing-token-id' | 'root-not-owned' | 'wrapped-parent' | 'root-owner-mismatch' | 'token-owner-mismatch' | 'token-owner-lookup-failed' | 'lookup-failed', detail: string, rootName: string, ): string { switch (reason) { case 'invalid-root': return 'Enter the parent .eth name, e.g. name.eth' case 'missing-token-id': return 'This identity is missing an ERC-8004 token id' case 'root-not-owned': return `${rootName} does not have an ENS manager on Ethereum mainnet. Switch wallets or pick a different parent name.` case 'wrapped-parent': return `${rootName} ENS NameWrapper ownership could not be verified: ${detail}` case 'root-owner-mismatch': return `Connected wallet does not manage ${rootName}. ${detail}` case 'token-owner-mismatch': return `Connected wallet manages ${rootName} but does not own this ERC-8004 token. ${detail}. Move the token to this wallet, then submit again.` case 'token-owner-lookup-failed': return `Could not verify ERC-8004 token owner: ${detail}` case 'lookup-failed': return `ENS lookup failed: ${detail}` } } export const EnsSetupRow: React.FC<{ label: string; value: string; muted?: boolean }> = ({ label, value, muted }) => ( {label} {value} ) export const EnsStatusBanner: React.FC<{ identity: EnsEditProps['identity']; noRootEnsName?: boolean }> = ({ identity, noRootEnsName }) => { const ensName = readIdentityStateString(identity.state, 'ensName') if (!ensName) { const status = noRootEnsName ? 'Not Linked. This wallet does not own a root .eth ENS name.' : 'Not Linked. Choose a setup below.' return {status}} /> } const validation = readValidationFromState(identity.state) if (validation?.ok) { return linked, {ensName}} /> } return ( issue, {ensName} ({ensValidationReasonText(validation?.reason)})} /> ) } type AssignEnsCurrentSetupProps = { currentEnsName: string currentMode: CustodyMode | undefined ownerAddress: string operatorAddress: string tokenNetworkLabel: string } export const AssignEnsCurrentSetup: React.FC = ({ currentEnsName, currentMode, ownerAddress, operatorAddress, tokenNetworkLabel, }) => { const modeLabel = displayCustodyMode(currentMode) return ( Current Setup {currentMode === 'advanced' ? ( <> {ownerAddress ? : null} {operatorAddress ? : null} ) : null} ) } type SubdomainEntryProps = { parent: string ownerAddress: Address initialValue?: string placeholder?: string error?: string onConfirm: (fullName: string) => void onBack: () => void } export const SubdomainEntry: React.FC = ({ parent, ownerAddress, initialValue, placeholder, error, onConfirm, onBack }) => ( {error ? {error} : null} { const v = sanitizeSubdomainPrefix(value) if (!v) return 'Subdomain name cannot be empty' if (value.includes('.')) return 'Enter only the subdomain name, not the full ENS name' if (!isEthDomain(`${v}.${parent}`)) return 'Invalid characters in subdomain name' return null }} onSubmit={value => { const prefix = sanitizeSubdomainPrefix(value) if (!prefix) return onConfirm(`${prefix}.${parent}`) }} onCancel={onBack} /> Wallet: {shortAddress(ownerAddress)} )