From 24214de38295ec366b70f8e5a117619782592a6e Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Fri, 22 Aug 2025 10:55:41 +0530
Subject: [PATCH 01/14] pass delegatedAccess as prop

---
 src/libs/actions/Delegate.ts | 76 ++++++++++++++++++++++++++++--------
 1 file changed, 59 insertions(+), 17 deletions(-)

diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts
index 7177ceb26de1..ed2da69076e1 100644
--- a/src/libs/actions/Delegate.ts
+++ b/src/libs/actions/Delegate.ts
@@ -20,14 +20,6 @@ import {getCurrentUserAccountID} from './Report';
 import updateSessionAuthTokens from './Session/updateSessionAuthTokens';
 import updateSessionUser from './Session/updateSessionUser';
 
-let delegatedAccess: DelegatedAccess;
-Onyx.connect({
-    key: ONYXKEYS.ACCOUNT,
-    callback: (val) => {
-        delegatedAccess = val?.delegatedAccess ?? {};
-    },
-});
-
 let credentials: Credentials = {};
 Onyx.connect({
     key: ONYXKEYS.CREDENTIALS,
@@ -76,11 +68,50 @@ const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [
     ONYXKEYS.NETWORK,
 ];
 
+type ClearDelegatorErrorsParams = {
+    delegatedAccess: DelegatedAccess;
+};
+
+type AddDelegateProps = {
+    email: string;
+    role: DelegateRole;
+    validateCode: string;
+    delegatedAccess: DelegatedAccess;
+};
+
+type RemoveDelegateProps = {
+    email: string;
+    delegatedAccess: DelegatedAccess;
+};
+
+type ClearDelegateErrorsByFieldProps = {
+    email: string;
+    fieldName: string;
+    delegatedAccess: DelegatedAccess;
+};
+
+type UpdateDelegateRoleProps = {
+    email: string;
+    role: DelegateRole;
+    validateCode: string;
+    delegatedAccess: DelegatedAccess;
+};
+
+type IsConnectedAsDelegateProps = {
+    delegatedAccess: DelegatedAccess;
+};
+
+type ConnectProps = {
+    email: string;
+    delegatedAccess: DelegatedAccess;
+    isFromOldDot?: boolean;
+};
+
 /**
  * Connects the user as a delegate to another account.
  * Returns a Promise that resolves to true on success, false on failure, or undefined if not applicable.
  */
-function connect(email: string, isFromOldDot = false) {
+function connect({email, delegatedAccess, isFromOldDot = false}: ConnectProps) {
     if (!delegatedAccess?.delegators && !isFromOldDot) {
         return;
     }
@@ -277,7 +308,7 @@ function disconnect() {
         });
 }
 
-function clearDelegatorErrors() {
+function clearDelegatorErrors({delegatedAccess}: ClearDelegatorErrorsParams) {
     if (!delegatedAccess?.delegators) {
         return;
     }
@@ -288,7 +319,7 @@ function requestValidationCode() {
     API.write(WRITE_COMMANDS.RESEND_VALIDATE_CODE, null);
 }
 
-function addDelegate(email: string, role: DelegateRole, validateCode: string) {
+function addDelegate({email, role, validateCode, delegatedAccess}: AddDelegateProps) {
     const existingDelegate = delegatedAccess?.delegates?.find((delegate) => delegate.email === email);
 
     const optimisticDelegateData = (): Delegate[] => {
@@ -438,7 +469,7 @@ function addDelegate(email: string, role: DelegateRole, validateCode: string) {
     API.write(WRITE_COMMANDS.ADD_DELEGATE, parameters, {optimisticData, successData, failureData});
 }
 
-function removeDelegate(email: string) {
+function removeDelegate({email, delegatedAccess}: RemoveDelegateProps) {
     if (!email) {
         return;
     }
@@ -510,7 +541,7 @@ function removeDelegate(email: string) {
     API.write(WRITE_COMMANDS.REMOVE_DELEGATE, parameters, {optimisticData, successData, failureData});
 }
 
-function clearDelegateErrorsByField(email: string, fieldName: string) {
+function clearDelegateErrorsByField({email, fieldName, delegatedAccess}: ClearDelegateErrorsByFieldProps) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -526,11 +557,11 @@ function clearDelegateErrorsByField(email: string, fieldName: string) {
     });
 }
 
-function isConnectedAsDelegate() {
+function isConnectedAsDelegate({delegatedAccess}: IsConnectedAsDelegateProps) {
     return !!delegatedAccess?.delegate;
 }
 
-function updateDelegateRole(email: string, role: DelegateRole, validateCode: string) {
+function updateDelegateRole({email, role, validateCode, delegatedAccess}: UpdateDelegateRoleProps) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -614,7 +645,7 @@ function updateDelegateRole(email: string, role: DelegateRole, validateCode: str
     API.write(WRITE_COMMANDS.UPDATE_DELEGATE_ROLE, parameters, {optimisticData, successData, failureData});
 }
 
-function updateDelegateRoleOptimistically(email: string, role: DelegateRole) {
+function updateDelegateRoleOptimistically({email, role, delegatedAccess}: UpdateDelegateRoleOptimisticallyProps) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -648,7 +679,7 @@ function updateDelegateRoleOptimistically(email: string, role: DelegateRole) {
     Onyx.update(optimisticData);
 }
 
-function clearDelegateRolePendingAction(email: string) {
+function clearDelegateRolePendingAction({email, delegatedAccess}: ClearDelegateRolePendingActionProps) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -693,6 +724,17 @@ function openSecuritySettingsPage() {
     API.read(READ_COMMANDS.OPEN_SECURITY_SETTINGS_PAGE, null);
 }
 
+type UpdateDelegateRoleOptimisticallyProps = {
+    email: string;
+    role: DelegateRole;
+    delegatedAccess: DelegatedAccess;
+};
+
+type ClearDelegateRolePendingActionProps = {
+    email: string;
+    delegatedAccess: DelegatedAccess;
+};
+
 export {
     connect,
     disconnect,

From 035d2319b4950bf4f1ebfa1ff74b09cd53490cf0 Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Fri, 22 Aug 2025 11:11:04 +0530
Subject: [PATCH 02/14] update prop passing in functions

---
 src/components/AccountSwitcher.tsx            |  4 ++--
 src/libs/Authentication.ts                    | 14 ++++++++++-
 .../Navigation/AppNavigator/AuthScreens.tsx   |  2 +-
 src/libs/actions/Delegate.ts                  | 24 +++++++++++--------
 .../AddDelegate/DelegateMagicCodeModal.tsx    |  4 ++--
 .../UpdateDelegateMagicCodeModal.tsx          |  4 ++--
 .../UpdateDelegateRolePage.tsx                |  7 ++++--
 .../ValidateCodeForm/BaseValidateCodeForm.tsx |  8 +++----
 .../Security/SecuritySettingsPage.tsx         |  4 ++--
 9 files changed, 45 insertions(+), 26 deletions(-)

diff --git a/src/components/AccountSwitcher.tsx b/src/components/AccountSwitcher.tsx
index 834cf97e5d36..cc64b99b0b9e 100644
--- a/src/components/AccountSwitcher.tsx
+++ b/src/components/AccountSwitcher.tsx
@@ -156,7 +156,7 @@ function AccountSwitcher({isScreenFocused}: AccountSwitcherProps) {
                             close(() => setShouldShowOfflineModal(true));
                             return;
                         }
-                        connect(email);
+                        connect({email, delegatedAccess: account?.delegatedAccess});
                     },
                 });
             });
@@ -166,7 +166,7 @@ function AccountSwitcher({isScreenFocused}: AccountSwitcherProps) {
 
     const hideDelegatorMenu = () => {
         setShouldShowDelegatorMenu(false);
-        clearDelegatorErrors();
+        clearDelegatorErrors({delegatedAccess: account?.delegatedAccess});
     };
 
     return (
diff --git a/src/libs/Authentication.ts b/src/libs/Authentication.ts
index b92039cc33fb..e0f073defd8f 100644
--- a/src/libs/Authentication.ts
+++ b/src/libs/Authentication.ts
@@ -1,7 +1,9 @@
 import Onyx from 'react-native-onyx';
+import type {OnyxEntry} from 'react-native-onyx';
 import CONFIG from '@src/CONFIG';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import type {Account} from '@src/types/onyx';
 import type Response from '@src/types/onyx/Response';
 import {isConnectedAsDelegate, restoreDelegateSession} from './actions/Delegate';
 import updateSessionAuthTokens from './actions/Session/updateSessionAuthTokens';
@@ -33,6 +35,16 @@ Onyx.connect({
     },
 });
 
+let account: OnyxEntry<Account>;
+// Authentication lib is not connected to any changes on the UI
+// So it is okay to use connectWithoutView here.
+Onyx.connectWithoutView({
+    key: ONYXKEYS.ACCOUNT,
+    callback: (value) => {
+        account = value;
+    },
+});
+
 function Authenticate(parameters: Parameters): Promise<Response | void> {
     const commandName = 'Authenticate';
 
@@ -136,7 +148,7 @@ function reauthenticate(command = ''): Promise<boolean> {
 
             // If we reauthenticate due to an expired delegate token, restore the delegate's original account.
             // This is because the credentials used to reauthenticate were for the delegate's original account, and not for the account they were connected as.
-            if (isConnectedAsDelegate()) {
+            if (isConnectedAsDelegate({delegatedAccess: account?.delegatedAccess})) {
                 Log.info('Reauthenticate while connected as a delegate. Restoring original account.');
                 restoreDelegateSession(response);
                 return true;
diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx
index 4023c7cce481..5d228f2c8c20 100644
--- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx
+++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx
@@ -316,7 +316,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
             // or returning from background. If so, we'll assume they have some app data already and we can call reconnectApp() instead of openApp() and connect() for delegator from OldDot.
             if (SessionUtils.didUserLogInDuringSession() || delegatorEmail) {
                 if (delegatorEmail) {
-                    connect(delegatorEmail, true)
+                    connect({email: delegatorEmail, delegatedAccess: account?.delegatedAccess, isFromOldDot: true})
                         ?.then((success) => {
                             App.setAppLoading(!!success);
                         })
diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts
index ed2da69076e1..1cb4657a4a43 100644
--- a/src/libs/actions/Delegate.ts
+++ b/src/libs/actions/Delegate.ts
@@ -69,41 +69,41 @@ const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [
 ];
 
 type ClearDelegatorErrorsParams = {
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 type AddDelegateProps = {
     email: string;
     role: DelegateRole;
     validateCode: string;
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 type RemoveDelegateProps = {
     email: string;
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 type ClearDelegateErrorsByFieldProps = {
     email: string;
     fieldName: string;
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 type UpdateDelegateRoleProps = {
     email: string;
     role: DelegateRole;
     validateCode: string;
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 type IsConnectedAsDelegateProps = {
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 type ConnectProps = {
     email: string;
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
     isFromOldDot?: boolean;
 };
 
@@ -320,6 +320,10 @@ function requestValidationCode() {
 }
 
 function addDelegate({email, role, validateCode, delegatedAccess}: AddDelegateProps) {
+    if (!delegatedAccess?.delegates) {
+        return;
+    }
+
     const existingDelegate = delegatedAccess?.delegates?.find((delegate) => delegate.email === email);
 
     const optimisticDelegateData = (): Delegate[] => {
@@ -470,7 +474,7 @@ function addDelegate({email, role, validateCode, delegatedAccess}: AddDelegatePr
 }
 
 function removeDelegate({email, delegatedAccess}: RemoveDelegateProps) {
-    if (!email) {
+    if (!email || !delegatedAccess?.delegates) {
         return;
     }
 
@@ -727,12 +731,12 @@ function openSecuritySettingsPage() {
 type UpdateDelegateRoleOptimisticallyProps = {
     email: string;
     role: DelegateRole;
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 type ClearDelegateRolePendingActionProps = {
     email: string;
-    delegatedAccess: DelegatedAccess;
+    delegatedAccess: DelegatedAccess | undefined;
 };
 
 export {
diff --git a/src/pages/settings/Security/AddDelegate/DelegateMagicCodeModal.tsx b/src/pages/settings/Security/AddDelegate/DelegateMagicCodeModal.tsx
index 33e4cf9ccaf1..56e55a4924fa 100644
--- a/src/pages/settings/Security/AddDelegate/DelegateMagicCodeModal.tsx
+++ b/src/pages/settings/Security/AddDelegate/DelegateMagicCodeModal.tsx
@@ -46,7 +46,7 @@ function DelegateMagicCodeModal({login, role, onClose, isValidateCodeActionModal
         if (isEmptyObject(validateLoginError) && isEmptyObject(validateCodeAction?.errorFields)) {
             return;
         }
-        clearDelegateErrorsByField(currentDelegate?.email ?? '', 'addDelegate');
+        clearDelegateErrorsByField({email: currentDelegate?.email ?? '', fieldName: 'addDelegate', delegatedAccess: account?.delegatedAccess});
     };
 
     return (
@@ -60,7 +60,7 @@ function DelegateMagicCodeModal({login, role, onClose, isValidateCodeActionModal
             isVisible={isValidateCodeActionModalVisible}
             title={translate('delegate.makeSureItIsYou')}
             sendValidateCode={() => requestValidateCodeAction()}
-            handleSubmitForm={(validateCode) => addDelegate(login, role, validateCode)}
+            handleSubmitForm={(validateCode) => addDelegate({email: login, role, validateCode, delegatedAccess: account?.delegatedAccess})}
             descriptionPrimary={translate('delegate.enterMagicCode', {contactMethod: account?.primaryLogin ?? ''})}
         />
     );
diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateMagicCodeModal.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateMagicCodeModal.tsx
index e2342dd652bc..a8c19d74e271 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateMagicCodeModal.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateMagicCodeModal.tsx
@@ -41,7 +41,7 @@ function UpdateDelegateMagicCodeModal({login, role, isValidateCodeActionModalVis
         if (isEmptyObject(updateDelegateErrors) && isEmptyObject(validateCodeAction?.errorFields)) {
             return;
         }
-        clearDelegateErrorsByField(currentDelegate?.email ?? '', 'updateDelegateRole');
+        clearDelegateErrorsByField({email: currentDelegate?.email ?? '', fieldName: 'updateDelegateRole', delegatedAccess: account?.delegatedAccess});
     };
 
     return (
@@ -54,7 +54,7 @@ function UpdateDelegateMagicCodeModal({login, role, isValidateCodeActionModalVis
             isVisible={isValidateCodeActionModalVisible}
             title={translate('delegate.makeSureItIsYou')}
             sendValidateCode={() => requestValidateCodeAction()}
-            handleSubmitForm={(validateCode) => updateDelegateRole(login, role, validateCode)}
+            handleSubmitForm={(validateCode) => updateDelegateRole({email: login, role, validateCode, delegatedAccess: account?.delegatedAccess})}
             descriptionPrimary={translate('delegate.enterMagicCode', {contactMethod: account?.primaryLogin ?? ''})}
         />
     );
diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
index b527f45c6b7e..621a66a1d3c2 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
@@ -10,12 +10,14 @@ import Text from '@components/Text';
 import TextLink from '@components/TextLink';
 import useBeforeRemove from '@hooks/useBeforeRemove';
 import useLocalize from '@hooks/useLocalize';
+import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {clearDelegateRolePendingAction, updateDelegateRoleOptimistically} from '@libs/actions/Delegate';
 import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
 import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
 import type SCREENS from '@src/SCREENS';
 import type {DelegateRole} from '@src/types/onyx/Account';
 import UpdateDelegateMagicCodeModal from './UpdateDelegateMagicCodeModal';
@@ -31,6 +33,7 @@ function UpdateDelegateRolePage({route}: UpdateDelegateRolePageProps) {
     const [isValidateCodeActionModalVisible, setIsValidateCodeActionModalVisible] = useState(showValidateActionModalFromURL ?? false);
     const [newRole, setNewRole] = useState<ValueOf<typeof CONST.DELEGATE_ROLE> | undefined>(newRoleFromURL);
     const [shouldShowLoading, setShouldShowLoading] = useState(showValidateActionModalFromURL ?? false);
+    const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true});
 
     useEffect(() => {
         Navigation.setParams({showValidateActionModal: isValidateCodeActionModalVisible, newRole});
@@ -47,8 +50,8 @@ function UpdateDelegateRolePage({route}: UpdateDelegateRolePageProps) {
 
     useBeforeRemove(() => setIsValidateCodeActionModalVisible(false));
     useEffect(() => {
-        updateDelegateRoleOptimistically(login ?? '', currentRole as DelegateRole);
-        return () => clearDelegateRolePendingAction(login);
+        updateDelegateRoleOptimistically({email: login ?? '', role: currentRole as DelegateRole, delegatedAccess: account?.delegatedAccess});
+        return () => clearDelegateRolePendingAction({email: login, delegatedAccess: account?.delegatedAccess});
         // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
     }, [login]);
 
diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
index 58a3e915158f..4c2849c31176 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
@@ -128,10 +128,10 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
             setValidateCode(text);
             setFormError({});
             if (validateLoginError) {
-                Delegate.clearDelegateErrorsByField(currentDelegate?.email ?? '', 'updateDelegateRole');
+                Delegate.clearDelegateErrorsByField({email: currentDelegate?.email ?? '', fieldName: 'updateDelegateRole', delegatedAccess: account?.delegatedAccess});
             }
         },
-        [currentDelegate?.email, validateLoginError],
+        [currentDelegate?.email, validateLoginError, account?.delegatedAccess],
     );
 
     /**
@@ -150,8 +150,8 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
 
         setFormError({});
 
-        Delegate.updateDelegateRole(delegate, role, validateCode);
-    }, [delegate, role, validateCode]);
+        Delegate.updateDelegateRole({email: delegate, role, validateCode, delegatedAccess: account?.delegatedAccess});
+    }, [delegate, role, validateCode, account?.delegatedAccess]);
 
     return (
         <View style={[styles.flex1, styles.justifyContentBetween, wrapperStyle]}>
diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx
index d45d1d33f0a8..9dacc893ef7c 100644
--- a/src/pages/settings/Security/SecuritySettingsPage.tsx
+++ b/src/pages/settings/Security/SecuritySettingsPage.tsx
@@ -242,7 +242,7 @@ function SecuritySettingsPage() {
                         shouldShowRightIcon: true,
                         pendingAction,
                         shouldForceOpacity: !!pendingAction,
-                        onPendingActionDismiss: () => clearDelegateErrorsByField(email, 'addDelegate'),
+                        onPendingActionDismiss: () => clearDelegateErrorsByField({email, fieldName: 'addDelegate', delegatedAccess: account?.delegatedAccess}),
                         error,
                         onPress,
                         success: selectedEmail === email,
@@ -427,7 +427,7 @@ function SecuritySettingsPage() {
                                 prompt={translate('delegate.removeCopilotConfirmation')}
                                 danger
                                 onConfirm={() => {
-                                    removeDelegate(selectedDelegate?.email ?? '');
+                                    removeDelegate({email: selectedDelegate?.email ?? '', delegatedAccess: account?.delegatedAccess});
                                     setShouldShowRemoveDelegateModal(false);
                                     setSelectedDelegate(undefined);
                                 }}

From d30a626ac5fb03437ad40a92e8e44ce357ef24a3 Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Fri, 22 Aug 2025 11:17:55 +0530
Subject: [PATCH 03/14] fix changed files ESlint

---
 .../ValidateCodeForm/BaseValidateCodeForm.tsx    | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
index 4c2849c31176..7afe42b138a8 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
@@ -16,9 +16,9 @@ import useOnyx from '@hooks/useOnyx';
 import useStyleUtils from '@hooks/useStyleUtils';
 import useTheme from '@hooks/useTheme';
 import useThemeStyles from '@hooks/useThemeStyles';
-import * as ErrorUtils from '@libs/ErrorUtils';
-import * as ValidationUtils from '@libs/ValidationUtils';
-import * as Delegate from '@userActions/Delegate';
+import {getLatestError} from '@libs/ErrorUtils';
+import {isValidValidateCode} from '@libs/ValidationUtils';
+import {clearDelegateErrorsByField, requestValidationCode, updateDelegateRole} from '@userActions/Delegate';
 import CONST from '@src/CONST';
 import type {TranslationPaths} from '@src/languages/types';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -67,7 +67,7 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
 
     const currentDelegate = account?.delegatedAccess?.delegates?.find((d) => d.email === delegate);
     const errorFields = account?.delegatedAccess?.errorFields ?? {};
-    const validateLoginError = ErrorUtils.getLatestError(errorFields.updateDelegateRole?.[currentDelegate?.email ?? '']);
+    const validateLoginError = getLatestError(errorFields.updateDelegateRole?.[currentDelegate?.email ?? '']);
 
     const shouldDisableResendValidateCode = !!isOffline || currentDelegate?.isLoading;
 
@@ -115,7 +115,7 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
         if (!login) {
             return;
         }
-        Delegate.requestValidationCode();
+        requestValidationCode();
 
         inputValidateCodeRef.current?.clear();
     };
@@ -128,7 +128,7 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
             setValidateCode(text);
             setFormError({});
             if (validateLoginError) {
-                Delegate.clearDelegateErrorsByField({email: currentDelegate?.email ?? '', fieldName: 'updateDelegateRole', delegatedAccess: account?.delegatedAccess});
+                clearDelegateErrorsByField({email: currentDelegate?.email ?? '', fieldName: 'updateDelegateRole', delegatedAccess: account?.delegatedAccess});
             }
         },
         [currentDelegate?.email, validateLoginError, account?.delegatedAccess],
@@ -143,14 +143,14 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
             return;
         }
 
-        if (!ValidationUtils.isValidValidateCode(validateCode)) {
+        if (!isValidValidateCode(validateCode)) {
             setFormError({validateCode: 'validateCodeForm.error.incorrectMagicCode'});
             return;
         }
 
         setFormError({});
 
-        Delegate.updateDelegateRole({email: delegate, role, validateCode, delegatedAccess: account?.delegatedAccess});
+        updateDelegateRole({email: delegate, role, validateCode, delegatedAccess: account?.delegatedAccess});
     }, [delegate, role, validateCode, account?.delegatedAccess]);
 
     return (

From 779feb19285d3018d03c05f1afdefdef108399ec Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Fri, 22 Aug 2025 15:43:04 +0530
Subject: [PATCH 04/14] add delegate tests

---
 tests/actions/DelegateTest.ts | 230 ++++++++++++++++++++++++++++++++++
 1 file changed, 230 insertions(+)
 create mode 100644 tests/actions/DelegateTest.ts

diff --git a/tests/actions/DelegateTest.ts b/tests/actions/DelegateTest.ts
new file mode 100644
index 000000000000..f7aa2a942380
--- /dev/null
+++ b/tests/actions/DelegateTest.ts
@@ -0,0 +1,230 @@
+import Onyx from 'react-native-onyx';
+import {addDelegate, clearDelegateErrorsByField, clearDelegatorErrors, isConnectedAsDelegate, removeDelegate, updateDelegateRole} from '@libs/actions/Delegate';
+import CONST from '@src/CONST';
+import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager';
+import ONYXKEYS from '@src/ONYXKEYS';
+import type {DelegatedAccess} from '@src/types/onyx/Account';
+import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
+
+OnyxUpdateManager();
+describe('actions/Delegate', () => {
+    beforeAll(async () => {
+        Onyx.init({
+            keys: ONYXKEYS,
+        });
+        await waitForBatchedUpdates();
+    });
+
+    beforeEach(async () => {
+        await Onyx.clear();
+        await waitForBatchedUpdates();
+    });
+
+    describe('clearDelegatorErrors', () => {
+        it('should clear delegator errors', async () => {
+            const delegatedAccess: DelegatedAccess = {
+                delegators: [
+                    {
+                        email: 'test@test.com',
+                        // @ts-expect-error - errorFields is not defined in the type
+                        errorFields: {
+                            addDelegate: {
+                                // eslint-disable-next-line @typescript-eslint/naming-convention
+                                '12211': {
+                                    email: 'Invalid email address',
+                                },
+                            },
+                        },
+                    },
+                ],
+            };
+
+            await Onyx.merge(ONYXKEYS.ACCOUNT, {delegatedAccess});
+            await waitForBatchedUpdates();
+
+            await new Promise<void>((resolve) => {
+                const connection = Onyx.connect({
+                    key: ONYXKEYS.ACCOUNT,
+                    callback: (account) => {
+                        // @ts-expect-error - errorFields is not defined in the type
+                        expect(account?.delegatedAccess?.delegators?.at(0)?.errorFields).toBeDefined();
+                        Onyx.disconnect(connection);
+                        resolve();
+                    },
+                });
+            });
+
+            clearDelegatorErrors({delegatedAccess});
+            await waitForBatchedUpdates();
+
+            await new Promise<void>((resolve) => {
+                const connection = Onyx.connect({
+                    key: ONYXKEYS.ACCOUNT,
+                    callback: (account) => {
+                        // @ts-expect-error - errorFields is not defined in the type
+                        expect(account?.delegatedAccess?.delegators?.at(0)?.errorFields).toBeUndefined();
+                        Onyx.disconnect(connection);
+                        resolve();
+                    },
+                });
+            });
+        });
+    });
+    describe('addDelegate', () => {
+        it('should add a delegate', async () => {
+            const delegatedAccess: DelegatedAccess = {
+                delegates: [],
+            };
+            await waitForBatchedUpdates();
+
+            addDelegate({email: 'test@test.com', role: CONST.DELEGATE_ROLE.ALL, validateCode: '123456', delegatedAccess});
+            await waitForBatchedUpdates();
+
+            await new Promise<void>((resolve) => {
+                const connection = Onyx.connect({
+                    key: ONYXKEYS.ACCOUNT,
+                    callback: (account) => {
+                        expect(account?.delegatedAccess?.delegates?.at(0)?.email).toBe('test@test.com');
+                        expect(account?.delegatedAccess?.delegates?.at(0)?.role).toBe(CONST.DELEGATE_ROLE.ALL);
+                        Onyx.disconnect(connection);
+                        resolve();
+                    },
+                });
+            });
+        });
+    });
+    describe('removeDelegate', () => {
+        it('should remove a delegate', async () => {
+            const delegatedAccess: DelegatedAccess = {
+                delegates: [
+                    {
+                        email: 'test@test.com',
+                        role: CONST.DELEGATE_ROLE.ALL,
+                    },
+                ],
+            };
+
+            await Onyx.merge(ONYXKEYS.ACCOUNT, {delegatedAccess});
+            await waitForBatchedUpdates();
+
+            removeDelegate({email: 'test@test.com', delegatedAccess});
+            await waitForBatchedUpdates();
+
+            await new Promise<void>((resolve) => {
+                const connection = Onyx.connect({
+                    key: ONYXKEYS.ACCOUNT,
+                    callback: (account) => {
+                        expect(account?.delegatedAccess?.delegates?.at(0)?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
+                        Onyx.disconnect(connection);
+                        resolve();
+                    },
+                });
+            });
+        });
+    });
+    describe('clearDelegateErrorsByField', () => {
+        it('should clear a delegate error by field', async () => {
+            const delegatedAccess: DelegatedAccess = {
+                delegates: [
+                    {
+                        email: 'test@test.com',
+                        role: CONST.DELEGATE_ROLE.ALL,
+                    },
+                ],
+                errorFields: {
+                    addDelegate: {
+                        // eslint-disable-next-line @typescript-eslint/naming-convention
+                        'test@test.com': {
+                            email: 'Invalid email address',
+                        },
+                    },
+                },
+            };
+
+            // Set initial Onyx state
+            await Onyx.merge(ONYXKEYS.ACCOUNT, {delegatedAccess});
+            await waitForBatchedUpdates();
+
+            // Clear an error in a simple field
+            clearDelegateErrorsByField({
+                email: 'test@test.com',
+                fieldName: 'addDelegate',
+                delegatedAccess,
+            });
+            await waitForBatchedUpdates();
+
+            // Assert
+            await new Promise<void>((resolve) => {
+                const connection = Onyx.connect({
+                    key: ONYXKEYS.ACCOUNT,
+                    callback: (account) => {
+                        const errorFields = account?.delegatedAccess?.errorFields;
+
+                        // The targeted errors should be cleared
+                        expect(errorFields?.addDelegate?.['test@test.com']).toBeUndefined();
+
+                        Onyx.disconnect(connection);
+                        resolve();
+                    },
+                });
+            });
+        });
+    });
+
+    describe('updateDelegateRole', () => {
+        it('should update a delegate role', async () => {
+            const delegatedAccess: DelegatedAccess = {
+                delegates: [
+                    {
+                        email: 'test@test.com',
+                        role: CONST.DELEGATE_ROLE.ALL,
+                    },
+                ],
+            };
+
+            await Onyx.merge(ONYXKEYS.ACCOUNT, {delegatedAccess});
+            await waitForBatchedUpdates();
+
+            updateDelegateRole({email: 'test@test.com', role: CONST.DELEGATE_ROLE.SUBMITTER, validateCode: '123456', delegatedAccess});
+            await waitForBatchedUpdates();
+
+            await new Promise<void>((resolve) => {
+                const connection = Onyx.connect({
+                    key: ONYXKEYS.ACCOUNT,
+                    callback: (account) => {
+                        expect(account?.delegatedAccess?.delegates?.at(0)?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE);
+                        expect(account?.delegatedAccess?.delegates?.at(0)?.pendingFields?.role).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE);
+                        Onyx.disconnect(connection);
+                        resolve();
+                    },
+                });
+            });
+        });
+    });
+    describe('isConnectedAsDelegate', () => {
+        it('should return true if the user is connected as a delegate', async () => {
+            const delegatedAccess: DelegatedAccess = {
+                delegates: [
+                    {
+                        email: 'test@test.com',
+                        role: CONST.DELEGATE_ROLE.ALL,
+                    },
+                ],
+            };
+
+            await Onyx.merge(ONYXKEYS.ACCOUNT, {delegatedAccess});
+            await waitForBatchedUpdates();
+
+            await new Promise<void>((resolve) => {
+                const connection = Onyx.connect({
+                    key: ONYXKEYS.ACCOUNT,
+                    callback: (account) => {
+                        expect(isConnectedAsDelegate({delegatedAccess: account?.delegatedAccess})).toBeDefined();
+                        Onyx.disconnect(connection);
+                        resolve();
+                    },
+                });
+            });
+        });
+    });
+});

From 84e7c286214c24a94b4679b13c0ae8243061fdf8 Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Fri, 22 Aug 2025 15:44:18 +0530
Subject: [PATCH 05/14] fix eslint

---
 .../ValidateCodeForm/BaseValidateCodeForm.tsx                   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
index 7afe42b138a8..e8ada13d07c5 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
@@ -60,7 +60,7 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
     const [formError, setFormError] = useState<ValidateCodeFormError>({});
     const [validateCode, setValidateCode] = useState('');
     const inputValidateCodeRef = useRef<MagicCodeInputHandle>(null);
-    const [account] = useOnyx(ONYXKEYS.ACCOUNT);
+    const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true});
     const login = account?.primaryLogin;
     // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing doesn't achieve the same result in this case
     const focusTimeoutRef = useRef<NodeJS.Timeout | null>(null);

From 23442a69caef6bd9bc3975192a104bd26a29a8f4 Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Fri, 22 Aug 2025 15:51:36 +0530
Subject: [PATCH 06/14] update package json warning

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 801341ed68bb..68695cac4b7d 100644
--- a/package.json
+++ b/package.json
@@ -46,7 +46,7 @@
     "test:debug": "TZ=utc NODE_OPTIONS='--inspect-brk --experimental-vm-modules' jest --runInBand",
     "perf-test": "NODE_OPTIONS=--experimental-vm-modules npx reassure",
     "typecheck": "NODE_OPTIONS=--max_old_space_size=8192 tsc",
-    "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=244 --cache --cache-location=node_modules/.cache/eslint",
+    "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=243 --cache --cache-location=node_modules/.cache/eslint",
     "lint-changed": "NODE_OPTIONS=--max_old_space_size=8192 ./scripts/lintChanged.sh",
     "lint-watch": "npx eslint-watch --watch --changed",
     "shellcheck": "./scripts/shellCheck.sh",

From 8ca10c5c228d843b8f8ed41115dfe94df03ecfef Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Sun, 7 Sep 2025 16:30:04 +0530
Subject: [PATCH 07/14] extract type

---
 src/libs/actions/Delegate.ts | 95 +++++++++++++++++++-----------------
 1 file changed, 49 insertions(+), 46 deletions(-)

diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts
index 8a2442c6f99d..066414f69041 100644
--- a/src/libs/actions/Delegate.ts
+++ b/src/libs/actions/Delegate.ts
@@ -2,7 +2,7 @@ import HybridAppModule from '@expensify/react-native-hybrid-app';
 import Onyx from 'react-native-onyx';
 import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx';
 import * as API from '@libs/API';
-import type {AddDelegateParams, RemoveDelegateParams, UpdateDelegateRoleParams} from '@libs/API/parameters';
+import type {AddDelegateParams as APIAddDelegateParams, RemoveDelegateParams as APIRemoveDelegateParams, UpdateDelegateRoleParams as APIUpdateDelegateRoleParams} from '@libs/API/parameters';
 import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
 import * as ErrorUtils from '@libs/ErrorUtils';
 import Log from '@libs/Log';
@@ -69,50 +69,64 @@ const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [
     ONYXKEYS.NETWORK,
 ];
 
-type ClearDelegatorErrorsParams = {
+type WithDelegatedAccess = {
+    // Optional keeps call sites clean, but still encourages passing `account?.delegatedAccess`.
     delegatedAccess: DelegatedAccess | undefined;
 };
 
-type AddDelegateProps = {
+type WithEmail = {
     email: string;
-    role: DelegateRole;
-    validateCode: string;
-    delegatedAccess: DelegatedAccess | undefined;
 };
 
-type RemoveDelegateProps = {
-    email: string;
-    delegatedAccess: DelegatedAccess | undefined;
-};
-
-type ClearDelegateErrorsByFieldProps = {
-    email: string;
-    fieldName: string;
-    delegatedAccess: DelegatedAccess | undefined;
+type WithRole = {
+    role: DelegateRole;
 };
 
-type UpdateDelegateRoleProps = {
-    email: string;
-    role: DelegateRole;
+type WithValidateCode = {
     validateCode: string;
-    delegatedAccess: DelegatedAccess | undefined;
 };
 
-type IsConnectedAsDelegateProps = {
-    delegatedAccess: DelegatedAccess | undefined;
+type WithFieldName = {
+    // Constrain to known keys to avoid misspells at call sites
+    fieldName: 'addDelegate' | 'updateDelegateRole'; // but string could work as well
 };
 
-type ConnectProps = {
-    email: string;
-    delegatedAccess: DelegatedAccess | undefined;
+type WithOldDotFlag = {
     isFromOldDot?: boolean;
 };
 
+// Clear delegator-level errors
+type ClearDelegatorErrorsParams = WithDelegatedAccess;
+
+// Add a delegate (requires code)
+type AddDelegateParams = WithEmail & WithRole & WithValidateCode & WithDelegatedAccess;
+
+// Remove a delegate
+type RemoveDelegateParams = WithEmail & WithDelegatedAccess;
+
+// Clear delegate errors scoped by field
+type ClearDelegateErrorsByFieldParams = WithEmail & WithFieldName & WithDelegatedAccess;
+
+// Update existing delegate role (requires code)
+type UpdateDelegateRoleParams = WithEmail & WithRole & WithValidateCode & WithDelegatedAccess;
+
+// Is connected as delegate?
+type IsConnectedAsDelegateParams = WithDelegatedAccess;
+
+// Connect as delegate
+type ConnectParams = WithEmail & WithDelegatedAccess & WithOldDotFlag;
+
+// Optimistic update to role (no code)
+type UpdateDelegateRoleOptimisticallyParams = WithEmail & WithRole & WithDelegatedAccess;
+
+// Clear pending action for role update
+type ClearDelegateRolePendingActionParams = WithEmail & WithDelegatedAccess;
+
 /**
  * Connects the user as a delegate to another account.
  * Returns a Promise that resolves to true on success, false on failure, or undefined if not applicable.
  */
-function connect({email, delegatedAccess, isFromOldDot = false}: ConnectProps) {
+function connect({email, delegatedAccess, isFromOldDot = false}: ConnectParams) {
     if (!delegatedAccess?.delegators && !isFromOldDot) {
         return;
     }
@@ -320,7 +334,7 @@ function requestValidationCode() {
     API.write(WRITE_COMMANDS.RESEND_VALIDATE_CODE, null);
 }
 
-function addDelegate({email, role, validateCode, delegatedAccess}: AddDelegateProps) {
+function addDelegate({email, role, validateCode, delegatedAccess}: AddDelegateParams) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -469,12 +483,12 @@ function addDelegate({email, role, validateCode, delegatedAccess}: AddDelegatePr
     };
     optimisticData.push(optimisticResetActionCode);
 
-    const parameters: AddDelegateParams = {delegateEmail: email, validateCode, role};
+    const parameters: APIAddDelegateParams = {delegateEmail: email, validateCode, role};
 
     API.write(WRITE_COMMANDS.ADD_DELEGATE, parameters, {optimisticData, successData, failureData});
 }
 
-function removeDelegate({email, delegatedAccess}: RemoveDelegateProps) {
+function removeDelegate({email, delegatedAccess}: RemoveDelegateParams) {
     if (!email || !delegatedAccess?.delegates) {
         return;
     }
@@ -541,12 +555,12 @@ function removeDelegate({email, delegatedAccess}: RemoveDelegateProps) {
         },
     ];
 
-    const parameters: RemoveDelegateParams = {delegateEmail: email};
+    const parameters: APIRemoveDelegateParams = {delegateEmail: email};
 
     API.write(WRITE_COMMANDS.REMOVE_DELEGATE, parameters, {optimisticData, successData, failureData});
 }
 
-function clearDelegateErrorsByField({email, fieldName, delegatedAccess}: ClearDelegateErrorsByFieldProps) {
+function clearDelegateErrorsByField({email, fieldName, delegatedAccess}: ClearDelegateErrorsByFieldParams) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -562,11 +576,11 @@ function clearDelegateErrorsByField({email, fieldName, delegatedAccess}: ClearDe
     });
 }
 
-function isConnectedAsDelegate({delegatedAccess}: IsConnectedAsDelegateProps) {
+function isConnectedAsDelegate({delegatedAccess}: IsConnectedAsDelegateParams) {
     return !!delegatedAccess?.delegate;
 }
 
-function updateDelegateRole({email, role, validateCode, delegatedAccess}: UpdateDelegateRoleProps) {
+function updateDelegateRole({email, role, validateCode, delegatedAccess}: UpdateDelegateRoleParams) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -645,12 +659,12 @@ function updateDelegateRole({email, role, validateCode, delegatedAccess}: Update
         },
     ];
 
-    const parameters: UpdateDelegateRoleParams = {delegateEmail: email, validateCode, role};
+    const parameters: APIUpdateDelegateRoleParams = {delegateEmail: email, validateCode, role};
 
     API.write(WRITE_COMMANDS.UPDATE_DELEGATE_ROLE, parameters, {optimisticData, successData, failureData});
 }
 
-function updateDelegateRoleOptimistically({email, role, delegatedAccess}: UpdateDelegateRoleOptimisticallyProps) {
+function updateDelegateRoleOptimistically({email, role, delegatedAccess}: UpdateDelegateRoleOptimisticallyParams) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -684,7 +698,7 @@ function updateDelegateRoleOptimistically({email, role, delegatedAccess}: Update
     Onyx.update(optimisticData);
 }
 
-function clearDelegateRolePendingAction({email, delegatedAccess}: ClearDelegateRolePendingActionProps) {
+function clearDelegateRolePendingAction({email, delegatedAccess}: ClearDelegateRolePendingActionParams) {
     if (!delegatedAccess?.delegates) {
         return;
     }
@@ -729,17 +743,6 @@ function openSecuritySettingsPage() {
     API.read(READ_COMMANDS.OPEN_SECURITY_SETTINGS_PAGE, null);
 }
 
-type UpdateDelegateRoleOptimisticallyProps = {
-    email: string;
-    role: DelegateRole;
-    delegatedAccess: DelegatedAccess | undefined;
-};
-
-type ClearDelegateRolePendingActionProps = {
-    email: string;
-    delegatedAccess: DelegatedAccess | undefined;
-};
-
 export {
     connect,
     disconnect,

From b08f983c692014ffee19e68e6c62f6fa2d2ba27d Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Sun, 7 Sep 2025 16:33:31 +0530
Subject: [PATCH 08/14] update reviewer suggestion

---
 .../ValidateCodeForm/BaseValidateCodeForm.tsx                   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
index e8ada13d07c5..38a64908a2fb 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/ValidateCodeForm/BaseValidateCodeForm.tsx
@@ -187,7 +187,7 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () =>
             <FixedFooter>
                 <OfflineWithFeedback>
                     <Button
-                        isDisabled={isOffline}
+                        isDisabled={isOffline || !!account?.delegatedAccess}
                         text={translate('common.verify')}
                         onPress={validateAndSubmitForm}
                         style={[styles.mt4]}

From bbcbfffc05a28869ba799d77b93d9ee103b0476a Mon Sep 17 00:00:00 2001
From: Gandalf <whogandalf@gmail.com>
Date: Sun, 7 Sep 2025 16:39:41 +0530
Subject: [PATCH 09/14] Apply suggestion from @ikevin127

Co-authored-by: Kevin Brian Bader <56457735+ikevin127@users.noreply.github.com>
---
 .../AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
index 621a66a1d3c2..32c52b0a4d24 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
@@ -51,7 +51,7 @@ function UpdateDelegateRolePage({route}: UpdateDelegateRolePageProps) {
     useBeforeRemove(() => setIsValidateCodeActionModalVisible(false));
     useEffect(() => {
         updateDelegateRoleOptimistically({email: login ?? '', role: currentRole as DelegateRole, delegatedAccess: account?.delegatedAccess});
-        return () => clearDelegateRolePendingAction({email: login, delegatedAccess: account?.delegatedAccess});
+        return () => clearDelegateRolePendingAction({email: login ?? '', delegatedAccess: account?.delegatedAccess});
         // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
     }, [login]);
 

From e880c902d9b1828c2256e21442b282353cedff6d Mon Sep 17 00:00:00 2001
From: Gandalf <whogandalf@gmail.com>
Date: Sun, 7 Sep 2025 16:40:15 +0530
Subject: [PATCH 10/14] Apply suggestion from @ikevin127

Co-authored-by: Kevin Brian Bader <56457735+ikevin127@users.noreply.github.com>
---
 tests/actions/DelegateTest.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/actions/DelegateTest.ts b/tests/actions/DelegateTest.ts
index f7aa2a942380..36bd0381d31f 100644
--- a/tests/actions/DelegateTest.ts
+++ b/tests/actions/DelegateTest.ts
@@ -219,7 +219,7 @@ describe('actions/Delegate', () => {
                 const connection = Onyx.connect({
                     key: ONYXKEYS.ACCOUNT,
                     callback: (account) => {
-                        expect(isConnectedAsDelegate({delegatedAccess: account?.delegatedAccess})).toBeDefined();
+                        expect(isConnectedAsDelegate({delegatedAccess: account?.delegatedAccess})).toBe(false);
                         Onyx.disconnect(connection);
                         resolve();
                     },

From 165b76eff2558bcab6a393fd16782cf1c9498e05 Mon Sep 17 00:00:00 2001
From: Gandalf <whogandalf@gmail.com>
Date: Sun, 7 Sep 2025 16:51:05 +0530
Subject: [PATCH 11/14] Apply suggestion from @allgandalf

---
 src/libs/Authentication.ts | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/src/libs/Authentication.ts b/src/libs/Authentication.ts
index 00240c5eac4d..1fc7254ace0d 100644
--- a/src/libs/Authentication.ts
+++ b/src/libs/Authentication.ts
@@ -45,16 +45,6 @@ Onyx.connectWithoutView({
     },
 });
 
-let account: OnyxEntry<Account>;
-// Authentication lib is not connected to any changes on the UI
-// So it is okay to use connectWithoutView here.
-Onyx.connectWithoutView({
-    key: ONYXKEYS.ACCOUNT,
-    callback: (value) => {
-        account = value;
-    },
-});
-
 function Authenticate(parameters: Parameters): Promise<Response | void> {
     const commandName = 'Authenticate';
 

From 25457d91b368ba0fae5b4c6995926a1b47ddf11e Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Sun, 7 Sep 2025 16:54:18 +0530
Subject: [PATCH 12/14] fix imports

---
 src/libs/Authentication.ts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/libs/Authentication.ts b/src/libs/Authentication.ts
index 1fc7254ace0d..cf83bb8ac43c 100644
--- a/src/libs/Authentication.ts
+++ b/src/libs/Authentication.ts
@@ -1,9 +1,7 @@
 import Onyx from 'react-native-onyx';
-import type {OnyxEntry} from 'react-native-onyx';
 import CONFIG from '@src/CONFIG';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
-import type {Account} from '@src/types/onyx';
 import type Response from '@src/types/onyx/Response';
 import {isConnectedAsDelegate, restoreDelegateSession} from './actions/Delegate';
 import updateSessionAuthTokens from './actions/Session/updateSessionAuthTokens';

From 43f5f5a87c1074c102f486510c312d658edf384e Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Sun, 7 Sep 2025 17:01:25 +0530
Subject: [PATCH 13/14] fix type error

---
 src/libs/Authentication.ts | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/libs/Authentication.ts b/src/libs/Authentication.ts
index cf83bb8ac43c..624d1b589b23 100644
--- a/src/libs/Authentication.ts
+++ b/src/libs/Authentication.ts
@@ -1,7 +1,9 @@
 import Onyx from 'react-native-onyx';
+import type {OnyxEntry} from 'react-native-onyx';
 import CONFIG from '@src/CONFIG';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import type {Account} from '@src/types/onyx';
 import type Response from '@src/types/onyx/Response';
 import {isConnectedAsDelegate, restoreDelegateSession} from './actions/Delegate';
 import updateSessionAuthTokens from './actions/Session/updateSessionAuthTokens';
@@ -43,6 +45,16 @@ Onyx.connectWithoutView({
     },
 });
 
+let account: OnyxEntry<Account>;
+// Authentication lib is not connected to any changes on the UI
+// So it is okay to use connectWithoutView here.
+Onyx.connectWithoutView({
+    key: ONYXKEYS.ACCOUNT,
+    callback: (value) => {
+        account = value;
+    },
+});
+
 function Authenticate(parameters: Parameters): Promise<Response | void> {
     const commandName = 'Authenticate';
 
@@ -154,7 +166,7 @@ function reauthenticate(command = ''): Promise<boolean> {
 
                 // If we reauthenticate due to an expired delegate token, restore the delegate's original account.
                 // This is because the credentials used to reauthenticate were for the delegate's original account, and not for the account they were connected as.
-                if (isConnectedAsDelegate()) {
+                if (isConnectedAsDelegate({delegatedAccess: account?.delegatedAccess})) {
                     Log.info('Reauthenticate while connected as a delegate. Restoring original account.');
                     restoreDelegateSession(response);
                     return true;

From 621a6ea19576e28877ffc4876ebf5a331e694f9a Mon Sep 17 00:00:00 2001
From: allgandalf <whogandalf@gmail.com>
Date: Wed, 10 Sep 2025 00:37:06 +0530
Subject: [PATCH 14/14] fix update delegate role

---
 src/libs/actions/Delegate.ts                  | 38 -------------------
 .../UpdateDelegateRolePage.tsx                | 11 ------
 2 files changed, 49 deletions(-)

diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts
index 46f1182946ae..234c49580c71 100644
--- a/src/libs/actions/Delegate.ts
+++ b/src/libs/actions/Delegate.ts
@@ -118,9 +118,6 @@ type IsConnectedAsDelegateParams = WithDelegatedAccess;
 // Connect as delegate
 type ConnectParams = WithEmail & WithDelegatedAccess & WithOldDotFlag;
 
-// Optimistic update to role (no code)
-type UpdateDelegateRoleOptimisticallyParams = WithEmail & WithRole & WithDelegatedAccess;
-
 // Clear pending action for role update
 type ClearDelegateRolePendingActionParams = WithEmail & WithDelegatedAccess;
 
@@ -666,40 +663,6 @@ function updateDelegateRole({email, role, validateCode, delegatedAccess}: Update
     API.write(WRITE_COMMANDS.UPDATE_DELEGATE_ROLE, parameters, {optimisticData, successData, failureData});
 }
 
-function updateDelegateRoleOptimistically({email, role, delegatedAccess}: UpdateDelegateRoleOptimisticallyParams) {
-    if (!delegatedAccess?.delegates) {
-        return;
-    }
-
-    const optimisticData: OnyxUpdate[] = [
-        {
-            onyxMethod: Onyx.METHOD.MERGE,
-            key: ONYXKEYS.ACCOUNT,
-            value: {
-                delegatedAccess: {
-                    errorFields: {
-                        updateDelegateRole: {
-                            [email]: null,
-                        },
-                    },
-                    delegates: delegatedAccess.delegates.map((delegate) =>
-                        delegate.email === email
-                            ? {
-                                  ...delegate,
-                                  role,
-                                  pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
-                                  pendingFields: {role: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE},
-                              }
-                            : delegate,
-                    ),
-                },
-            },
-        },
-    ];
-
-    Onyx.update(optimisticData);
-}
-
 function clearDelegateRolePendingAction({email, delegatedAccess}: ClearDelegateRolePendingActionParams) {
     if (!delegatedAccess?.delegates) {
         return;
@@ -754,7 +717,6 @@ export {
     clearDelegateErrorsByField,
     restoreDelegateSession,
     isConnectedAsDelegate,
-    updateDelegateRoleOptimistically,
     clearDelegateRolePendingAction,
     updateDelegateRole,
     removeDelegate,
diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
index 32c52b0a4d24..106a810f5183 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
@@ -10,16 +10,12 @@ import Text from '@components/Text';
 import TextLink from '@components/TextLink';
 import useBeforeRemove from '@hooks/useBeforeRemove';
 import useLocalize from '@hooks/useLocalize';
-import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
-import {clearDelegateRolePendingAction, updateDelegateRoleOptimistically} from '@libs/actions/Delegate';
 import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
 import CONST from '@src/CONST';
-import ONYXKEYS from '@src/ONYXKEYS';
 import type SCREENS from '@src/SCREENS';
-import type {DelegateRole} from '@src/types/onyx/Account';
 import UpdateDelegateMagicCodeModal from './UpdateDelegateMagicCodeModal';
 
 type UpdateDelegateRolePageProps = PlatformStackScreenProps<SettingsNavigatorParamList, typeof SCREENS.SETTINGS.DELEGATE.UPDATE_DELEGATE_ROLE>;
@@ -33,7 +29,6 @@ function UpdateDelegateRolePage({route}: UpdateDelegateRolePageProps) {
     const [isValidateCodeActionModalVisible, setIsValidateCodeActionModalVisible] = useState(showValidateActionModalFromURL ?? false);
     const [newRole, setNewRole] = useState<ValueOf<typeof CONST.DELEGATE_ROLE> | undefined>(newRoleFromURL);
     const [shouldShowLoading, setShouldShowLoading] = useState(showValidateActionModalFromURL ?? false);
-    const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true});
 
     useEffect(() => {
         Navigation.setParams({showValidateActionModal: isValidateCodeActionModalVisible, newRole});
@@ -49,12 +44,6 @@ function UpdateDelegateRolePage({route}: UpdateDelegateRolePageProps) {
     }));
 
     useBeforeRemove(() => setIsValidateCodeActionModalVisible(false));
-    useEffect(() => {
-        updateDelegateRoleOptimistically({email: login ?? '', role: currentRole as DelegateRole, delegatedAccess: account?.delegatedAccess});
-        return () => clearDelegateRolePendingAction({email: login ?? '', delegatedAccess: account?.delegatedAccess});
-        // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
-    }, [login]);
-
     return (
         <ScreenWrapper
             includeSafeAreaPaddingBottom={false}
