Page MenuHomePhorge

D14911.1765145835.diff
No OneTemporary

Size
25 KB
Referenced Files
None
Subscribers
None

D14911.1765145835.diff

diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js
--- a/lib/actions/user-actions.js
+++ b/lib/actions/user-actions.js
@@ -934,6 +934,7 @@
siweMessage: string,
siweSignature: string,
fid: ?string,
+ farcasterDCsToken: ?string,
) => Promise<IdentityAuthResult> {
const client = React.useContext(IdentityClientContext);
const identityClient = client?.identityClient;
diff --git a/lib/types/siwe-types.js b/lib/types/siwe-types.js
--- a/lib/types/siwe-types.js
+++ b/lib/types/siwe-types.js
@@ -128,6 +128,7 @@
+message: string,
+signature: string,
+fid?: ?string,
+ +farcasterDCsToken?: ?string,
};
export const SIWEMessageTypes = Object.freeze({
diff --git a/lib/utils/services-utils.js b/lib/utils/services-utils.js
--- a/lib/utils/services-utils.js
+++ b/lib/utils/services-utils.js
@@ -14,6 +14,8 @@
// an authoritative keyserver for things like DMs.
const relyingOnAuthoritativeKeyserver = true;
+const supportsFarcasterDCs = false;
+
// If this returns true, then we're using the login 2.0, which means that a user
// can either restore an account (primary login) or log in using the QR code
// (secondary login).
@@ -64,4 +66,5 @@
httpResponseIsInvalidCSAT,
errorMessageIsInvalidCSAT,
fullBackupSupport,
+ supportsFarcasterDCs,
};
diff --git a/native/.eslintrc.json b/native/.eslintrc.json
--- a/native/.eslintrc.json
+++ b/native/.eslintrc.json
@@ -2,6 +2,9 @@
"env": {
"react-native/react-native": true
},
+ "globals": {
+ "URLSearchParams": "readonly"
+ },
"plugins": ["react-native"],
"rules": {
"react-native/no-unused-styles": 2,
diff --git a/native/account/registration/auth-navigator.react.js b/native/account/registration/auth-navigator.react.js
--- a/native/account/registration/auth-navigator.react.js
+++ b/native/account/registration/auth-navigator.react.js
@@ -25,6 +25,7 @@
} from './auth-router.js';
import AvatarSelection from './avatar-selection.react.js';
import ConnectEthereum from './connect-ethereum.react.js';
+import { ConnectFarcasterDCs } from './connect-farcaster-dcs.react.js';
import ConnectFarcaster from './connect-farcaster.react.js';
import CoolOrNerdModeSelection from './cool-or-nerd-mode-selection.react.js';
import EmojiAvatarSelection from './emoji-avatar-selection.react.js';
@@ -59,6 +60,7 @@
RestoreBackupScreenRouteName,
RestoreBackupErrorScreenRouteName,
RestoreSIWEBackupRouteName,
+ ConnectFarcasterDCsRouteName,
} from '../../navigation/route-names.js';
import QRCodeScreen from '../qr-code-screen.react.js';
import RestoreBackupErrorScreen from '../restore-backup-error-screen.react.js';
@@ -234,6 +236,10 @@
name={RestoreSIWEBackupRouteName}
component={RestoreSIWEBackup}
/>
+ <Auth.Screen
+ name={ConnectFarcasterDCsRouteName}
+ component={ConnectFarcasterDCs}
+ />
</Auth.Navigator>
);
}
diff --git a/native/account/registration/avatar-selection.react.js b/native/account/registration/avatar-selection.react.js
--- a/native/account/registration/avatar-selection.react.js
+++ b/native/account/registration/avatar-selection.react.js
@@ -41,6 +41,7 @@
+accountSelection: AccountSelection,
+farcasterID: ?string,
+farcasterAvatarURL: ?string,
+ +farcasterDCsToken: ?string,
},
};
diff --git a/native/account/registration/connect-ethereum.react.js b/native/account/registration/connect-ethereum.react.js
--- a/native/account/registration/connect-ethereum.react.js
+++ b/native/account/registration/connect-ethereum.react.js
@@ -48,6 +48,7 @@
+keyserverURL?: ?string,
+farcasterID: ?string,
+farcasterAvatarURL: ?string,
+ +farcasterDCsToken: ?string,
},
};
diff --git a/native/account/registration/connect-farcaster-dcs.react.js b/native/account/registration/connect-farcaster-dcs.react.js
new file mode 100644
--- /dev/null
+++ b/native/account/registration/connect-farcaster-dcs.react.js
@@ -0,0 +1,246 @@
+// @flow
+
+import invariant from 'invariant';
+import * as React from 'react';
+
+import type { AuthNavigationProp } from './auth-navigator.react.js';
+import { siweNonceExpired } from './ethereum-utils.js';
+import { RegistrationContext } from './registration-context.js';
+import RegistrationTextInput from './registration-text-input.react.js';
+import type { CoolOrNerdMode } from './registration-types.js';
+import FarcasterPrompt from '../../components/farcaster-prompt.react.js';
+import PrimaryButton from '../../components/primary-button.react.js';
+import { FarcasterAuthContextProvider } from '../../farcaster-auth/farcaster-auth-context-provider.react.js';
+import { useGetAuthToken } from '../../farcaster-auth/farcaster-auth-utils.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
+import {
+ AvatarSelectionRouteName,
+ ConnectEthereumRouteName,
+} from '../../navigation/route-names.js';
+import { useStyles } from '../../themes/colors.js';
+import Alert from '../../utils/alert.js';
+import AuthButtonContainer from '../auth-components/auth-button-container.react.js';
+import AuthContainer from '../auth-components/auth-container.react.js';
+import AuthContentContainer from '../auth-components/auth-content-container.react.js';
+
+export type ConnectFarcasterDCsParams = {
+ +userSelections: {
+ +coolOrNerdMode?: ?CoolOrNerdMode,
+ +keyserverURL?: ?string,
+ +farcasterID: string,
+ +farcasterAvatarURL: ?string,
+ },
+};
+
+type Props = {
+ +navigation: AuthNavigationProp<'ConnectFarcasterDCs'>,
+ +route: NavigationRoute<'ConnectFarcasterDCs'>,
+};
+
+function InnerConnectFarcasterDCs(props: Props): React.Node {
+ const { navigation, route } = props;
+
+ const { navigate } = navigation;
+ const userSelections = route.params?.userSelections;
+
+ const [mnemonic, setMnemonic] = React.useState<?string>(null);
+
+ const registrationContext = React.useContext(RegistrationContext);
+ invariant(registrationContext, 'registrationContext should be set');
+ const {
+ cachedSelections,
+ setCachedSelections,
+ skipEthereumLoginOnce,
+ setSkipEthereumLoginOnce,
+ } = registrationContext;
+
+ const { ethereumAccount } = cachedSelections;
+ const goToNextStep = React.useCallback(
+ (farcasterDCsToken?: ?string) => {
+ invariant(
+ !ethereumAccount || ethereumAccount.nonceTimestamp,
+ 'nonceTimestamp must be set after connecting to Ethereum account',
+ );
+ const nonceExpired =
+ ethereumAccount &&
+ ethereumAccount.nonceTimestamp &&
+ siweNonceExpired(ethereumAccount.nonceTimestamp);
+ if (nonceExpired) {
+ setCachedSelections(oldUserSelections => ({
+ ...oldUserSelections,
+ ethereumAccount: undefined,
+ }));
+ }
+
+ if (!skipEthereumLoginOnce || !ethereumAccount || nonceExpired) {
+ navigate<'ConnectEthereum'>({
+ name: ConnectEthereumRouteName,
+ params: {
+ userSelections: {
+ ...userSelections,
+ farcasterDCsToken,
+ },
+ },
+ });
+ return;
+ }
+
+ const newUserSelections = {
+ ...userSelections,
+ accountSelection: ethereumAccount,
+ farcasterDCsToken,
+ };
+ setSkipEthereumLoginOnce(false);
+ navigate<'AvatarSelection'>({
+ name: AvatarSelectionRouteName,
+ params: { userSelections: newUserSelections },
+ });
+ },
+ [
+ ethereumAccount,
+ navigate,
+ setCachedSelections,
+ setSkipEthereumLoginOnce,
+ skipEthereumLoginOnce,
+ userSelections,
+ ],
+ );
+
+ const onSkip = React.useCallback(() => {
+ if (cachedSelections.farcasterDCsToken) {
+ setCachedSelections(({ farcasterDCsToken, ...rest }) => rest);
+ }
+ goToNextStep();
+ }, [cachedSelections.farcasterDCsToken, goToNextStep, setCachedSelections]);
+
+ const getAuthToken = useGetAuthToken();
+ const [signingInProgress, setSigningInProgress] = React.useState(false);
+ const onConnect = React.useCallback(async () => {
+ if (!mnemonic) {
+ goToNextStep();
+ return;
+ }
+
+ setSigningInProgress(true);
+ try {
+ const token = await getAuthToken(userSelections.farcasterID, mnemonic);
+ setCachedSelections(oldUserSelections => ({
+ farcasterDCsToken: token,
+ ...oldUserSelections,
+ }));
+ goToNextStep(token);
+ } catch (e) {
+ Alert.alert(
+ 'Failed to connect',
+ 'Failed to connect to Farcaster Direct Casts. Please try again later.',
+ );
+ }
+ setSigningInProgress(false);
+ }, [
+ getAuthToken,
+ goToNextStep,
+ mnemonic,
+ setCachedSelections,
+ userSelections.farcasterID,
+ ]);
+
+ let buttonVariant = 'enabled';
+ if (!mnemonic || cachedSelections.farcasterDCsToken) {
+ buttonVariant = 'disabled';
+ } else if (signingInProgress) {
+ buttonVariant = 'loading';
+ }
+
+ const onUseAlreadyConnectedAccount = React.useCallback(() => {
+ goToNextStep(cachedSelections.farcasterDCsToken);
+ }, [cachedSelections.farcasterDCsToken, goToNextStep]);
+ const alreadyConnected = !!cachedSelections.farcasterDCsToken;
+ let alreadyConnectedButton = null;
+ if (alreadyConnected) {
+ alreadyConnectedButton = (
+ <PrimaryButton
+ onPress={onUseAlreadyConnectedAccount}
+ label="Use connected account"
+ variant="enabled"
+ />
+ );
+ }
+
+ const onChangeText = React.useCallback(
+ (text: string) => {
+ setMnemonic(text);
+ setCachedSelections(({ farcasterDCsToken, ...rest }) => rest);
+ },
+ [setCachedSelections],
+ );
+
+ const styles = useStyles(unboundStyles);
+ return React.useMemo(
+ () => (
+ <AuthContainer>
+ <AuthContentContainer style={styles.scrollViewContentContainer}>
+ <FarcasterPrompt textType="connect_DC" />
+ <RegistrationTextInput
+ autoCapitalize="none"
+ autoComplete="off"
+ autoCorrect={false}
+ editable={!signingInProgress}
+ keyboardType="default"
+ onChangeText={onChangeText}
+ onSubmitEditing={onConnect}
+ placeholder="Wallet mnemonic"
+ returnKeyType="go"
+ secureTextEntry={true}
+ value={mnemonic}
+ />
+ </AuthContentContainer>
+ <AuthButtonContainer>
+ {alreadyConnectedButton}
+ <PrimaryButton
+ onPress={onConnect}
+ label="Connect Direct Casts"
+ variant={buttonVariant}
+ />
+ <PrimaryButton
+ onPress={onSkip}
+ label="Do not connect"
+ variant="outline"
+ />
+ </AuthButtonContainer>
+ </AuthContainer>
+ ),
+ [
+ alreadyConnectedButton,
+ buttonVariant,
+ mnemonic,
+ onChangeText,
+ onConnect,
+ onSkip,
+ signingInProgress,
+ styles.scrollViewContentContainer,
+ ],
+ );
+}
+
+const unboundStyles = {
+ scrollViewContentContainer: {
+ flexGrow: 1,
+ },
+ description: {
+ fontFamily: 'Arial',
+ fontSize: 15,
+ lineHeight: 20,
+ color: 'panelForegroundSecondaryLabel',
+ paddingBottom: 16,
+ },
+};
+
+function ConnectFarcasterDCs(props: Props): React.Node {
+ return (
+ <FarcasterAuthContextProvider>
+ <InnerConnectFarcasterDCs {...props} />
+ </FarcasterAuthContextProvider>
+ );
+}
+
+export { ConnectFarcasterDCs };
diff --git a/native/account/registration/connect-farcaster.react.js b/native/account/registration/connect-farcaster.react.js
--- a/native/account/registration/connect-farcaster.react.js
+++ b/native/account/registration/connect-farcaster.react.js
@@ -7,6 +7,7 @@
import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js';
import type { BaseFCAvatarInfo } from 'lib/utils/farcaster-helpers.js';
+import { supportsFarcasterDCs } from 'lib/utils/services-utils.js';
import type { AuthNavigationProp } from './auth-navigator.react.js';
import { siweNonceExpired } from './ethereum-utils.js';
@@ -64,6 +65,21 @@
const goToNextStep = React.useCallback(
(fid?: ?string, farcasterAvatarURL: ?string) => {
setWebViewState('closed');
+
+ if (fid && supportsFarcasterDCs) {
+ navigate<'ConnectFarcasterDCs'>({
+ name: 'ConnectFarcasterDCs',
+ params: {
+ userSelections: {
+ ...userSelections,
+ farcasterID: fid,
+ farcasterAvatarURL: farcasterAvatarURL,
+ },
+ },
+ });
+ return;
+ }
+
invariant(
!ethereumAccount || ethereumAccount.nonceTimestamp,
'nonceTimestamp must be set after connecting to Ethereum account',
@@ -87,6 +103,7 @@
...userSelections,
farcasterID: fid,
farcasterAvatarURL: farcasterAvatarURL,
+ farcasterDCsToken: null,
},
},
});
@@ -98,6 +115,7 @@
farcasterID: fid,
accountSelection: ethereumAccount,
farcasterAvatarURL: farcasterAvatarURL,
+ farcasterDCsToken: null,
};
setSkipEthereumLoginOnce(false);
navigate<'AvatarSelection'>({
@@ -116,14 +134,20 @@
);
const onSkip = React.useCallback(() => {
- if (cachedSelections.farcasterID || cachedSelections.farcasterAvatarURL) {
+ if (
+ cachedSelections.farcasterID ||
+ cachedSelections.farcasterAvatarURL ||
+ cachedSelections.farcasterDCsToken
+ ) {
setCachedSelections(
- ({ farcasterID, farcasterAvatarURL, ...rest }) => rest,
+ ({ farcasterID, farcasterAvatarURL, farcasterDCsToken, ...rest }) =>
+ rest,
);
}
goToNextStep();
}, [
cachedSelections.farcasterAvatarURL,
+ cachedSelections.farcasterDCsToken,
cachedSelections.farcasterID,
goToNextStep,
setCachedSelections,
diff --git a/native/account/registration/password-selection.react.js b/native/account/registration/password-selection.react.js
--- a/native/account/registration/password-selection.react.js
+++ b/native/account/registration/password-selection.react.js
@@ -27,7 +27,8 @@
+keyserverURL?: ?string,
+farcasterID: ?string,
+username: string,
- farcasterAvatarURL: ?string,
+ +farcasterAvatarURL: ?string,
+ +farcasterDCsToken: ?string,
},
};
diff --git a/native/account/registration/registration-server-call.js b/native/account/registration/registration-server-call.js
--- a/native/account/registration/registration-server-call.js
+++ b/native/account/registration/registration-server-call.js
@@ -150,6 +150,7 @@
farcasterID: ?string,
onNonceExpired: () => mixed,
onAlertAcknowledged: ?() => mixed,
+ farcasterDCsToken: ?string,
) => {
try {
await identityWalletRegisterCall({
@@ -157,6 +158,7 @@
message: accountSelection.message,
signature: accountSelection.signature,
fid: farcasterID,
+ farcasterDCsToken,
});
} catch (e) {
const messageForException = getMessageForException(e);
@@ -203,6 +205,7 @@
clearCachedSelections,
onNonceExpired,
onAlertAcknowledged,
+ farcasterDCsToken,
} = input;
if (accountSelection.accountType === 'username') {
await identityRegisterUsernameAccount(
@@ -216,6 +219,7 @@
farcasterID,
onNonceExpired,
onAlertAcknowledged,
+ farcasterDCsToken,
);
}
if (passedKeyserverURL) {
diff --git a/native/account/registration/registration-terms.react.js b/native/account/registration/registration-terms.react.js
--- a/native/account/registration/registration-terms.react.js
+++ b/native/account/registration/registration-terms.react.js
@@ -32,6 +32,7 @@
+avatarData: ?AvatarData,
+siweBackupSecrets?: ?SignedMessage,
+farcasterAvatarURL: ?string,
+ +farcasterDCsToken: ?string,
},
};
@@ -63,8 +64,13 @@
const { navigation } = props;
const { reconnectEthereum } = navigation;
- const { coolOrNerdMode, keyserverURL, farcasterID, farcasterAvatarURL } =
- userSelections;
+ const {
+ coolOrNerdMode,
+ keyserverURL,
+ farcasterID,
+ farcasterAvatarURL,
+ farcasterDCsToken,
+ } = userSelections;
const navigateToConnectEthereum = React.useCallback(() => {
reconnectEthereum({
userSelections: {
@@ -72,6 +78,7 @@
keyserverURL,
farcasterID,
farcasterAvatarURL,
+ farcasterDCsToken,
},
});
}, [
@@ -80,6 +87,7 @@
keyserverURL,
farcasterID,
farcasterAvatarURL,
+ farcasterDCsToken,
]);
const onNonceExpired = React.useCallback(() => {
setCachedSelections(oldUserSelections => ({
diff --git a/native/account/registration/registration-types.js b/native/account/registration/registration-types.js
--- a/native/account/registration/registration-types.js
+++ b/native/account/registration/registration-types.js
@@ -48,6 +48,7 @@
+clearCachedSelections: () => void,
+onNonceExpired: () => mixed,
+onAlertAcknowledged?: () => mixed,
+ +farcasterDCsToken: ?string,
};
export type CachedUserSelections = {
@@ -60,6 +61,7 @@
+farcasterID?: string,
+siweBackupSecrets?: ?SignedMessage,
+farcasterAvatarURL?: ?string,
+ +farcasterDCsToken?: ?string,
};
export const ensAvatarSelection: AvatarData = {
diff --git a/native/account/registration/siwe-backup-message-creation.react.js b/native/account/registration/siwe-backup-message-creation.react.js
--- a/native/account/registration/siwe-backup-message-creation.react.js
+++ b/native/account/registration/siwe-backup-message-creation.react.js
@@ -141,6 +141,7 @@
+accountSelection: AccountSelection,
+avatarData: ?AvatarData,
+farcasterAvatarURL: ?string,
+ +farcasterDCsToken: ?string,
},
};
diff --git a/native/account/registration/username-selection.react.js b/native/account/registration/username-selection.react.js
--- a/native/account/registration/username-selection.react.js
+++ b/native/account/registration/username-selection.react.js
@@ -28,6 +28,7 @@
+keyserverURL?: ?string,
+farcasterID: ?string,
+farcasterAvatarURL: ?string,
+ +farcasterDCsToken: ?string,
},
};
diff --git a/native/account/siwe-hooks.js b/native/account/siwe-hooks.js
--- a/native/account/siwe-hooks.js
+++ b/native/account/siwe-hooks.js
@@ -13,12 +13,13 @@
const identityWalletRegister = useIdentityWalletRegister();
const dispatchActionPromise = useDispatchActionPromise();
return React.useCallback(
- async ({ address, message, signature, fid }) => {
+ async ({ address, message, signature, fid, farcasterDCsToken }) => {
const siwePromise = identityWalletRegister(
address,
message,
signature,
fid,
+ farcasterDCsToken,
);
void dispatchActionPromise(identityRegisterActionTypes, siwePromise);
diff --git a/native/components/farcaster-prompt.react.js b/native/components/farcaster-prompt.react.js
--- a/native/components/farcaster-prompt.react.js
+++ b/native/components/farcaster-prompt.react.js
@@ -1,58 +1,82 @@
// @flow
import * as React from 'react';
-import { View, Text } from 'react-native';
+import { Text, View } from 'react-native';
import { useStyles } from '../themes/colors.js';
import FarcasterLogo from '../vectors/farcaster-logo.react.js';
-type TextType = 'connect' | 'disconnect';
+type TextType = 'connect' | 'disconnect' | 'connect_DC';
type Props = {
+textType: TextType,
};
+const prompts = {
+ connect: {
+ headerText: 'Do you want to connect your Farcaster account?',
+ bodyTexts: [
+ 'Connecting your Farcaster account lets us bootstrap your social ' +
+ 'graph. We’ll also surface communities based on your Farcaster ' +
+ 'channels.',
+ ],
+ displayLogo: true,
+ },
+ disconnect: {
+ headerText: 'Disconnect from Farcaster',
+ bodyTexts: ['You can disconnect your Farcaster account at any time.'],
+ displayLogo: true,
+ },
+ connect_DC: {
+ headerText: 'Do you want to connect your Farcaster Direct Casts?',
+ bodyTexts: [
+ 'If you share your Farcaster custody mnemonic below, you’ll be able to ' +
+ 'send and receive Direct Cast messages using Comm.',
+ 'You can find it in the Farcaster app within Settings → Advanced → ' +
+ 'Show Farcaster recovery phrase.',
+ 'Your mnemonic phrase is only used locally and is not sent to our ' +
+ 'servers.',
+ ],
+ displayLogo: false,
+ },
+};
+
function FarcasterPrompt(props: Props): React.Node {
const { textType } = props;
- let headerText;
- if (textType === 'disconnect') {
- headerText = 'Disconnect from Farcaster';
- } else {
- headerText = 'Do you want to connect your Farcaster account?';
- }
+ const { headerText, bodyTexts, displayLogo } = prompts[textType];
- let bodyText;
- if (textType === 'disconnect') {
- bodyText = 'You can disconnect your Farcaster account at any time.';
- } else {
- bodyText =
- 'Connecting your Farcaster account lets us bootstrap your social ' +
- 'graph. We’ll also surface communities based on your Farcaster ' +
- 'channels.';
+ const styles = useStyles(unboundStyles);
+
+ let farcasterLogo = null;
+ if (displayLogo) {
+ farcasterLogo = (
+ <View style={styles.farcasterLogoContainer}>
+ <FarcasterLogo />
+ </View>
+ );
}
- const styles = useStyles(unboundStyles);
- const farcasterPrompt = React.useMemo(
+ const bodyText = React.useMemo(
+ () =>
+ bodyTexts.map((text, id) => (
+ <Text style={styles.body} key={id}>
+ {text}
+ </Text>
+ )),
+ [bodyTexts, styles.body],
+ );
+
+ return React.useMemo(
() => (
<>
<Text style={styles.header}>{headerText}</Text>
- <Text style={styles.body}>{bodyText}</Text>
- <View style={styles.farcasterLogoContainer}>
- <FarcasterLogo />
- </View>
+ {bodyText}
+ {farcasterLogo}
</>
),
- [
- bodyText,
- headerText,
- styles.body,
- styles.farcasterLogoContainer,
- styles.header,
- ],
+ [bodyText, farcasterLogo, headerText, styles.header],
);
-
- return farcasterPrompt;
}
const unboundStyles = {
diff --git a/native/farcaster-auth/farcaster-auth-utils.js b/native/farcaster-auth/farcaster-auth-utils.js
new file mode 100644
--- /dev/null
+++ b/native/farcaster-auth/farcaster-auth-utils.js
@@ -0,0 +1,41 @@
+// @flow
+
+import * as React from 'react';
+
+import { useSignFarcasterAuthMessage } from 'lib/components/farcaster-auth-context.js';
+
+function useGetAuthToken(): (
+ fid: string,
+ walletMnemonic: string,
+) => Promise<string> {
+ const signAuthMessage = useSignFarcasterAuthMessage();
+
+ return React.useCallback(
+ async (fid: string, walletMnemonic: string) => {
+ const nonceResponse = await fetch(
+ 'https://client.farcaster.xyz/v2/get-dc-nonce',
+ );
+ const nonceData = await nonceResponse.json();
+ const nonce = nonceData.result.nonce;
+
+ const signResult = await signAuthMessage({
+ nonce,
+ fid,
+ walletMnemonic,
+ });
+
+ const params = new URLSearchParams({
+ message: signResult.message,
+ signature: signResult.signature,
+ });
+ const tokenResponse = await fetch(
+ `https://client.farcaster.xyz/v2/get-dc-auth-token?${params.toString()}`,
+ );
+ const tokenData = await tokenResponse.json();
+ return tokenData.result.token;
+ },
+ [signAuthMessage],
+ );
+}
+
+export { useGetAuthToken };
diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js
--- a/native/navigation/route-names.js
+++ b/native/navigation/route-names.js
@@ -8,6 +8,7 @@
import type { ConnectSecondaryDeviceParams } from '../account/qr-auth/connect-secondary-device.react.js';
import type { AvatarSelectionParams } from '../account/registration/avatar-selection.react.js';
import type { ConnectEthereumParams } from '../account/registration/connect-ethereum.react.js';
+import type { ConnectFarcasterDCsParams } from '../account/registration/connect-farcaster-dcs.react.js';
import type { ConnectFarcasterParams } from '../account/registration/connect-farcaster.react.js';
import type { EmojiAvatarSelectionParams } from '../account/registration/emoji-avatar-selection.react.js';
import type { ExistingEthereumAccountParams } from '../account/registration/existing-ethereum-account.react.js';
@@ -142,6 +143,7 @@
export const RestoreSIWEBackupRouteName = 'RestoreSIWEBackup';
export const ExistingEthereumAccountRouteName = 'ExistingEthereumAccount';
export const ConnectFarcasterRouteName = 'ConnectFarcaster';
+export const ConnectFarcasterDCsRouteName = 'ConnectFarcasterDCs';
export const UsernameSelectionRouteName = 'UsernameSelection';
export const CommunityCreationRouteName = 'CommunityCreation';
export const CommunityConfigurationRouteName = 'CommunityConfiguration';
@@ -327,6 +329,7 @@
+ConnectEthereum: ConnectEthereumParams,
+ExistingEthereumAccount: ExistingEthereumAccountParams,
+ConnectFarcaster: ConnectFarcasterParams,
+ +ConnectFarcasterDCs: ConnectFarcasterDCsParams,
+CreateSIWEBackupMessage: CreateSIWEBackupMessageParams,
+UsernameSelection: UsernameSelectionParams,
+PasswordSelection: PasswordSelectionParams,

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 7, 10:17 PM (18 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5846190
Default Alt Text
D14911.1765145835.diff (25 KB)

Event Timeline